summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/assets/javascripts/commons/polyfills.js1
-rw-r--r--app/assets/javascripts/gl_form.js87
-rw-r--r--app/assets/javascripts/helpers/indent_helper.js182
-rw-r--r--app/assets/javascripts/lib/utils/common_utils.js65
-rw-r--r--app/assets/javascripts/lib/utils/keycodes.js10
-rw-r--r--app/assets/javascripts/lib/utils/undo_stack.js105
-rw-r--r--app/assets/javascripts/vue_shared/components/markdown/toolbar.vue41
-rw-r--r--app/assets/stylesheets/framework/common.scss1
-rw-r--r--app/assets/stylesheets/framework/lists.scss16
-rw-r--r--app/controllers/application_controller.rb2
-rw-r--r--app/controllers/concerns/authenticates_with_two_factor.rb4
-rw-r--r--app/controllers/concerns/group_tree.rb20
-rw-r--r--app/controllers/omniauth_callbacks_controller.rb2
-rw-r--r--app/controllers/projects/artifacts_controller.rb5
-rw-r--r--app/controllers/projects/build_artifacts_controller.rb2
-rw-r--r--app/controllers/sessions_controller.rb11
-rw-r--r--app/finders/group_descendants_finder.rb2
-rw-r--r--app/graphql/types/group_type.rb8
-rw-r--r--app/helpers/groups_helper.rb4
-rw-r--r--app/helpers/submodule_helper.rb2
-rw-r--r--app/mailers/emails/members.rb17
-rw-r--r--app/mailers/notify.rb12
-rw-r--r--app/mailers/previews/notify_preview.rb8
-rw-r--r--app/models/ci/pipeline.rb10
-rw-r--r--app/models/concerns/descendant.rb11
-rw-r--r--app/models/concerns/protected_ref.rb2
-rw-r--r--app/models/deployment_metrics.rb13
-rw-r--r--app/models/group.rb3
-rw-r--r--app/models/namespace.rb2
-rw-r--r--app/models/project.rb25
-rw-r--r--app/models/project_services/chat_message/pipeline_message.rb225
-rw-r--r--app/policies/group_policy.rb6
-rw-r--r--app/serializers/stage_entity.rb8
-rw-r--r--app/services/ci/process_pipeline_service.rb4
-rw-r--r--app/services/groups/nested_create_service.rb4
-rw-r--r--app/services/groups/transfer_service.rb1
-rw-r--r--app/services/members/destroy_service.rb2
-rw-r--r--app/services/notification_service.rb2
-rw-r--r--app/services/users/refresh_authorized_projects_service.rb8
-rw-r--r--app/views/groups/settings/_advanced.html.haml25
-rw-r--r--app/views/layouts/nav/sidebar/_project.html.haml8
-rw-r--r--app/views/projects/settings/ci_cd/_autodevops_form.html.haml4
-rw-r--r--app/views/projects/settings/ci_cd/show.html.haml6
-rw-r--r--app/views/shared/notes/_hints.html.haml11
-rw-r--r--changelogs/unreleased/32495-improve-slack-notification-on-pipeline-status.yml5
-rw-r--r--changelogs/unreleased/59325-units-are-not-shown-on-the-performance-dashboard-2.yml5
-rw-r--r--changelogs/unreleased/63568-access-email-notifications-custom-email.yml5
-rw-r--r--changelogs/unreleased/64257-warden_set_user_fix.yml5
-rw-r--r--changelogs/unreleased/64972-fix-unicorn-workers-metric.yml5
-rw-r--r--changelogs/unreleased/delete-designs-v2.yml4
-rw-r--r--changelogs/unreleased/dm-submodule-links-nil.yml5
-rw-r--r--changelogs/unreleased/extract_auto_deploy_into_base_image.yml5
-rw-r--r--changelogs/unreleased/mh-editor-indents.yml5
-rw-r--r--changelogs/unreleased/remove_deployment_metrics_deployment_platform_fallback.yml6
-rw-r--r--config/prometheus/cluster_metrics.yml16
-rw-r--r--config/prometheus/common_metrics.yml42
-rw-r--r--db/migrate/20190709220014_import_common_metrics_y_axis.rb13
-rw-r--r--db/migrate/20190715140740_add_event_type_to_design_management_designs_versions.rb27
-rw-r--r--db/schema.rb2
-rw-r--r--doc/ci/README.md6
-rw-r--r--doc/ci/introduction/index.md5
-rw-r--r--doc/ci/pipelines.md5
-rw-r--r--doc/development/README.md4
-rw-r--r--doc/development/database_review.md11
-rw-r--r--doc/development/filtering_by_label.md166
-rw-r--r--doc/user/project/integrations/prometheus.md3
-rw-r--r--lib/api/entities.rb5
-rw-r--r--lib/api/groups.rb5
-rw-r--r--lib/api/job_artifacts.rb4
-rw-r--r--lib/api/validations/types/labels_list.rb2
-rw-r--r--lib/banzai/reference_redactor.rb2
-rw-r--r--lib/gitlab/auth/activity.rb7
-rw-r--r--lib/gitlab/background_migration/backfill_project_repositories.rb2
-rw-r--r--lib/gitlab/badge/coverage/report.rb2
-rw-r--r--lib/gitlab/ci/config/normalizer.rb2
-rw-r--r--lib/gitlab/ci/status/factory.rb6
-rw-r--r--lib/gitlab/ci/templates/Auto-DevOps.gitlab-ci.yml3
-rw-r--r--lib/gitlab/ci/templates/Jobs/Deploy.gitlab-ci.yml421
-rw-r--r--lib/gitlab/object_hierarchy.rb17
-rw-r--r--lib/gitlab/project_authorizations.rb121
-rw-r--r--lib/gitlab/project_authorizations/with_nested_groups.rb125
-rw-r--r--lib/gitlab/project_authorizations/without_nested_groups.rb35
-rw-r--r--lib/gitlab/submodule_links.rb11
-rw-r--r--lib/prometheus/pid_provider.rb35
-rw-r--r--locale/gitlab.pot66
-rw-r--r--package.json4
-rw-r--r--qa/qa/page/project/issue/show.rb5
-rw-r--r--qa/qa/page/project/settings/ci_cd.rb21
-rw-r--r--qa/qa/page/project/sub_menus/project.rb4
-rw-r--r--spec/controllers/boards/issues_controller_spec.rb2
-rw-r--r--spec/controllers/concerns/group_tree_spec.rb4
-rw-r--r--spec/controllers/dashboard/groups_controller_spec.rb2
-rw-r--r--spec/controllers/groups/children_controller_spec.rb4
-rw-r--r--spec/controllers/groups/labels_controller_spec.rb4
-rw-r--r--spec/controllers/groups_controller_spec.rb6
-rw-r--r--spec/controllers/import/bitbucket_controller_spec.rb6
-rw-r--r--spec/controllers/import/gitlab_controller_spec.rb6
-rw-r--r--spec/controllers/projects/merge_requests_controller_spec.rb5
-rw-r--r--spec/controllers/projects/milestones_controller_spec.rb2
-rw-r--r--spec/factories/abuse_reports.rb2
-rw-r--r--spec/factories/appearances.rb2
-rw-r--r--spec/factories/application_settings.rb2
-rw-r--r--spec/factories/award_emoji.rb2
-rw-r--r--spec/factories/badge.rb2
-rw-r--r--spec/factories/boards.rb2
-rw-r--r--spec/factories/broadcast_messages.rb2
-rw-r--r--spec/factories/chat_names.rb2
-rw-r--r--spec/factories/chat_teams.rb2
-rw-r--r--spec/factories/ci/bridge.rb2
-rw-r--r--spec/factories/ci/build_trace_chunks.rb2
-rw-r--r--spec/factories/ci/build_trace_section_names.rb2
-rw-r--r--spec/factories/ci/builds.rb2
-rw-r--r--spec/factories/ci/group_variables.rb2
-rw-r--r--spec/factories/ci/job_artifacts.rb2
-rw-r--r--spec/factories/ci/pipeline_schedule.rb2
-rw-r--r--spec/factories/ci/pipeline_schedule_variables.rb2
-rw-r--r--spec/factories/ci/pipeline_variables.rb2
-rw-r--r--spec/factories/ci/pipelines.rb2
-rw-r--r--spec/factories/ci/runner_projects.rb2
-rw-r--r--spec/factories/ci/runners.rb2
-rw-r--r--spec/factories/ci/stages.rb2
-rw-r--r--spec/factories/ci/trigger_requests.rb2
-rw-r--r--spec/factories/ci/triggers.rb2
-rw-r--r--spec/factories/ci/variables.rb2
-rw-r--r--spec/factories/clusters/applications/helm.rb2
-rw-r--r--spec/factories/clusters/clusters.rb2
-rw-r--r--spec/factories/clusters/platforms/kubernetes.rb2
-rw-r--r--spec/factories/clusters/providers/gcp.rb2
-rw-r--r--spec/factories/commit_statuses.rb2
-rw-r--r--spec/factories/commits.rb2
-rw-r--r--spec/factories/container_repositories.rb2
-rw-r--r--spec/factories/conversational_development_index_metrics.rb2
-rw-r--r--spec/factories/deploy_keys_projects.rb2
-rw-r--r--spec/factories/deploy_tokens.rb2
-rw-r--r--spec/factories/deployments.rb2
-rw-r--r--spec/factories/emails.rb2
-rw-r--r--spec/factories/environments.rb2
-rw-r--r--spec/factories/events.rb2
-rw-r--r--spec/factories/file_uploaders.rb2
-rw-r--r--spec/factories/fork_network_members.rb2
-rw-r--r--spec/factories/fork_networks.rb2
-rw-r--r--spec/factories/gitaly/commit.rb2
-rw-r--r--spec/factories/gitaly/commit_author.rb2
-rw-r--r--spec/factories/gitaly/tag.rb2
-rw-r--r--spec/factories/gpg_key_subkeys.rb2
-rw-r--r--spec/factories/gpg_keys.rb2
-rw-r--r--spec/factories/gpg_signature.rb2
-rw-r--r--spec/factories/group_custom_attributes.rb2
-rw-r--r--spec/factories/group_members.rb2
-rw-r--r--spec/factories/groups.rb2
-rw-r--r--spec/factories/identities.rb2
-rw-r--r--spec/factories/import_export_uploads.rb2
-rw-r--r--spec/factories/import_states.rb2
-rw-r--r--spec/factories/instance_configuration.rb2
-rw-r--r--spec/factories/internal_ids.rb2
-rw-r--r--spec/factories/issues.rb2
-rw-r--r--spec/factories/keys.rb2
-rw-r--r--spec/factories/label_links.rb2
-rw-r--r--spec/factories/label_priorities.rb2
-rw-r--r--spec/factories/labels.rb2
-rw-r--r--spec/factories/lfs_file_locks.rb2
-rw-r--r--spec/factories/lfs_objects.rb2
-rw-r--r--spec/factories/lfs_objects_projects.rb2
-rw-r--r--spec/factories/lists.rb2
-rw-r--r--spec/factories/merge_requests.rb2
-rw-r--r--spec/factories/merge_requests_closing_issues.rb2
-rw-r--r--spec/factories/milestones.rb2
-rw-r--r--spec/factories/namespaces.rb2
-rw-r--r--spec/factories/notes.rb2
-rw-r--r--spec/factories/notification_settings.rb2
-rw-r--r--spec/factories/oauth_access_grants.rb2
-rw-r--r--spec/factories/oauth_access_tokens.rb2
-rw-r--r--spec/factories/oauth_applications.rb2
-rw-r--r--spec/factories/pages_domains.rb2
-rw-r--r--spec/factories/personal_access_tokens.rb2
-rw-r--r--spec/factories/pool_repositories.rb2
-rw-r--r--spec/factories/programming_languages.rb2
-rw-r--r--spec/factories/project_auto_devops.rb2
-rw-r--r--spec/factories/project_custom_attributes.rb2
-rw-r--r--spec/factories/project_deploy_tokens.rb2
-rw-r--r--spec/factories/project_group_links.rb2
-rw-r--r--spec/factories/project_hooks.rb2
-rw-r--r--spec/factories/project_members.rb2
-rw-r--r--spec/factories/project_statistics.rb2
-rw-r--r--spec/factories/project_wikis.rb2
-rw-r--r--spec/factories/projects.rb2
-rw-r--r--spec/factories/protected_branches.rb2
-rw-r--r--spec/factories/protected_tags.rb2
-rw-r--r--spec/factories/redirect_routes.rb2
-rw-r--r--spec/factories/releases.rb2
-rw-r--r--spec/factories/remote_mirrors.rb2
-rw-r--r--spec/factories/repository_languages.rb2
-rw-r--r--spec/factories/sent_notifications.rb2
-rw-r--r--spec/factories/sequences.rb2
-rw-r--r--spec/factories/service_hooks.rb2
-rw-r--r--spec/factories/services.rb2
-rw-r--r--spec/factories/shards.rb2
-rw-r--r--spec/factories/snippets.rb2
-rw-r--r--spec/factories/spam_logs.rb2
-rw-r--r--spec/factories/subscriptions.rb2
-rw-r--r--spec/factories/system_hooks.rb2
-rw-r--r--spec/factories/system_note_metadata.rb2
-rw-r--r--spec/factories/term_agreements.rb2
-rw-r--r--spec/factories/terms.rb2
-rw-r--r--spec/factories/timelogs.rb2
-rw-r--r--spec/factories/todos.rb2
-rw-r--r--spec/factories/trending_project.rb2
-rw-r--r--spec/factories/u2f_registrations.rb2
-rw-r--r--spec/factories/uploads.rb2
-rw-r--r--spec/factories/user_agent_details.rb2
-rw-r--r--spec/factories/user_callouts.rb2
-rw-r--r--spec/factories/user_custom_attributes.rb2
-rw-r--r--spec/factories/users.rb2
-rw-r--r--spec/factories/users_star_projects.rb2
-rw-r--r--spec/factories/web_hook_log.rb2
-rw-r--r--spec/factories/wiki_directories.rb2
-rw-r--r--spec/factories/wiki_pages.rb2
-rw-r--r--spec/features/contextual_sidebar_spec.rb4
-rw-r--r--spec/features/dashboard/groups_list_spec.rb6
-rw-r--r--spec/features/groups/empty_states_spec.rb2
-rw-r--r--spec/features/groups/group_settings_spec.rb2
-rw-r--r--spec/features/groups/issues_spec.rb2
-rw-r--r--spec/features/groups/members/list_members_spec.rb4
-rw-r--r--spec/features/groups/share_lock_spec.rb2
-rw-r--r--spec/features/groups/show_spec.rb38
-rw-r--r--spec/features/groups_spec.rb4
-rw-r--r--spec/features/ide_spec.rb2
-rw-r--r--spec/features/import/manifest_import_spec.rb2
-rw-r--r--spec/features/labels_hierarchy_spec.rb2
-rw-r--r--spec/features/markdown/metrics_spec.rb60
-rw-r--r--spec/features/oauth_login_spec.rb1
-rw-r--r--spec/features/projects/artifacts/user_downloads_artifacts_spec.rb4
-rw-r--r--spec/features/projects/members/invite_group_spec.rb4
-rw-r--r--spec/features/projects/new_project_spec.rb2
-rw-r--r--spec/features/projects/settings/pipelines_settings_spec.rb2
-rw-r--r--spec/features/projects/settings/user_transfers_a_project_spec.rb2
-rw-r--r--spec/features/projects/sub_group_issuables_spec.rb2
-rw-r--r--spec/features/projects/user_creates_project_spec.rb2
-rw-r--r--spec/features/projects/wiki/user_creates_wiki_page_spec.rb12
-rw-r--r--spec/features/projects_spec.rb2
-rw-r--r--spec/features/users/login_spec.rb38
-rw-r--r--spec/finders/autocomplete/users_finder_spec.rb2
-rw-r--r--spec/finders/cluster_ancestors_finder_spec.rb4
-rw-r--r--spec/finders/group_descendants_finder_spec.rb6
-rw-r--r--spec/finders/group_members_finder_spec.rb4
-rw-r--r--spec/finders/group_projects_finder_spec.rb12
-rw-r--r--spec/finders/groups_finder_spec.rb2
-rw-r--r--spec/finders/issues_finder_spec.rb2
-rw-r--r--spec/finders/labels_finder_spec.rb6
-rw-r--r--spec/finders/members_finder_spec.rb8
-rw-r--r--spec/finders/merge_requests_finder_spec.rb2
-rw-r--r--spec/finders/todos_finder_spec.rb2
-rw-r--r--spec/fixtures/security-reports/dependency_list/gl-dependency-scanning-report.json4
-rw-r--r--spec/frontend/helpers/indent_helper_spec.js371
-rw-r--r--spec/frontend/lib/utils/common_utils_spec.js180
-rw-r--r--spec/frontend/lib/utils/undo_stack_spec.js237
-rw-r--r--spec/graphql/resolvers/namespace_projects_resolver_spec.rb2
-rw-r--r--spec/helpers/auto_devops_helper_spec.rb6
-rw-r--r--spec/helpers/groups_helper_spec.rb6
-rw-r--r--spec/helpers/namespaces_helper_spec.rb4
-rw-r--r--spec/helpers/submodule_helper_spec.rb13
-rw-r--r--spec/javascripts/badges/components/badge_list_spec.js2
-rw-r--r--spec/javascripts/badges/components/badge_spec.js2
-rw-r--r--spec/javascripts/boards/board_list_spec.js2
-rw-r--r--spec/javascripts/registry/components/app_spec.js2
-rw-r--r--spec/javascripts/reports/components/grouped_test_reports_app_spec.js12
-rw-r--r--spec/javascripts/vue_mr_widget/components/mr_widget_status_icon_spec.js2
-rw-r--r--spec/javascripts/vue_mr_widget/components/states/mr_widget_auto_merge_failed_spec.js4
-rw-r--r--spec/javascripts/vue_mr_widget/components/states/mr_widget_checking_spec.js2
-rw-r--r--spec/javascripts/vue_shared/components/file_icon_spec.js2
-rw-r--r--spec/javascripts/vue_shared/components/header_ci_component_spec.js2
-rw-r--r--spec/lib/after_commit_queue_spec.rb2
-rw-r--r--spec/lib/api/api_spec.rb2
-rw-r--r--spec/lib/api/helpers/custom_validators_spec.rb2
-rw-r--r--spec/lib/api/helpers/pagination_spec.rb2
-rw-r--r--spec/lib/api/helpers/related_resources_helpers_spec.rb2
-rw-r--r--spec/lib/api/helpers/version_spec.rb2
-rw-r--r--spec/lib/api/helpers_spec.rb2
-rw-r--r--spec/lib/backup/files_spec.rb2
-rw-r--r--spec/lib/backup/manager_spec.rb2
-rw-r--r--spec/lib/backup/repository_spec.rb2
-rw-r--r--spec/lib/backup/uploads_spec.rb2
-rw-r--r--spec/lib/banzai/color_parser_spec.rb2
-rw-r--r--spec/lib/banzai/commit_renderer_spec.rb2
-rw-r--r--spec/lib/banzai/cross_project_reference_spec.rb2
-rw-r--r--spec/lib/banzai/filter/absolute_link_filter_spec.rb2
-rw-r--r--spec/lib/banzai/filter/abstract_reference_filter_spec.rb2
-rw-r--r--spec/lib/banzai/filter/ascii_doc_post_processing_filter_spec.rb2
-rw-r--r--spec/lib/banzai/filter/autolink_filter_spec.rb2
-rw-r--r--spec/lib/banzai/filter/blockquote_fence_filter_spec.rb2
-rw-r--r--spec/lib/banzai/filter/color_filter_spec.rb2
-rw-r--r--spec/lib/banzai/filter/commit_range_reference_filter_spec.rb2
-rw-r--r--spec/lib/banzai/filter/commit_reference_filter_spec.rb2
-rw-r--r--spec/lib/banzai/filter/commit_trailers_filter_spec.rb2
-rw-r--r--spec/lib/banzai/filter/emoji_filter_spec.rb2
-rw-r--r--spec/lib/banzai/filter/external_issue_reference_filter_spec.rb2
-rw-r--r--spec/lib/banzai/filter/external_link_filter_spec.rb2
-rw-r--r--spec/lib/banzai/filter/front_matter_filter_spec.rb2
-rw-r--r--spec/lib/banzai/filter/gollum_tags_filter_spec.rb2
-rw-r--r--spec/lib/banzai/filter/html_entity_filter_spec.rb2
-rw-r--r--spec/lib/banzai/filter/image_lazy_load_filter_spec.rb2
-rw-r--r--spec/lib/banzai/filter/image_link_filter_spec.rb2
-rw-r--r--spec/lib/banzai/filter/inline_diff_filter_spec.rb2
-rw-r--r--spec/lib/banzai/filter/issuable_state_filter_spec.rb2
-rw-r--r--spec/lib/banzai/filter/issue_reference_filter_spec.rb2
-rw-r--r--spec/lib/banzai/filter/label_reference_filter_spec.rb2
-rw-r--r--spec/lib/banzai/filter/markdown_filter_spec.rb2
-rw-r--r--spec/lib/banzai/filter/math_filter_spec.rb2
-rw-r--r--spec/lib/banzai/filter/merge_request_reference_filter_spec.rb2
-rw-r--r--spec/lib/banzai/filter/mermaid_filter_spec.rb2
-rw-r--r--spec/lib/banzai/filter/milestone_reference_filter_spec.rb6
-rw-r--r--spec/lib/banzai/filter/plantuml_filter_spec.rb2
-rw-r--r--spec/lib/banzai/filter/reference_filter_spec.rb2
-rw-r--r--spec/lib/banzai/filter/reference_redactor_filter_spec.rb2
-rw-r--r--spec/lib/banzai/filter/relative_link_filter_spec.rb2
-rw-r--r--spec/lib/banzai/filter/sanitization_filter_spec.rb2
-rw-r--r--spec/lib/banzai/filter/snippet_reference_filter_spec.rb2
-rw-r--r--spec/lib/banzai/filter/spaced_link_filter_spec.rb2
-rw-r--r--spec/lib/banzai/filter/syntax_highlight_filter_spec.rb2
-rw-r--r--spec/lib/banzai/filter/table_of_contents_filter_spec.rb12
-rw-r--r--spec/lib/banzai/filter/user_reference_filter_spec.rb2
-rw-r--r--spec/lib/banzai/filter/video_link_filter_spec.rb2
-rw-r--r--spec/lib/banzai/filter/wiki_link_filter_spec.rb2
-rw-r--r--spec/lib/banzai/filter_array_spec.rb2
-rw-r--r--spec/lib/banzai/issuable_extractor_spec.rb2
-rw-r--r--spec/lib/banzai/object_renderer_spec.rb2
-rw-r--r--spec/lib/banzai/pipeline/description_pipeline_spec.rb2
-rw-r--r--spec/lib/banzai/pipeline/email_pipeline_spec.rb2
-rw-r--r--spec/lib/banzai/pipeline/full_pipeline_spec.rb2
-rw-r--r--spec/lib/banzai/pipeline/gfm_pipeline_spec.rb2
-rw-r--r--spec/lib/banzai/pipeline/wiki_pipeline_spec.rb2
-rw-r--r--spec/lib/banzai/querying_spec.rb2
-rw-r--r--spec/lib/banzai/reference_parser/base_parser_spec.rb2
-rw-r--r--spec/lib/banzai/reference_parser/commit_parser_spec.rb2
-rw-r--r--spec/lib/banzai/reference_parser/commit_range_parser_spec.rb2
-rw-r--r--spec/lib/banzai/reference_parser/external_issue_parser_spec.rb2
-rw-r--r--spec/lib/banzai/reference_parser/issue_parser_spec.rb2
-rw-r--r--spec/lib/banzai/reference_parser/label_parser_spec.rb2
-rw-r--r--spec/lib/banzai/reference_parser/merge_request_parser_spec.rb2
-rw-r--r--spec/lib/banzai/reference_parser/milestone_parser_spec.rb2
-rw-r--r--spec/lib/banzai/reference_parser/snippet_parser_spec.rb2
-rw-r--r--spec/lib/banzai/reference_parser/user_parser_spec.rb2
-rw-r--r--spec/lib/banzai/reference_redactor_spec.rb2
-rw-r--r--spec/lib/banzai/renderer_spec.rb2
-rw-r--r--spec/lib/bitbucket/collection_spec.rb2
-rw-r--r--spec/lib/bitbucket/connection_spec.rb2
-rw-r--r--spec/lib/bitbucket/page_spec.rb2
-rw-r--r--spec/lib/bitbucket/paginator_spec.rb2
-rw-r--r--spec/lib/bitbucket/representation/comment_spec.rb2
-rw-r--r--spec/lib/bitbucket/representation/issue_spec.rb2
-rw-r--r--spec/lib/bitbucket/representation/pull_request_comment_spec.rb2
-rw-r--r--spec/lib/bitbucket/representation/pull_request_spec.rb2
-rw-r--r--spec/lib/bitbucket/representation/repo_spec.rb2
-rw-r--r--spec/lib/bitbucket/representation/user_spec.rb2
-rw-r--r--spec/lib/bitbucket_server/client_spec.rb2
-rw-r--r--spec/lib/bitbucket_server/connection_spec.rb2
-rw-r--r--spec/lib/bitbucket_server/page_spec.rb2
-rw-r--r--spec/lib/bitbucket_server/paginator_spec.rb2
-rw-r--r--spec/lib/bitbucket_server/representation/activity_spec.rb2
-rw-r--r--spec/lib/bitbucket_server/representation/comment_spec.rb2
-rw-r--r--spec/lib/bitbucket_server/representation/pull_request_comment_spec.rb2
-rw-r--r--spec/lib/bitbucket_server/representation/pull_request_spec.rb2
-rw-r--r--spec/lib/bitbucket_server/representation/repo_spec.rb2
-rw-r--r--spec/lib/constraints/feature_constrainer_spec.rb2
-rw-r--r--spec/lib/constraints/group_url_constrainer_spec.rb2
-rw-r--r--spec/lib/constraints/project_url_constrainer_spec.rb2
-rw-r--r--spec/lib/constraints/user_url_constrainer_spec.rb2
-rw-r--r--spec/lib/container_registry/blob_spec.rb2
-rw-r--r--spec/lib/container_registry/client_spec.rb2
-rw-r--r--spec/lib/container_registry/path_spec.rb2
-rw-r--r--spec/lib/container_registry/registry_spec.rb2
-rw-r--r--spec/lib/container_registry/tag_spec.rb2
-rw-r--r--spec/lib/event_filter_spec.rb2
-rw-r--r--spec/lib/expand_variables_spec.rb2
-rw-r--r--spec/lib/extracts_path_spec.rb2
-rw-r--r--spec/lib/feature/gitaly_spec.rb2
-rw-r--r--spec/lib/feature_spec.rb2
-rw-r--r--spec/lib/file_size_validator_spec.rb2
-rw-r--r--spec/lib/forever_spec.rb2
-rw-r--r--spec/lib/gitaly/server_spec.rb2
-rw-r--r--spec/lib/gitlab/action_rate_limiter_spec.rb2
-rw-r--r--spec/lib/gitlab/allowable_spec.rb2
-rw-r--r--spec/lib/gitlab/app_logger_spec.rb2
-rw-r--r--spec/lib/gitlab/asciidoc_spec.rb2
-rw-r--r--spec/lib/gitlab/auth/activity_spec.rb2
-rw-r--r--spec/lib/gitlab/auth/blocked_user_tracker_spec.rb2
-rw-r--r--spec/lib/gitlab/auth/ldap/access_spec.rb2
-rw-r--r--spec/lib/gitlab/auth/ldap/adapter_spec.rb2
-rw-r--r--spec/lib/gitlab/auth/ldap/authentication_spec.rb2
-rw-r--r--spec/lib/gitlab/auth/ldap/config_spec.rb2
-rw-r--r--spec/lib/gitlab/auth/ldap/dn_spec.rb2
-rw-r--r--spec/lib/gitlab/auth/ldap/user_spec.rb2
-rw-r--r--spec/lib/gitlab/auth/o_auth/auth_hash_spec.rb14
-rw-r--r--spec/lib/gitlab/auth/o_auth/identity_linker_spec.rb2
-rw-r--r--spec/lib/gitlab/auth/o_auth/provider_spec.rb2
-rw-r--r--spec/lib/gitlab/auth/o_auth/user_spec.rb2
-rw-r--r--spec/lib/gitlab/auth/request_authenticator_spec.rb2
-rw-r--r--spec/lib/gitlab/auth/saml/auth_hash_spec.rb2
-rw-r--r--spec/lib/gitlab/auth/saml/identity_linker_spec.rb2
-rw-r--r--spec/lib/gitlab/auth/saml/user_spec.rb2
-rw-r--r--spec/lib/gitlab/auth/unique_ips_limiter_spec.rb2
-rw-r--r--spec/lib/gitlab/auth/user_access_denied_reason_spec.rb2
-rw-r--r--spec/lib/gitlab/auth/user_auth_finders_spec.rb2
-rw-r--r--spec/lib/gitlab/auth_spec.rb2
-rw-r--r--spec/lib/gitlab/background_migration/add_merge_request_diff_commits_count_spec.rb2
-rw-r--r--spec/lib/gitlab/background_migration/archive_legacy_traces_spec.rb2
-rw-r--r--spec/lib/gitlab/background_migration/encrypt_columns_spec.rb2
-rw-r--r--spec/lib/gitlab/background_migration/encrypt_runners_tokens_spec.rb2
-rw-r--r--spec/lib/gitlab/background_migration/fix_cross_project_label_links_spec.rb6
-rw-r--r--spec/lib/gitlab/background_migration/migrate_build_stage_spec.rb2
-rw-r--r--spec/lib/gitlab/background_migration/migrate_legacy_artifacts_spec.rb2
-rw-r--r--spec/lib/gitlab/background_migration/migrate_stage_index_spec.rb2
-rw-r--r--spec/lib/gitlab/background_migration/populate_untracked_uploads_dependencies/untracked_file_spec.rb2
-rw-r--r--spec/lib/gitlab/background_migration/populate_untracked_uploads_spec.rb2
-rw-r--r--spec/lib/gitlab/background_migration/prepare_untracked_uploads_spec.rb2
-rw-r--r--spec/lib/gitlab/background_migration/schedule_calculate_wiki_sizes_spec.rb2
-rw-r--r--spec/lib/gitlab/background_migration/set_confidential_note_events_on_services_spec.rb2
-rw-r--r--spec/lib/gitlab/background_migration/set_confidential_note_events_on_webhooks_spec.rb2
-rw-r--r--spec/lib/gitlab/background_migration_spec.rb2
-rw-r--r--spec/lib/gitlab/badge/coverage/metadata_spec.rb2
-rw-r--r--spec/lib/gitlab/badge/coverage/report_spec.rb2
-rw-r--r--spec/lib/gitlab/badge/coverage/template_spec.rb2
-rw-r--r--spec/lib/gitlab/badge/pipeline/metadata_spec.rb2
-rw-r--r--spec/lib/gitlab/badge/pipeline/status_spec.rb2
-rw-r--r--spec/lib/gitlab/badge/pipeline/template_spec.rb2
-rw-r--r--spec/lib/gitlab/badge/shared/metadata.rb2
-rw-r--r--spec/lib/gitlab/bare_repository_import/importer_spec.rb18
-rw-r--r--spec/lib/gitlab/bare_repository_import/repository_spec.rb2
-rw-r--r--spec/lib/gitlab/bitbucket_import/importer_spec.rb2
-rw-r--r--spec/lib/gitlab/bitbucket_import/project_creator_spec.rb2
-rw-r--r--spec/lib/gitlab/bitbucket_import/wiki_formatter_spec.rb2
-rw-r--r--spec/lib/gitlab/bitbucket_server_import/importer_spec.rb2
-rw-r--r--spec/lib/gitlab/blame_spec.rb2
-rw-r--r--spec/lib/gitlab/build_access_spec.rb2
-rw-r--r--spec/lib/gitlab/cache/ci/project_pipeline_status_spec.rb2
-rw-r--r--spec/lib/gitlab/cache/request_cache_spec.rb2
-rw-r--r--spec/lib/gitlab/changes_list_spec.rb2
-rw-r--r--spec/lib/gitlab/chat_name_token_spec.rb2
-rw-r--r--spec/lib/gitlab/chat_spec.rb2
-rw-r--r--spec/lib/gitlab/checks/change_access_spec.rb2
-rw-r--r--spec/lib/gitlab/checks/force_push_spec.rb2
-rw-r--r--spec/lib/gitlab/checks/lfs_integrity_spec.rb2
-rw-r--r--spec/lib/gitlab/checks/project_created_spec.rb2
-rw-r--r--spec/lib/gitlab/checks/project_moved_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/ansi2html_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/build/artifacts/adapters/gzip_stream_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/build/artifacts/adapters/raw_stream_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/build/artifacts/metadata/entry_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/build/artifacts/metadata_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/build/artifacts/path_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/build/credentials/factory_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/build/credentials/registry_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/build/image_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/build/policy/changes_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/build/policy/kubernetes_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/build/policy/refs_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/build/policy/variables_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/build/policy_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/build/step_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/charts_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/config/entry/artifacts_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/config/entry/cache_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/config/entry/commands_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/config/entry/coverage_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/config/entry/default_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/config/entry/environment_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/config/entry/hidden_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/config/entry/image_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/config/entry/job_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/config/entry/jobs_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/config/entry/key_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/config/entry/paths_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/config/entry/policy_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/config/entry/reports_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/config/entry/retry_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/config/entry/root_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/config/entry/script_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/config/entry/service_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/config/entry/services_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/config/entry/stage_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/config/entry/stages_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/config/entry/variables_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/config/extendable/entry_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/config/extendable_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/config_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/cron_parser_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/mask_secret_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/parsers/test/junit_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/pipeline/chain/build_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/pipeline/chain/command_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/pipeline/chain/create_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/pipeline/chain/populate_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/pipeline/chain/sequence_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/pipeline/chain/skip_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/pipeline/chain/validate/abilities_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/pipeline/chain/validate/config_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/pipeline/chain/validate/repository_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/pipeline/duration_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/pipeline/expression/lexeme/and_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/pipeline/expression/lexeme/equals_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/pipeline/expression/lexeme/matches_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/pipeline/expression/lexeme/not_equals_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/pipeline/expression/lexeme/not_matches_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/pipeline/expression/lexeme/null_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/pipeline/expression/lexeme/or_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/pipeline/expression/lexeme/pattern_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/pipeline/expression/lexeme/string_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/pipeline/expression/lexeme/variable_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/pipeline/expression/lexer_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/pipeline/expression/parser_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/pipeline/expression/statement_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/pipeline/expression/token_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/pipeline/seed/stage_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/reports/test_case_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/reports/test_reports_comparer_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/reports/test_reports_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/reports/test_suite_comparer_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/reports/test_suite_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/status/build/action_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/status/build/cancelable_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/status/build/canceled_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/status/build/common_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/status/build/created_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/status/build/erased_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/status/build/factory_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/status/build/failed_allowed_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/status/build/failed_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/status/build/failed_unmet_prerequisites_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/status/build/manual_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/status/build/pending_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/status/build/play_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/status/build/retried_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/status/build/retryable_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/status/build/scheduled_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/status/build/skipped_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/status/build/stop_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/status/build/unschedule_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/status/canceled_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/status/created_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/status/extended_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/status/external/common_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/status/external/factory_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/status/factory_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/status/failed_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/status/group/common_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/status/group/factory_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/status/manual_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/status/pending_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/status/pipeline/blocked_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/status/pipeline/common_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/status/pipeline/delayed_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/status/pipeline/factory_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/status/running_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/status/scheduled_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/status/skipped_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/status/stage/common_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/status/stage/factory_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/status/success_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/status/success_warning_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/trace/chunked_io_spec.rb4
-rw-r--r--spec/lib/gitlab/ci/trace/section_parser_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/trace_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/variables/collection/item_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/variables/collection_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/yaml_processor_spec.rb2
-rw-r--r--spec/lib/gitlab/ci_access_spec.rb2
-rw-r--r--spec/lib/gitlab/closing_issue_extractor_spec.rb2
-rw-r--r--spec/lib/gitlab/color_schemes_spec.rb2
-rw-r--r--spec/lib/gitlab/config/entry/attributable_spec.rb2
-rw-r--r--spec/lib/gitlab/config/entry/boolean_spec.rb2
-rw-r--r--spec/lib/gitlab/config/entry/configurable_spec.rb2
-rw-r--r--spec/lib/gitlab/config/entry/factory_spec.rb2
-rw-r--r--spec/lib/gitlab/config/entry/simplifiable_spec.rb2
-rw-r--r--spec/lib/gitlab/config/entry/undefined_spec.rb2
-rw-r--r--spec/lib/gitlab/config/entry/unspecified_spec.rb2
-rw-r--r--spec/lib/gitlab/config/entry/validatable_spec.rb2
-rw-r--r--spec/lib/gitlab/config/entry/validator_spec.rb2
-rw-r--r--spec/lib/gitlab/config/loader/yaml_spec.rb2
-rw-r--r--spec/lib/gitlab/conflict/file_collection_spec.rb2
-rw-r--r--spec/lib/gitlab/conflict/file_spec.rb2
-rw-r--r--spec/lib/gitlab/contributions_calendar_spec.rb2
-rw-r--r--spec/lib/gitlab/cross_project_access/check_collection_spec.rb2
-rw-r--r--spec/lib/gitlab/cross_project_access/check_info_spec.rb2
-rw-r--r--spec/lib/gitlab/cross_project_access/class_methods_spec.rb2
-rw-r--r--spec/lib/gitlab/cross_project_access_spec.rb2
-rw-r--r--spec/lib/gitlab/crypto_helper_spec.rb2
-rw-r--r--spec/lib/gitlab/current_settings_spec.rb2
-rw-r--r--spec/lib/gitlab/cycle_analytics/base_event_fetcher_spec.rb2
-rw-r--r--spec/lib/gitlab/cycle_analytics/code_event_fetcher_spec.rb2
-rw-r--r--spec/lib/gitlab/cycle_analytics/code_stage_spec.rb2
-rw-r--r--spec/lib/gitlab/cycle_analytics/events_spec.rb2
-rw-r--r--spec/lib/gitlab/cycle_analytics/issue_event_fetcher_spec.rb2
-rw-r--r--spec/lib/gitlab/cycle_analytics/issue_stage_spec.rb2
-rw-r--r--spec/lib/gitlab/cycle_analytics/permissions_spec.rb2
-rw-r--r--spec/lib/gitlab/cycle_analytics/plan_event_fetcher_spec.rb2
-rw-r--r--spec/lib/gitlab/cycle_analytics/plan_stage_spec.rb2
-rw-r--r--spec/lib/gitlab/cycle_analytics/production_event_fetcher_spec.rb2
-rw-r--r--spec/lib/gitlab/cycle_analytics/production_stage_spec.rb2
-rw-r--r--spec/lib/gitlab/cycle_analytics/review_event_fetcher_spec.rb2
-rw-r--r--spec/lib/gitlab/cycle_analytics/review_stage_spec.rb2
-rw-r--r--spec/lib/gitlab/cycle_analytics/shared_event_spec.rb2
-rw-r--r--spec/lib/gitlab/cycle_analytics/shared_stage_spec.rb2
-rw-r--r--spec/lib/gitlab/cycle_analytics/stage_summary_spec.rb2
-rw-r--r--spec/lib/gitlab/cycle_analytics/staging_event_fetcher_spec.rb2
-rw-r--r--spec/lib/gitlab/cycle_analytics/staging_stage_spec.rb2
-rw-r--r--spec/lib/gitlab/cycle_analytics/test_event_fetcher_spec.rb2
-rw-r--r--spec/lib/gitlab/cycle_analytics/test_stage_spec.rb2
-rw-r--r--spec/lib/gitlab/cycle_analytics/updater_spec.rb2
-rw-r--r--spec/lib/gitlab/cycle_analytics/usage_data_spec.rb2
-rw-r--r--spec/lib/gitlab/daemon_spec.rb2
-rw-r--r--spec/lib/gitlab/data_builder/build_spec.rb2
-rw-r--r--spec/lib/gitlab/data_builder/note_spec.rb2
-rw-r--r--spec/lib/gitlab/data_builder/pipeline_spec.rb2
-rw-r--r--spec/lib/gitlab/data_builder/push_spec.rb2
-rw-r--r--spec/lib/gitlab/data_builder/wiki_page_spec.rb2
-rw-r--r--spec/lib/gitlab/database/count/exact_count_strategy_spec.rb2
-rw-r--r--spec/lib/gitlab/database/count/reltuples_count_strategy_spec.rb4
-rw-r--r--spec/lib/gitlab/database/count/tablesample_count_strategy_spec.rb4
-rw-r--r--spec/lib/gitlab/database/count_spec.rb2
-rw-r--r--spec/lib/gitlab/database/grant_spec.rb4
-rw-r--r--spec/lib/gitlab/database/migration_helpers_spec.rb2
-rw-r--r--spec/lib/gitlab/database/multi_threaded_migration_spec.rb2
-rw-r--r--spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_base_spec.rb2
-rw-r--r--spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_namespaces_spec.rb2
-rw-r--r--spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_projects_spec.rb2
-rw-r--r--spec/lib/gitlab/database/rename_reserved_paths_migration/v1_spec.rb2
-rw-r--r--spec/lib/gitlab/database/sha_attribute_spec.rb2
-rw-r--r--spec/lib/gitlab/database_spec.rb2
-rw-r--r--spec/lib/gitlab/dependency_linker/cartfile_linker_spec.rb2
-rw-r--r--spec/lib/gitlab/dependency_linker/composer_json_linker_spec.rb2
-rw-r--r--spec/lib/gitlab/dependency_linker/gemfile_linker_spec.rb2
-rw-r--r--spec/lib/gitlab/dependency_linker/gemspec_linker_spec.rb2
-rw-r--r--spec/lib/gitlab/dependency_linker/godeps_json_linker_spec.rb2
-rw-r--r--spec/lib/gitlab/dependency_linker/package_json_linker_spec.rb2
-rw-r--r--spec/lib/gitlab/dependency_linker/podfile_linker_spec.rb2
-rw-r--r--spec/lib/gitlab/dependency_linker/podspec_json_linker_spec.rb2
-rw-r--r--spec/lib/gitlab/dependency_linker/podspec_linker_spec.rb2
-rw-r--r--spec/lib/gitlab/dependency_linker/requirements_txt_linker_spec.rb2
-rw-r--r--spec/lib/gitlab/dependency_linker_spec.rb2
-rw-r--r--spec/lib/gitlab/diff/diff_refs_spec.rb2
-rw-r--r--spec/lib/gitlab/diff/file_collection/merge_request_diff_spec.rb2
-rw-r--r--spec/lib/gitlab/diff/file_spec.rb2
-rw-r--r--spec/lib/gitlab/diff/formatters/image_formatter_spec.rb2
-rw-r--r--spec/lib/gitlab/diff/formatters/text_formatter_spec.rb2
-rw-r--r--spec/lib/gitlab/diff/highlight_spec.rb2
-rw-r--r--spec/lib/gitlab/diff/inline_diff_markdown_marker_spec.rb2
-rw-r--r--spec/lib/gitlab/diff/inline_diff_marker_spec.rb2
-rw-r--r--spec/lib/gitlab/diff/inline_diff_spec.rb2
-rw-r--r--spec/lib/gitlab/diff/line_mapper_spec.rb2
-rw-r--r--spec/lib/gitlab/diff/line_spec.rb2
-rw-r--r--spec/lib/gitlab/diff/parallel_diff_spec.rb2
-rw-r--r--spec/lib/gitlab/diff/parser_spec.rb2
-rw-r--r--spec/lib/gitlab/diff/position_spec.rb2
-rw-r--r--spec/lib/gitlab/diff/position_tracer_spec.rb2
-rw-r--r--spec/lib/gitlab/downtime_check/message_spec.rb2
-rw-r--r--spec/lib/gitlab/downtime_check_spec.rb2
-rw-r--r--spec/lib/gitlab/email/attachment_uploader_spec.rb2
-rw-r--r--spec/lib/gitlab/email/hook/additional_headers_interceptor_spec.rb2
-rw-r--r--spec/lib/gitlab/email/hook/delivery_metrics_observer_spec.rb2
-rw-r--r--spec/lib/gitlab/email/hook/disable_email_interceptor_spec.rb2
-rw-r--r--spec/lib/gitlab/email/message/repository_push_spec.rb2
-rw-r--r--spec/lib/gitlab/email/receiver_spec.rb2
-rw-r--r--spec/lib/gitlab/email/reply_parser_spec.rb2
-rw-r--r--spec/lib/gitlab/encoding_helper_spec.rb14
-rw-r--r--spec/lib/gitlab/etag_caching/middleware_spec.rb2
-rw-r--r--spec/lib/gitlab/etag_caching/router_spec.rb2
-rw-r--r--spec/lib/gitlab/group_search_results_spec.rb6
-rw-r--r--spec/lib/gitlab/manifest_import/manifest_spec.rb2
-rw-r--r--spec/lib/gitlab/manifest_import/project_creator_spec.rb2
-rw-r--r--spec/lib/gitlab/object_hierarchy_spec.rb2
-rw-r--r--spec/lib/gitlab/performance_bar_spec.rb4
-rw-r--r--spec/lib/gitlab/project_authorizations_spec.rb38
-rw-r--r--spec/lib/gitlab/sql/cte_spec.rb2
-rw-r--r--spec/lib/gitlab/sql/recursive_cte_spec.rb2
-rw-r--r--spec/lib/gitlab/submodule_links_spec.rb47
-rw-r--r--spec/lib/prometheus/pid_provider_spec.rb66
-rw-r--r--spec/mailers/notify_spec.rb21
-rw-r--r--spec/models/ci/pipeline_spec.rb17
-rw-r--r--spec/models/ci/runner_spec.rb2
-rw-r--r--spec/models/clusters/cluster_spec.rb2
-rw-r--r--spec/models/concerns/deployment_platform_spec.rb2
-rw-r--r--spec/models/concerns/group_descendant_spec.rb6
-rw-r--r--spec/models/concerns/issuable_spec.rb2
-rw-r--r--spec/models/deployment_metrics_spec.rb12
-rw-r--r--spec/models/group_spec.rb28
-rw-r--r--spec/models/members/group_member_spec.rb2
-rw-r--r--spec/models/members/project_member_spec.rb2
-rw-r--r--spec/models/namespace/root_storage_statistics_spec.rb2
-rw-r--r--spec/models/namespace_spec.rb20
-rw-r--r--spec/models/notification_recipient_spec.rb2
-rw-r--r--spec/models/postgresql/replication_slot_spec.rb2
-rw-r--r--spec/models/project_group_link_spec.rb2
-rw-r--r--spec/models/project_services/chat_message/pipeline_message_spec.rb484
-rw-r--r--spec/models/project_services/microsoft_teams_service_spec.rb3
-rw-r--r--spec/models/project_spec.rb101
-rw-r--r--spec/models/todo_spec.rb6
-rw-r--r--spec/models/user_spec.rb38
-rw-r--r--spec/policies/group_member_policy_spec.rb2
-rw-r--r--spec/policies/group_policy_spec.rb59
-rw-r--r--spec/presenters/clusters/cluster_presenter_spec.rb2
-rw-r--r--spec/requests/api/boards_spec.rb2
-rw-r--r--spec/requests/api/graphql/namespace/projects_spec.rb2
-rw-r--r--spec/requests/api/group_labels_spec.rb4
-rw-r--r--spec/requests/api/groups_spec.rb10
-rw-r--r--spec/requests/api/issues/get_group_issues_spec.rb2
-rw-r--r--spec/requests/api/members_spec.rb6
-rw-r--r--spec/requests/api/merge_requests_spec.rb2
-rw-r--r--spec/requests/api/projects_spec.rb2
-rw-r--r--spec/requests/api/resource_label_events_spec.rb45
-rw-r--r--spec/requests/openid_connect_spec.rb2
-rw-r--r--spec/serializers/group_child_entity_spec.rb2
-rw-r--r--spec/serializers/group_child_serializer_spec.rb4
-rw-r--r--spec/serializers/pipeline_serializer_spec.rb2
-rw-r--r--spec/services/boards/issues/list_service_spec.rb2
-rw-r--r--spec/services/groups/auto_devops_service_spec.rb2
-rw-r--r--spec/services/groups/create_service_spec.rb46
-rw-r--r--spec/services/groups/nested_create_service_spec.rb30
-rw-r--r--spec/services/groups/transfer_service_spec.rb17
-rw-r--r--spec/services/groups/update_service_spec.rb2
-rw-r--r--spec/services/issues/update_service_spec.rb4
-rw-r--r--spec/services/members/destroy_service_spec.rb6
-rw-r--r--spec/services/notification_service_spec.rb50
-rw-r--r--spec/services/projects/autocomplete_service_spec.rb2
-rw-r--r--spec/services/todos/destroy/entity_leave_service_spec.rb2
-rw-r--r--spec/services/todos/destroy/group_private_service_spec.rb2
-rw-r--r--spec/services/users/refresh_authorized_projects_service_spec.rb4
-rw-r--r--spec/spec_helper.rb8
-rw-r--r--spec/support/controllers/githubish_import_controller_shared_examples.rb6
-rw-r--r--spec/support/helpers/prometheus_helpers.rb8
-rw-r--r--spec/support/shared_contexts/policies/group_policy_shared_context.rb2
-rw-r--r--spec/support/shared_examples/models/chat_service_shared_examples.rb3
-rw-r--r--spec/support/shared_examples/notify_shared_examples.rb2
-rw-r--r--spec/support/shared_examples/project_latest_successful_build_for_examples.rb63
-rw-r--r--spec/support/shared_examples/resource_label_events_api.rb44
-rw-r--r--spec/support/shared_examples/slack_mattermost_notifications_shared_examples.rb4
-rw-r--r--spec/views/groups/edit.html.haml_spec.rb2
-rw-r--r--spec/views/layouts/header/_new_dropdown.haml_spec.rb2
-rw-r--r--yarn.lock10
738 files changed, 4329 insertions, 1550 deletions
diff --git a/app/assets/javascripts/commons/polyfills.js b/app/assets/javascripts/commons/polyfills.js
index 7a6ad3dc771..daa941a63cd 100644
--- a/app/assets/javascripts/commons/polyfills.js
+++ b/app/assets/javascripts/commons/polyfills.js
@@ -12,6 +12,7 @@ import 'core-js/es/promise/finally';
import 'core-js/es/string/code-point-at';
import 'core-js/es/string/from-code-point';
import 'core-js/es/string/includes';
+import 'core-js/es/string/repeat';
import 'core-js/es/string/starts-with';
import 'core-js/es/string/ends-with';
import 'core-js/es/symbol';
diff --git a/app/assets/javascripts/gl_form.js b/app/assets/javascripts/gl_form.js
index a66555838ba..b98fe9f6ce2 100644
--- a/app/assets/javascripts/gl_form.js
+++ b/app/assets/javascripts/gl_form.js
@@ -3,9 +3,16 @@ import autosize from 'autosize';
import GfmAutoComplete, { defaultAutocompleteConfig } from 'ee_else_ce/gfm_auto_complete';
import dropzoneInput from './dropzone_input';
import { addMarkdownListeners, removeMarkdownListeners } from './lib/utils/text_markdown';
+import IndentHelper from './helpers/indent_helper';
+import { keystroke } from './lib/utils/common_utils';
+import * as keys from './lib/utils/keycodes';
+import UndoStack from './lib/utils/undo_stack';
export default class GLForm {
constructor(form, enableGFM = {}) {
+ this.handleKeyShortcuts = this.handleKeyShortcuts.bind(this);
+ this.setState = this.setState.bind(this);
+
this.form = form;
this.textarea = this.form.find('textarea.js-gfm-input');
this.enableGFM = Object.assign({}, defaultAutocompleteConfig, enableGFM);
@@ -16,6 +23,10 @@ export default class GLForm {
this.enableGFM[item] = Boolean(dataSources[item]);
}
});
+
+ this.undoStack = new UndoStack();
+ this.indentHelper = new IndentHelper(this.textarea[0]);
+
// Before we start, we should clean up any previous data for this form
this.destroy();
// Set up the form
@@ -85,9 +96,84 @@ export default class GLForm {
clearEventListeners() {
this.textarea.off('focus');
this.textarea.off('blur');
+ this.textarea.off('keydown');
removeMarkdownListeners(this.form);
}
+ setState(state) {
+ const selection = [this.textarea[0].selectionStart, this.textarea[0].selectionEnd];
+ this.textarea.val(state);
+ this.textarea[0].setSelectionRange(selection[0], selection[1]);
+ }
+
+ /*
+ Handle keypresses for a custom undo/redo stack.
+ We need this because the toolbar buttons and indentation helpers mess with the browser's
+ native undo/redo capability.
+ */
+ handleUndo(event) {
+ const content = this.textarea.val();
+ const { selectionStart, selectionEnd } = this.textarea[0];
+ const stack = this.undoStack;
+
+ if (stack.isEmpty()) {
+ // ==== Save initial state in undo history ====
+ stack.save(content);
+ }
+
+ if (keystroke(event, keys.Z_KEY_CODE, 'l')) {
+ // ==== Undo ====
+ event.preventDefault();
+ stack.save(content);
+ if (stack.canUndo()) {
+ this.setState(stack.undo());
+ }
+ } else if (keystroke(event, keys.Z_KEY_CODE, 'ls') || keystroke(event, keys.Y_KEY_CODE, 'l')) {
+ // ==== Redo ====
+ event.preventDefault();
+ if (stack.canRedo()) {
+ this.setState(stack.redo());
+ }
+ } else if (
+ keystroke(event, keys.SPACE_KEY_CODE) ||
+ keystroke(event, keys.ENTER_KEY_CODE) ||
+ selectionStart !== selectionEnd
+ ) {
+ // ==== Save after finishing a word or before deleting a large selection ====
+ stack.save(content);
+ } else if (content === '') {
+ // ==== Save after deleting everything ====
+ stack.save('');
+ } else {
+ // ==== Save after 1 second of inactivity ====
+ stack.scheduleSave(content);
+ }
+ }
+
+ handleIndent(event) {
+ if (keystroke(event, keys.LEFT_BRACKET_KEY_CODE, 'l')) {
+ // ==== Unindent selected lines ====
+ event.preventDefault();
+ this.indentHelper.unindent();
+ } else if (keystroke(event, keys.RIGHT_BRACKET_KEY_CODE, 'l')) {
+ // ==== Indent selected lines ====
+ event.preventDefault();
+ this.indentHelper.indent();
+ } else if (keystroke(event, keys.ENTER_KEY_CODE)) {
+ // ==== Auto-indent new lines ====
+ event.preventDefault();
+ this.indentHelper.newline();
+ } else if (keystroke(event, keys.BACKSPACE_KEY_CODE)) {
+ // ==== Auto-delete indents at the beginning of the line ====
+ this.indentHelper.backspace(event);
+ }
+ }
+
+ handleKeyShortcuts(event) {
+ this.handleIndent(event);
+ this.handleUndo(event);
+ }
+
addEventListeners() {
this.textarea.on('focus', function focusTextArea() {
$(this)
@@ -99,5 +185,6 @@ export default class GLForm {
.closest('.md-area')
.removeClass('is-focused');
});
+ this.textarea.on('keydown', e => this.handleKeyShortcuts(e.originalEvent));
}
}
diff --git a/app/assets/javascripts/helpers/indent_helper.js b/app/assets/javascripts/helpers/indent_helper.js
new file mode 100644
index 00000000000..a8815fac04e
--- /dev/null
+++ b/app/assets/javascripts/helpers/indent_helper.js
@@ -0,0 +1,182 @@
+const INDENT_SEQUENCE = ' ';
+
+function countLeftSpaces(text) {
+ const i = text.split('').findIndex(c => c !== ' ');
+ return i === -1 ? text.length : i;
+}
+
+/**
+ * IndentHelper provides methods that allow manual and smart indentation in
+ * textareas. It supports line indent/unindent, selection indent/unindent,
+ * auto indentation on newlines, and smart deletion of indents with backspace.
+ */
+export default class IndentHelper {
+ /**
+ * Creates a new IndentHelper and binds it to the given `textarea`. You can provide a custom indent sequence in the second parameter, but the `newline` and `backspace` operations may work funny if the indent sequence isn't spaces only.
+ */
+ constructor(textarea, indentSequence = INDENT_SEQUENCE) {
+ this.element = textarea;
+ this.seq = indentSequence;
+ }
+
+ getSelection() {
+ return { start: this.element.selectionStart, end: this.element.selectionEnd };
+ }
+
+ isRangeSelection() {
+ return this.element.selectionStart !== this.element.selectionEnd;
+ }
+
+ /**
+ * Re-implementation of textarea's setRangeText method, because IE/Edge don't support it.
+ *
+ * @see https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#dom-textarea%2Finput-setrangetext
+ */
+ setRangeText(replacement, start, end, selectMode) {
+ // Disable eslint to remain as faithful as possible to the above linked spec
+ /* eslint-disable no-param-reassign, no-case-declarations */
+ const text = this.element.value;
+
+ if (start > end) {
+ throw new RangeError('setRangeText: start index must be less than or equal to end index');
+ }
+
+ // Clamp to [0, len]
+ start = Math.max(0, Math.min(start, text.length));
+ end = Math.max(0, Math.min(end, text.length));
+
+ let selection = { start: this.element.selectionStart, end: this.element.selectionEnd };
+
+ this.element.value = text.slice(0, start) + replacement + text.slice(end);
+
+ const newLength = replacement.length;
+ const newEnd = start + newLength;
+
+ switch (selectMode) {
+ case 'select':
+ selection = { start, newEnd };
+ break;
+ case 'start':
+ selection = { start, end: start };
+ break;
+ case 'end':
+ selection = { start: newEnd, end: newEnd };
+ break;
+ case 'preserve':
+ default:
+ const oldLength = end - start;
+ const delta = newLength - oldLength;
+ if (selection.start > end) {
+ selection.start += delta;
+ } else if (selection.start > start) {
+ selection.start = start;
+ }
+ if (selection.end > end) {
+ selection.end += delta;
+ } else if (selection.end > start) {
+ selection.end = newEnd;
+ }
+ }
+
+ this.element.setSelectionRange(selection.start, selection.end);
+
+ /* eslint-enable no-param-reassign, no-case-declarations */
+ }
+
+ /**
+ * Returns an array of lines in the textarea, with information about their
+ * start/end offsets and whether they are included in the current selection.
+ */
+ splitLines() {
+ const { start, end } = this.getSelection();
+
+ const lines = this.element.value.split('\n');
+ let textStart = 0;
+ const lineObjects = [];
+ lines.forEach(line => {
+ const lineObj = {
+ text: line,
+ start: textStart,
+ end: textStart + line.length,
+ };
+ lineObj.inSelection = lineObj.start <= end && lineObj.end >= start;
+ lineObjects.push(lineObj);
+ textStart += line.length + 1;
+ });
+ return lineObjects;
+ }
+
+ /**
+ * Indents selected lines by one level.
+ */
+ indent() {
+ const { start } = this.getSelection();
+
+ const selectedLines = this.splitLines().filter(line => line.inSelection);
+ if (!this.isRangeSelection() && start === selectedLines[0].start) {
+ // Special case: if cursor is at the beginning of the line, move it one
+ // indent right.
+ const line = selectedLines[0];
+ this.setRangeText(this.seq, line.start, line.start, 'end');
+ } else {
+ selectedLines.reverse();
+ selectedLines.forEach(line => {
+ this.setRangeText(INDENT_SEQUENCE, line.start, line.start, 'preserve');
+ });
+ }
+ }
+
+ /**
+ * Unindents selected lines by one level.
+ */
+ unindent() {
+ const lines = this.splitLines().filter(line => line.inSelection);
+ lines.reverse();
+ lines
+ .filter(line => line.text.startsWith(this.seq))
+ .forEach(line => {
+ this.setRangeText('', line.start, line.start + this.seq.length, 'preserve');
+ });
+ }
+
+ /**
+ * Emulates a newline keypress, automatically indenting the new line.
+ */
+ newline() {
+ const { start, end } = this.getSelection();
+
+ if (this.isRangeSelection()) {
+ // Manually kill the selection before calculating the indent
+ this.setRangeText('', start, end, 'start');
+ }
+
+ // Auto-indent the next line
+ const currentLine = this.splitLines().find(line => line.end >= start);
+ const spaces = countLeftSpaces(currentLine.text);
+ this.setRangeText(`\n${' '.repeat(spaces)}`, start, start, 'end');
+ }
+
+ /**
+ * If the cursor is positioned at the end of a line's leading indents,
+ * emulates a backspace keypress by deleting a single level of indents.
+ * @param event The DOM KeyboardEvent that triggers this action, or null.
+ */
+ backspace(event) {
+ const { start } = this.getSelection();
+
+ // If the cursor is at the end of leading indents, delete an indent.
+ if (!this.isRangeSelection()) {
+ const currentLine = this.splitLines().find(line => line.end >= start);
+ const cursorPosition = start - currentLine.start;
+ if (countLeftSpaces(currentLine.text) === cursorPosition && cursorPosition > 0) {
+ if (event) event.preventDefault();
+
+ let spacesToDelete = cursorPosition % this.seq.length;
+ if (spacesToDelete === 0) {
+ spacesToDelete = this.seq.length;
+ }
+ this.setRangeText('', start - spacesToDelete, start, 'start');
+ }
+ }
+ }
+}
diff --git a/app/assets/javascripts/lib/utils/common_utils.js b/app/assets/javascripts/lib/utils/common_utils.js
index 5e90893b684..1a94aee2398 100644
--- a/app/assets/javascripts/lib/utils/common_utils.js
+++ b/app/assets/javascripts/lib/utils/common_utils.js
@@ -203,6 +203,71 @@ export const isMetaKey = e => e.metaKey || e.ctrlKey || e.altKey || e.shiftKey;
// 3) Middle-click or Mouse Wheel Click (e.which is 2)
export const isMetaClick = e => e.metaKey || e.ctrlKey || e.which === 2;
+export const getPlatformLeaderKey = () => {
+ // eslint-disable-next-line @gitlab/i18n/no-non-i18n-strings
+ if (navigator && navigator.platform && navigator.platform.startsWith('Mac')) {
+ return 'meta';
+ }
+ return 'ctrl';
+};
+
+export const getPlatformLeaderKeyHTML = () => {
+ if (getPlatformLeaderKey() === 'meta') {
+ return '&#8984;';
+ }
+ // eslint-disable-next-line @gitlab/i18n/no-non-i18n-strings
+ return 'Ctrl';
+};
+
+export const isPlatformLeaderKey = e => {
+ if (getPlatformLeaderKey() === 'meta') {
+ return Boolean(e.metaKey);
+ }
+ return Boolean(e.ctrlKey);
+};
+
+/**
+ * Tests if a KeyboardEvent corresponds exactly to a keystroke.
+ *
+ * This function avoids hacking around an old version of Mousetrap, which we ship at the moment. It should be removed after we upgrade to the newest Mousetrap. See:
+ * - https://gitlab.com/gitlab-org/gitlab-ce/issues/63182
+ * - https://gitlab.com/gitlab-org/gitlab-ce/issues/64246
+ *
+ * @example
+ * // Matches the enter key with exactly zero modifiers
+ * keystroke(event, 13)
+ *
+ * @example
+ * // Matches Control-Shift-Z
+ * keystroke(event, 90, 'cs')
+ *
+ * @param e The KeyboardEvent to test.
+ * @param keyCode The key code of the key to test. Why keycodes? IE/Edge don't support the more convenient `key` and `code` properties.
+ * @param modifiers A string of modifiers keys. Each modifier key is represented by one character. The set of pressed modifier keys must match the given string exactly. Available options are 'a' for Alt/Option, 'c' for Control, 'm' for Meta/Command, 's' for Shift, and 'l' for the leader key (Meta on MacOS and Control otherwise).
+ * @returns {boolean} True if the KeyboardEvent corresponds to the given keystroke.
+ */
+export const keystroke = (e, keyCode, modifiers = '') => {
+ if (!e || !keyCode) {
+ return false;
+ }
+
+ const leader = getPlatformLeaderKey();
+ const mods = modifiers.toLowerCase().replace('l', leader.charAt(0));
+
+ // Match depressed modifier keys
+ if (
+ e.altKey !== mods.includes('a') ||
+ e.ctrlKey !== mods.includes('c') ||
+ e.metaKey !== mods.includes('m') ||
+ e.shiftKey !== mods.includes('s')
+ ) {
+ return false;
+ }
+
+ // Match the depressed key
+ return keyCode === (e.keyCode || e.which);
+};
+
export const contentTop = () => {
const perfBar = $('#js-peek').outerHeight() || 0;
const mrTabsHeight = $('.merge-request-tabs').outerHeight() || 0;
diff --git a/app/assets/javascripts/lib/utils/keycodes.js b/app/assets/javascripts/lib/utils/keycodes.js
index 5e0f9b612a2..e24fcf47d71 100644
--- a/app/assets/javascripts/lib/utils/keycodes.js
+++ b/app/assets/javascripts/lib/utils/keycodes.js
@@ -1,4 +1,10 @@
-export const UP_KEY_CODE = 38;
-export const DOWN_KEY_CODE = 40;
+export const BACKSPACE_KEY_CODE = 8;
export const ENTER_KEY_CODE = 13;
export const ESC_KEY_CODE = 27;
+export const SPACE_KEY_CODE = 32;
+export const UP_KEY_CODE = 38;
+export const DOWN_KEY_CODE = 40;
+export const Y_KEY_CODE = 89;
+export const Z_KEY_CODE = 90;
+export const LEFT_BRACKET_KEY_CODE = 219;
+export const RIGHT_BRACKET_KEY_CODE = 221;
diff --git a/app/assets/javascripts/lib/utils/undo_stack.js b/app/assets/javascripts/lib/utils/undo_stack.js
new file mode 100644
index 00000000000..6cfdc2a0a0f
--- /dev/null
+++ b/app/assets/javascripts/lib/utils/undo_stack.js
@@ -0,0 +1,105 @@
+/**
+ * UndoStack provides a custom implementation of an undo/redo engine. It was originally written for GitLab's Markdown editor (`gl_form.js`), whose rich text editing capabilities broke native browser undo/redo behaviour.
+ *
+ * UndoStack supports predictable undos/redos, debounced saves, maximum history length, and duplicate detection.
+ *
+ * Usage:
+ * - `stack = new UndoStack();`
+ * - Saves a state to the stack with `stack.save(state)`.
+ * - Get the current state with `stack.current()`.
+ * - Revert to the previous state with `stack.undo()`.
+ * - Redo a previous undo with `stack.redo()`;
+ * - Queue a future save with `stack.scheduleSave(state, delay)`. Useful for text editors.
+ * - See the full undo history in `stack.history`.
+ */
+export default class UndoStack {
+ constructor(maxLength = 1000) {
+ this.clear();
+ this.maxLength = maxLength;
+
+ // If you're storing reference-types in the undo stack, you might want to
+ // reassign this property to some deep-equals function.
+ this.comparator = (a, b) => a === b;
+ }
+
+ current() {
+ if (this.cursor === -1) {
+ return undefined;
+ }
+ return this.history[this.cursor];
+ }
+
+ isEmpty() {
+ return this.history.length === 0;
+ }
+
+ clear() {
+ this.clearPending();
+ this.history = [];
+ this.cursor = -1;
+ }
+
+ save(state) {
+ this.clearPending();
+ if (this.comparator(state, this.current())) {
+ // Don't save state if it's the same as the current state
+ return;
+ }
+
+ this.history.length = this.cursor + 1;
+ this.history.push(state);
+ this.cursor += 1;
+
+ if (this.history.length > this.maxLength) {
+ this.history.shift();
+ this.cursor -= 1;
+ }
+ }
+
+ scheduleSave(state, delay = 1000) {
+ this.clearPending();
+ this.pendingState = state;
+ this.timeout = setTimeout(this.saveNow.bind(this), delay);
+ }
+
+ saveNow() {
+ // Persists scheduled saves immediately
+ this.save(this.pendingState);
+ this.clearPending();
+ }
+
+ clearPending() {
+ // Cancels any scheduled saves
+ if (this.timeout) {
+ clearTimeout(this.timeout);
+ delete this.timeout;
+ delete this.pendingState;
+ }
+ }
+
+ canUndo() {
+ return this.cursor > 0;
+ }
+
+ undo() {
+ this.clearPending();
+ if (!this.canUndo()) {
+ return undefined;
+ }
+ this.cursor -= 1;
+ return this.history[this.cursor];
+ }
+
+ canRedo() {
+ return this.cursor >= 0 && this.cursor < this.history.length - 1;
+ }
+
+ redo() {
+ this.clearPending();
+ if (!this.canRedo()) {
+ return undefined;
+ }
+ this.cursor += 1;
+ return this.history[this.cursor];
+ }
+}
diff --git a/app/assets/javascripts/vue_shared/components/markdown/toolbar.vue b/app/assets/javascripts/vue_shared/components/markdown/toolbar.vue
index 8ce5b615795..21c44b59520 100644
--- a/app/assets/javascripts/vue_shared/components/markdown/toolbar.vue
+++ b/app/assets/javascripts/vue_shared/components/markdown/toolbar.vue
@@ -1,5 +1,6 @@
<script>
import { GlLink } from '@gitlab/ui';
+import { s__, sprintf } from '~/locale';
export default {
components: {
@@ -22,8 +23,28 @@ export default {
},
},
computed: {
- hasQuickActionsDocsPath() {
- return this.quickActionsDocsPath !== '';
+ toolbarHelpHtml() {
+ const mdLinkStart = `<a href="${this.markdownDocsPath}" target="_blank" rel="noopener noreferrer" tabindex="-1">`;
+ const actionsLinkStart = `<a href="${this.quickActionsDocsPath}" target="_blank" rel="noopener noreferrer" tabindex="-1">`;
+ const linkEnd = '</a>';
+
+ if (this.markdownDocsPath && !this.quickActionsDocsPath) {
+ return sprintf(
+ s__('Editor|%{mdLinkStart}Markdown is supported%{mdLinkEnd}'),
+ { mdLinkStart, mdLinkEnd: linkEnd },
+ false,
+ );
+ } else if (this.markdownDocsPath && this.quickActionsDocsPath) {
+ return sprintf(
+ s__(
+ 'Editor|%{mdLinkStart}Markdown%{mdLinkEnd} and %{actionsLinkStart}quick actions%{actionsLinkEnd} are supported',
+ ),
+ { mdLinkStart, mdLinkEnd: linkEnd, actionsLinkStart, actionsLinkEnd: linkEnd },
+ false,
+ );
+ }
+
+ return null;
},
},
};
@@ -32,21 +53,7 @@ export default {
<template>
<div class="comment-toolbar clearfix">
<div class="toolbar-text">
- <template v-if="!hasQuickActionsDocsPath && markdownDocsPath">
- <gl-link :href="markdownDocsPath" target="_blank" tabindex="-1">{{
- __('Markdown is supported')
- }}</gl-link>
- </template>
- <template v-if="hasQuickActionsDocsPath && markdownDocsPath">
- <gl-link :href="markdownDocsPath" target="_blank" tabindex="-1">{{
- __('Markdown')
- }}</gl-link>
- and
- <gl-link :href="quickActionsDocsPath" target="_blank" tabindex="-1">{{
- __('quick actions')
- }}</gl-link>
- are supported
- </template>
+ <span v-html="toolbarHelpHtml"></span>
</div>
<span v-if="canAttachFile" class="uploading-container">
<span class="uploading-progress-container hide">
diff --git a/app/assets/stylesheets/framework/common.scss b/app/assets/stylesheets/framework/common.scss
index 61ab0476c42..6b44834cc52 100644
--- a/app/assets/stylesheets/framework/common.scss
+++ b/app/assets/stylesheets/framework/common.scss
@@ -441,6 +441,7 @@ img.emoji {
.mw-460 { max-width: 460px; }
.mw-6em { max-width: 6em; }
.mw-70p { max-width: 70%; }
+.mw-90p { max-width: 90%; }
.min-height-0 { min-height: 0; }
diff --git a/app/assets/stylesheets/framework/lists.scss b/app/assets/stylesheets/framework/lists.scss
index 460d9ea9526..ecd32dcd0ce 100644
--- a/app/assets/stylesheets/framework/lists.scss
+++ b/app/assets/stylesheets/framework/lists.scss
@@ -285,3 +285,19 @@ ul.indent-list {
max-width: 350px;
}
}
+
+.horizontal-list {
+ padding-left: 0;
+ list-style: none;
+
+ > li {
+ float: left;
+ }
+
+ &.list-items-separated {
+ > li:not(:last-child)::after {
+ content: '\00b7';
+ margin: 0 $gl-padding-4;
+ }
+ }
+}
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index 0c80a276fce..1d55a073f3b 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -421,7 +421,7 @@ class ApplicationController < ActionController::Base
end
def manifest_import_enabled?
- Group.supports_nested_objects? && Gitlab::CurrentSettings.import_sources.include?('manifest')
+ Gitlab::CurrentSettings.import_sources.include?('manifest')
end
def phabricator_import_enabled?
diff --git a/app/controllers/concerns/authenticates_with_two_factor.rb b/app/controllers/concerns/authenticates_with_two_factor.rb
index 4926062f9ca..8c8f0b3a22e 100644
--- a/app/controllers/concerns/authenticates_with_two_factor.rb
+++ b/app/controllers/concerns/authenticates_with_two_factor.rb
@@ -55,7 +55,7 @@ module AuthenticatesWithTwoFactor
remember_me(user) if user_params[:remember_me] == '1'
user.save!
- sign_in(user, message: :two_factor_authenticated)
+ sign_in(user, message: :two_factor_authenticated, event: :authentication)
else
user.increment_failed_attempts!
Gitlab::AppLogger.info("Failed Login: user=#{user.username} ip=#{request.remote_ip} method=OTP")
@@ -72,7 +72,7 @@ module AuthenticatesWithTwoFactor
session.delete(:challenge)
remember_me(user) if user_params[:remember_me] == '1'
- sign_in(user, message: :two_factor_authenticated)
+ sign_in(user, message: :two_factor_authenticated, event: :authentication)
else
user.increment_failed_attempts!
Gitlab::AppLogger.info("Failed Login: user=#{user.username} ip=#{request.remote_ip} method=U2F")
diff --git a/app/controllers/concerns/group_tree.rb b/app/controllers/concerns/group_tree.rb
index e9a7d6a3152..d076c62c707 100644
--- a/app/controllers/concerns/group_tree.rb
+++ b/app/controllers/concerns/group_tree.rb
@@ -32,18 +32,14 @@ module GroupTree
def filtered_groups_with_ancestors(groups)
filtered_groups = groups.search(params[:filter]).page(params[:page])
- if Group.supports_nested_objects?
- # We find the ancestors by ID of the search results here.
- # Otherwise the ancestors would also have filters applied,
- # which would cause them not to be preloaded.
- #
- # Pagination needs to be applied before loading the ancestors to
- # make sure ancestors are not cut off by pagination.
- Gitlab::ObjectHierarchy.new(Group.where(id: filtered_groups.select(:id)))
- .base_and_ancestors
- else
- filtered_groups
- end
+ # We find the ancestors by ID of the search results here.
+ # Otherwise the ancestors would also have filters applied,
+ # which would cause them not to be preloaded.
+ #
+ # Pagination needs to be applied before loading the ancestors to
+ # make sure ancestors are not cut off by pagination.
+ Gitlab::ObjectHierarchy.new(Group.where(id: filtered_groups.select(:id)))
+ .base_and_ancestors
end
# rubocop: enable CodeReuse/ActiveRecord
end
diff --git a/app/controllers/omniauth_callbacks_controller.rb b/app/controllers/omniauth_callbacks_controller.rb
index 2a8dd997d04..b1efa767154 100644
--- a/app/controllers/omniauth_callbacks_controller.rb
+++ b/app/controllers/omniauth_callbacks_controller.rb
@@ -139,7 +139,7 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController
if user.two_factor_enabled? && !auth_user.bypass_two_factor?
prompt_for_two_factor(user)
else
- sign_in_and_redirect(user)
+ sign_in_and_redirect(user, event: :authentication)
end
else
fail_login(user)
diff --git a/app/controllers/projects/artifacts_controller.rb b/app/controllers/projects/artifacts_controller.rb
index 2ef18d900f2..da8a371acaa 100644
--- a/app/controllers/projects/artifacts_controller.rb
+++ b/app/controllers/projects/artifacts_controller.rb
@@ -92,7 +92,10 @@ class Projects::ArtifactsController < Projects::ApplicationController
def build_from_ref
return unless @ref_name
- project.latest_successful_build_for(params[:job], @ref_name)
+ commit = project.commit(@ref_name)
+ return unless commit
+
+ project.latest_successful_build_for_sha(params[:job], commit.id)
end
def artifacts_file
diff --git a/app/controllers/projects/build_artifacts_controller.rb b/app/controllers/projects/build_artifacts_controller.rb
index 4274c356227..99f4524eec5 100644
--- a/app/controllers/projects/build_artifacts_controller.rb
+++ b/app/controllers/projects/build_artifacts_controller.rb
@@ -51,6 +51,6 @@ class Projects::BuildArtifactsController < Projects::ApplicationController
def job_from_ref
return unless @ref_name
- project.latest_successful_build_for(params[:job], @ref_name)
+ project.latest_successful_build_for_ref(params[:job], @ref_name)
end
end
diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb
index 7604b31467a..1880bead3ee 100644
--- a/app/controllers/sessions_controller.rb
+++ b/app/controllers/sessions_controller.rb
@@ -26,6 +26,17 @@ class SessionsController < Devise::SessionsController
after_action :log_failed_login, if: -> { action_name == 'new' && failed_login? }
helper_method :captcha_enabled?
+ # protect_from_forgery is already prepended in ApplicationController but
+ # authenticate_with_two_factor which signs in the user is prepended before
+ # that here.
+ # We need to make sure CSRF token is verified before authenticating the user
+ # because Devise.clean_up_csrf_token_on_authentication is set to true by
+ # default to avoid CSRF token fixation attacks. Authenticating the user first
+ # would cause the CSRF token to be cleared and then
+ # RequestForgeryProtection#verify_authenticity_token would fail because of
+ # token mismatch.
+ protect_from_forgery with: :exception, prepend: true
+
CAPTCHA_HEADER = 'X-GitLab-Show-Login-Captcha'.freeze
def new
diff --git a/app/finders/group_descendants_finder.rb b/app/finders/group_descendants_finder.rb
index ec340f38450..4e489a9c930 100644
--- a/app/finders/group_descendants_finder.rb
+++ b/app/finders/group_descendants_finder.rb
@@ -132,8 +132,6 @@ class GroupDescendantsFinder
end
def subgroups
- return Group.none unless Group.supports_nested_objects?
-
# When filtering subgroups, we want to find all matches within the tree of
# descendants to show to the user
groups = if params[:filter]
diff --git a/app/graphql/types/group_type.rb b/app/graphql/types/group_type.rb
index 530aecc2bf9..66b41919914 100644
--- a/app/graphql/types/group_type.rb
+++ b/app/graphql/types/group_type.rb
@@ -14,10 +14,8 @@ module Types
group.avatar_url(only_path: false)
end
- if ::Group.supports_nested_objects?
- field :parent, GroupType,
- null: true,
- resolve: -> (obj, _args, _ctx) { Gitlab::Graphql::Loaders::BatchModelLoader.new(Group, obj.parent_id).find }
- end
+ field :parent, GroupType,
+ null: true,
+ resolve: -> (obj, _args, _ctx) { Gitlab::Graphql::Loaders::BatchModelLoader.new(Group, obj.parent_id).find }
end
end
diff --git a/app/helpers/groups_helper.rb b/app/helpers/groups_helper.rb
index 5aed7e313e6..160f9ac4793 100644
--- a/app/helpers/groups_helper.rb
+++ b/app/helpers/groups_helper.rb
@@ -127,10 +127,6 @@ module GroupsHelper
groups.to_json
end
- def supports_nested_groups?
- Group.supports_nested_objects?
- end
-
private
def get_group_sidebar_links
diff --git a/app/helpers/submodule_helper.rb b/app/helpers/submodule_helper.rb
index 9a281065b90..e683e2959d1 100644
--- a/app/helpers/submodule_helper.rb
+++ b/app/helpers/submodule_helper.rb
@@ -13,6 +13,8 @@ module SubmoduleHelper
end
def submodule_links_for_url(submodule_item_id, url, repository)
+ return [nil, nil] unless url
+
if url == '.' || url == './'
url = File.join(Gitlab.config.gitlab.url, repository.project.full_path)
end
diff --git a/app/mailers/emails/members.rb b/app/mailers/emails/members.rb
index 2bfa59774d7..76fa7236ab1 100644
--- a/app/mailers/emails/members.rb
+++ b/app/mailers/emails/members.rb
@@ -9,11 +9,11 @@ module Emails
helper_method :member_source, :member
end
- def member_access_requested_email(member_source_type, member_id, recipient_notification_email)
+ def member_access_requested_email(member_source_type, member_id, recipient_id)
@member_source_type = member_source_type
@member_id = member_id
- mail(to: recipient_notification_email,
+ mail(to: recipient(recipient_id, notification_group),
subject: subject("Request to join the #{member_source.human_name} #{member_source.model_name.singular}"))
end
@@ -21,16 +21,15 @@ module Emails
@member_source_type = member_source_type
@member_id = member_id
- mail(to: member.user.notification_email,
+ mail(to: recipient(member.user, notification_group),
subject: subject("Access to the #{member_source.human_name} #{member_source.model_name.singular} was granted"))
end
def member_access_denied_email(member_source_type, source_id, user_id)
@member_source_type = member_source_type
@member_source = member_source_class.find(source_id)
- requester = User.find(user_id)
- mail(to: requester.notification_email,
+ mail(to: recipient(user_id, notification_group),
subject: subject("Access to the #{member_source.human_name} #{member_source.model_name.singular} was denied"))
end
@@ -48,7 +47,7 @@ module Emails
@member_id = member_id
return unless member.created_by
- mail(to: member.created_by.notification_email,
+ mail(to: recipient(member.created_by, notification_group),
subject: subject('Invitation accepted'))
end
@@ -59,7 +58,7 @@ module Emails
@member_source = member_source_class.find(source_id)
@invite_email = invite_email
- mail(to: recipient(created_by_id, member_source_type == 'Project' ? @member_source.group : @member_source),
+ mail(to: recipient(created_by_id, notification_group),
subject: subject('Invitation declined'))
end
@@ -71,6 +70,10 @@ module Emails
@member_source ||= member.source
end
+ def notification_group
+ @member_source_type.casecmp?('project') ? member_source.group : member_source
+ end
+
private
def member_source_class
diff --git a/app/mailers/notify.rb b/app/mailers/notify.rb
index 8ef20a03541..5d292094a05 100644
--- a/app/mailers/notify.rb
+++ b/app/mailers/notify.rb
@@ -71,14 +71,18 @@ class Notify < BaseMailer
address.format
end
- # Look up a User by their ID and return their email address
+ # Look up a User's notification email for a particular context.
+ # Can look up by their ID or can accept a User object.
#
- # recipient_id - User ID
+ # recipient - User object OR a User ID
# notification_group - The parent group of the notification
#
# Returns a String containing the User's email address.
- def recipient(recipient_id, notification_group = nil)
- User.find(recipient_id).notification_email_for(notification_group)
+ def recipient(recipient, notification_group = nil)
+ user = recipient if recipient.is_a?(User)
+ user ||= User.find(recipient)
+
+ user.notification_email_for(notification_group)
end
# Formats arguments into a String suitable for use as an email subject
diff --git a/app/mailers/previews/notify_preview.rb b/app/mailers/previews/notify_preview.rb
index 80e0a17c312..b3fab930922 100644
--- a/app/mailers/previews/notify_preview.rb
+++ b/app/mailers/previews/notify_preview.rb
@@ -105,11 +105,11 @@ class NotifyPreview < ActionMailer::Preview
end
def member_access_granted_email
- Notify.member_access_granted_email('project', user.id).message
+ Notify.member_access_granted_email(member.source_type, member.id).message
end
def member_access_requested_email
- Notify.member_access_requested_email('group', user.id, 'some@example.com').message
+ Notify.member_access_requested_email('group', user.id, user.id).message
end
def member_invite_accepted_email
@@ -183,6 +183,10 @@ class NotifyPreview < ActionMailer::Preview
@user ||= User.last
end
+ def member
+ @member ||= Member.last
+ end
+
def create_note(params)
Notes::CreateService.new(project, user, params).execute
end
diff --git a/app/models/ci/pipeline.rb b/app/models/ci/pipeline.rb
index c2eb51ba100..1c76f401690 100644
--- a/app/models/ci/pipeline.rb
+++ b/app/models/ci/pipeline.rb
@@ -229,10 +229,12 @@ module Ci
#
# ref - The name (or names) of the branch(es)/tag(s) to limit the list of
# pipelines to.
+ # sha - The commit SHA (or mutliple SHAs) to limit the list of pipelines to.
# limit - This limits a backlog search, default to 100.
- def self.newest_first(ref: nil, limit: 100)
+ def self.newest_first(ref: nil, sha: nil, limit: 100)
relation = order(id: :desc)
relation = relation.where(ref: ref) if ref
+ relation = relation.where(sha: sha) if sha
if limit
ids = relation.limit(limit).select(:id)
@@ -246,10 +248,14 @@ module Ci
newest_first(ref: ref).pluck(:status).first
end
- def self.latest_successful_for(ref)
+ def self.latest_successful_for_ref(ref)
newest_first(ref: ref).success.take
end
+ def self.latest_successful_for_sha(sha)
+ newest_first(sha: sha).success.take
+ end
+
def self.latest_successful_for_refs(refs)
relation = newest_first(ref: refs).success
diff --git a/app/models/concerns/descendant.rb b/app/models/concerns/descendant.rb
deleted file mode 100644
index 4c436522122..00000000000
--- a/app/models/concerns/descendant.rb
+++ /dev/null
@@ -1,11 +0,0 @@
-# frozen_string_literal: true
-
-module Descendant
- extend ActiveSupport::Concern
-
- class_methods do
- def supports_nested_objects?
- Gitlab::Database.postgresql?
- end
- end
-end
diff --git a/app/models/concerns/protected_ref.rb b/app/models/concerns/protected_ref.rb
index af387c99f3d..0648b4a78e1 100644
--- a/app/models/concerns/protected_ref.rb
+++ b/app/models/concerns/protected_ref.rb
@@ -47,7 +47,7 @@ module ProtectedRef
def access_levels_for_ref(ref, action:, protected_refs: nil)
self.matching(ref, protected_refs: protected_refs)
- .map(&:"#{action}_access_levels").flatten
+ .flat_map(&:"#{action}_access_levels")
end
# Returns all protected refs that match the given ref name.
diff --git a/app/models/deployment_metrics.rb b/app/models/deployment_metrics.rb
index cfe762ca25e..2056c8bc59c 100644
--- a/app/models/deployment_metrics.rb
+++ b/app/models/deployment_metrics.rb
@@ -44,18 +44,7 @@ class DeploymentMetrics
end
end
- # TODO remove fallback case to deployment_platform_cluster.
- # Otherwise we will continue to pay the performance penalty described in
- # https://gitlab.com/gitlab-org/gitlab-ce/issues/63475
- #
- # Removal issue: https://gitlab.com/gitlab-org/gitlab-ce/issues/64105
def cluster_prometheus
- cluster_with_fallback = cluster || deployment_platform_cluster
-
- cluster_with_fallback.application_prometheus if cluster_with_fallback&.application_prometheus_available?
- end
-
- def deployment_platform_cluster
- deployment.environment.deployment_platform&.cluster
+ cluster.application_prometheus if cluster&.application_prometheus_available?
end
end
diff --git a/app/models/group.rb b/app/models/group.rb
index 26ce2957e9b..74eb556b1b5 100644
--- a/app/models/group.rb
+++ b/app/models/group.rb
@@ -10,7 +10,6 @@ class Group < Namespace
include Referable
include SelectForProjectAuthorization
include LoadedInGroupList
- include Descendant
include GroupDescendant
include TokenAuthenticatable
include WithUploads
@@ -388,7 +387,7 @@ class Group < Namespace
variables = Ci::GroupVariable.where(group: list_of_ids)
variables = variables.unprotected unless project.protected_for?(ref)
variables = variables.group_by(&:group_id)
- list_of_ids.reverse.map { |group| variables[group.id] }.compact.flatten
+ list_of_ids.reverse.flat_map { |group| variables[group.id] }.compact
end
def group_member(user)
diff --git a/app/models/namespace.rb b/app/models/namespace.rb
index b8d7348268a..058350b16ce 100644
--- a/app/models/namespace.rb
+++ b/app/models/namespace.rb
@@ -332,8 +332,6 @@ class Namespace < ApplicationRecord
end
def force_share_with_group_lock_on_descendants
- return unless Group.supports_nested_objects?
-
# We can't use `descendants.update_all` since Rails will throw away the WITH
# RECURSIVE statement. We also can't use WHERE EXISTS since we can't use
# different table aliases, hence we're just using WHERE IN. Since we have a
diff --git a/app/models/project.rb b/app/models/project.rb
index 0020e423628..cca7da8c49a 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -719,16 +719,27 @@ class Project < ApplicationRecord
repository.commits_by(oids: oids)
end
- # ref can't be HEAD, can only be branch/tag name or SHA
- def latest_successful_build_for(job_name, ref = default_branch)
- latest_pipeline = ci_pipelines.latest_successful_for(ref)
+ # ref can't be HEAD, can only be branch/tag name
+ def latest_successful_build_for_ref(job_name, ref = default_branch)
+ return unless ref
+
+ latest_pipeline = ci_pipelines.latest_successful_for_ref(ref)
+ return unless latest_pipeline
+
+ latest_pipeline.builds.latest.with_artifacts_archive.find_by(name: job_name)
+ end
+
+ def latest_successful_build_for_sha(job_name, sha)
+ return unless sha
+
+ latest_pipeline = ci_pipelines.latest_successful_for_sha(sha)
return unless latest_pipeline
latest_pipeline.builds.latest.with_artifacts_archive.find_by(name: job_name)
end
- def latest_successful_build_for!(job_name, ref = default_branch)
- latest_successful_build_for(job_name, ref) || raise(ActiveRecord::RecordNotFound.new("Couldn't find job #{job_name}"))
+ def latest_successful_build_for_ref!(job_name, ref = default_branch)
+ latest_successful_build_for_ref(job_name, ref) || raise(ActiveRecord::RecordNotFound.new("Couldn't find job #{job_name}"))
end
def merge_base_commit(first_commit_id, second_commit_id)
@@ -1503,12 +1514,12 @@ class Project < ApplicationRecord
end
@latest_successful_pipeline_for_default_branch =
- ci_pipelines.latest_successful_for(default_branch)
+ ci_pipelines.latest_successful_for_ref(default_branch)
end
def latest_successful_pipeline_for(ref = nil)
if ref && ref != default_branch
- ci_pipelines.latest_successful_for(ref)
+ ci_pipelines.latest_successful_for_ref(ref)
else
latest_successful_pipeline_for_default_branch
end
diff --git a/app/models/project_services/chat_message/pipeline_message.rb b/app/models/project_services/chat_message/pipeline_message.rb
index 62aec4351db..4edf263433f 100644
--- a/app/models/project_services/chat_message/pipeline_message.rb
+++ b/app/models/project_services/chat_message/pipeline_message.rb
@@ -1,24 +1,47 @@
# frozen_string_literal: true
+require 'slack-notifier'
module ChatMessage
class PipelineMessage < BaseMessage
+ MAX_VISIBLE_JOBS = 10
+
+ attr_reader :user
attr_reader :ref_type
attr_reader :ref
attr_reader :status
+ attr_reader :detailed_status
attr_reader :duration
+ attr_reader :finished_at
attr_reader :pipeline_id
+ attr_reader :failed_stages
+ attr_reader :failed_jobs
+
+ attr_reader :project
+ attr_reader :commit
+ attr_reader :committer
+ attr_reader :pipeline
def initialize(data)
super
+ @user = data[:user]
@user_name = data.dig(:user, :username) || 'API'
pipeline_attributes = data[:object_attributes]
@ref_type = pipeline_attributes[:tag] ? 'tag' : 'branch'
@ref = pipeline_attributes[:ref]
@status = pipeline_attributes[:status]
+ @detailed_status = pipeline_attributes[:detailed_status]
@duration = pipeline_attributes[:duration].to_i
+ @finished_at = pipeline_attributes[:finished_at] ? Time.parse(pipeline_attributes[:finished_at]).to_i : nil
@pipeline_id = pipeline_attributes[:id]
+ @failed_jobs = Array(data[:builds]).select { |b| b[:status] == 'failed' }.reverse # Show failed jobs from oldest to newest
+ @failed_stages = @failed_jobs.map { |j| j[:stage] }.uniq
+
+ @project = Project.find(data[:project][:id])
+ @commit = project.commit_by(oid: data[:commit][:id])
+ @committer = commit.committer
+ @pipeline = Ci::Pipeline.find(pipeline_id)
end
def pretext
@@ -28,38 +51,145 @@ module ChatMessage
def attachments
return message if markdown
- [{ text: format(message), color: attachment_color }]
+ return [{ text: format(message), color: attachment_color }] unless fancy_notifications?
+
+ [{
+ fallback: format(message),
+ color: attachment_color,
+ author_name: user_combined_name,
+ author_icon: user_avatar,
+ author_link: author_url,
+ title: s_("ChatMessage|Pipeline #%{pipeline_id} %{humanized_status} in %{duration}") %
+ {
+ pipeline_id: pipeline_id,
+ humanized_status: humanized_status,
+ duration: pretty_duration(duration)
+ },
+ title_link: pipeline_url,
+ fields: attachments_fields,
+ footer: project.name,
+ footer_icon: project.avatar_url,
+ ts: finished_at
+ }]
end
def activity
{
- title: "Pipeline #{pipeline_link} of #{ref_type} #{branch_link} by #{user_combined_name} #{humanized_status}",
- subtitle: "in #{project_link}",
- text: "in #{pretty_duration(duration)}",
+ title: s_("ChatMessage|Pipeline %{pipeline_link} of %{ref_type} %{branch_link} by %{user_combined_name} %{humanized_status}") %
+ {
+ pipeline_link: pipeline_link,
+ ref_type: ref_type,
+ branch_link: branch_link,
+ user_combined_name: user_combined_name,
+ humanized_status: humanized_status
+ },
+ subtitle: s_("ChatMessage|in %{project_link}") % { project_link: project_link },
+ text: s_("ChatMessage|in %{duration}") % { duration: pretty_duration(duration) },
image: user_avatar || ''
}
end
private
+ def fancy_notifications?
+ Feature.enabled?(:fancy_pipeline_slack_notifications, default_enabled: true)
+ end
+
+ def failed_stages_field
+ {
+ title: s_("ChatMessage|Failed stage").pluralize(failed_stages.length),
+ value: Slack::Notifier::LinkFormatter.format(failed_stages_links),
+ short: true
+ }
+ end
+
+ def failed_jobs_field
+ {
+ title: s_("ChatMessage|Failed job").pluralize(failed_jobs.length),
+ value: Slack::Notifier::LinkFormatter.format(failed_jobs_links),
+ short: true
+ }
+ end
+
+ def yaml_error_field
+ {
+ title: s_("ChatMessage|Invalid CI config YAML file"),
+ value: pipeline.yaml_errors,
+ short: false
+ }
+ end
+
+ def attachments_fields
+ fields = [
+ {
+ title: ref_type == "tag" ? s_("ChatMessage|Tag") : s_("ChatMessage|Branch"),
+ value: Slack::Notifier::LinkFormatter.format(ref_name_link),
+ short: true
+ },
+ {
+ title: s_("ChatMessage|Commit"),
+ value: Slack::Notifier::LinkFormatter.format(commit_link),
+ short: true
+ }
+ ]
+
+ fields << failed_stages_field if failed_stages.any?
+ fields << failed_jobs_field if failed_jobs.any?
+ fields << yaml_error_field if pipeline.has_yaml_errors?
+
+ fields
+ end
+
def message
- "#{project_link}: Pipeline #{pipeline_link} of #{ref_type} #{branch_link} by #{user_combined_name} #{humanized_status} in #{pretty_duration(duration)}"
+ s_("ChatMessage|%{project_link}: Pipeline %{pipeline_link} of %{ref_type} %{branch_link} by %{user_combined_name} %{humanized_status} in %{duration}") %
+ {
+ project_link: project_link,
+ pipeline_link: pipeline_link,
+ ref_type: ref_type,
+ branch_link: branch_link,
+ user_combined_name: user_combined_name,
+ humanized_status: humanized_status,
+ duration: pretty_duration(duration)
+ }
end
def humanized_status
- case status
- when 'success'
- 'passed'
+ if fancy_notifications?
+ case status
+ when 'success'
+ detailed_status == "passed with warnings" ? s_("ChatMessage|has passed with warnings") : s_("ChatMessage|has passed")
+ when 'failed'
+ s_("ChatMessage|has failed")
+ else
+ status
+ end
else
- status
+ case status
+ when 'success'
+ s_("ChatMessage|passed")
+ when 'failed'
+ s_("ChatMessage|failed")
+ else
+ status
+ end
end
end
def attachment_color
- if status == 'success'
- 'good'
+ if fancy_notifications?
+ case status
+ when 'success'
+ detailed_status == 'passed with warnings' ? 'warning' : 'good'
+ else
+ 'danger'
+ end
else
- 'danger'
+ case status
+ when 'success'
+ 'good'
+ else
+ 'danger'
+ end
end
end
@@ -71,16 +201,83 @@ module ChatMessage
"[#{ref}](#{branch_url})"
end
+ def project_url
+ project.web_url
+ end
+
def project_link
- "[#{project_name}](#{project_url})"
+ "[#{project.name}](#{project_url})"
+ end
+
+ def pipeline_failed_jobs_url
+ "#{project_url}/pipelines/#{pipeline_id}/failures"
end
def pipeline_url
- "#{project_url}/pipelines/#{pipeline_id}"
+ if fancy_notifications? && failed_jobs.any?
+ pipeline_failed_jobs_url
+ else
+ "#{project_url}/pipelines/#{pipeline_id}"
+ end
end
def pipeline_link
"[##{pipeline_id}](#{pipeline_url})"
end
+
+ def job_url(job)
+ "#{project_url}/-/jobs/#{job[:id]}"
+ end
+
+ def job_link(job)
+ "[#{job[:name]}](#{job_url(job)})"
+ end
+
+ def failed_jobs_links
+ failed = failed_jobs.slice(0, MAX_VISIBLE_JOBS)
+ truncated = failed_jobs.slice(MAX_VISIBLE_JOBS, failed_jobs.size)
+
+ failed_links = failed.map { |job| job_link(job) }
+
+ unless truncated.blank?
+ failed_links << s_("ChatMessage|and [%{count} more](%{pipeline_failed_jobs_url})") % {
+ count: truncated.size,
+ pipeline_failed_jobs_url: pipeline_failed_jobs_url
+ }
+ end
+
+ failed_links.join(I18n.translate(:'support.array.words_connector'))
+ end
+
+ def stage_link(stage)
+ # All stages link to the pipeline page
+ "[#{stage}](#{pipeline_url})"
+ end
+
+ def failed_stages_links
+ failed_stages.map { |s| stage_link(s) }.join(I18n.translate(:'support.array.words_connector'))
+ end
+
+ def commit_url
+ Gitlab::UrlBuilder.build(commit)
+ end
+
+ def commit_link
+ "[#{commit.title}](#{commit_url})"
+ end
+
+ def commits_page_url
+ "#{project_url}/commits/#{ref}"
+ end
+
+ def ref_name_link
+ "[#{ref}](#{commits_page_url})"
+ end
+
+ def author_url
+ return unless user && committer
+
+ Gitlab::UrlBuilder.build(committer)
+ end
end
end
diff --git a/app/policies/group_policy.rb b/app/policies/group_policy.rb
index 0add8bfad31..84b1873c05d 100644
--- a/app/policies/group_policy.rb
+++ b/app/policies/group_policy.rb
@@ -16,8 +16,6 @@ class GroupPolicy < BasePolicy
condition(:maintainer) { access_level >= GroupMember::MAINTAINER }
condition(:reporter) { access_level >= GroupMember::REPORTER }
- condition(:nested_groups_supported, scope: :global) { Group.supports_nested_objects? }
-
condition(:has_parent, scope: :subject) { @subject.has_parent? }
condition(:share_with_group_locked, scope: :subject) { @subject.share_with_group_lock? }
condition(:parent_share_with_group_locked, scope: :subject) { @subject.parent&.share_with_group_lock? }
@@ -108,8 +106,8 @@ class GroupPolicy < BasePolicy
enable :read_nested_project_resources
end
- rule { owner & nested_groups_supported }.enable :create_subgroup
- rule { maintainer & maintainer_can_create_group & nested_groups_supported }.enable :create_subgroup
+ rule { owner }.enable :create_subgroup
+ rule { maintainer & maintainer_can_create_group }.enable :create_subgroup
rule { public_group | logged_in_viewable }.enable :view_globally
diff --git a/app/serializers/stage_entity.rb b/app/serializers/stage_entity.rb
index 029dd3d0684..0b0454c5282 100644
--- a/app/serializers/stage_entity.rb
+++ b/app/serializers/stage_entity.rb
@@ -59,14 +59,14 @@ class StageEntity < Grape::Entity
end
def latest_statuses
- HasStatus::ORDERED_STATUSES.map do |ordered_status|
+ HasStatus::ORDERED_STATUSES.flat_map do |ordered_status|
grouped_statuses.fetch(ordered_status, [])
- end.flatten
+ end
end
def retried_statuses
- HasStatus::ORDERED_STATUSES.map do |ordered_status|
+ HasStatus::ORDERED_STATUSES.flat_map do |ordered_status|
grouped_retried_statuses.fetch(ordered_status, [])
- end.flatten
+ end
end
end
diff --git a/app/services/ci/process_pipeline_service.rb b/app/services/ci/process_pipeline_service.rb
index aaf56048b5c..207cc5017d0 100644
--- a/app/services/ci/process_pipeline_service.rb
+++ b/app/services/ci/process_pipeline_service.rb
@@ -10,13 +10,13 @@ module Ci
update_retried
new_builds =
- stage_indexes_of_created_processables.map do |index|
+ stage_indexes_of_created_processables.flat_map do |index|
process_stage(index)
end
@pipeline.update_status
- new_builds.flatten.any?
+ new_builds.any?
end
private
diff --git a/app/services/groups/nested_create_service.rb b/app/services/groups/nested_create_service.rb
index 01bd685712b..a51ac9aa593 100644
--- a/app/services/groups/nested_create_service.rb
+++ b/app/services/groups/nested_create_service.rb
@@ -18,10 +18,6 @@ module Groups
return namespace
end
- if group_path.include?('/') && !Group.supports_nested_objects?
- raise 'Nested groups are not supported on MySQL'
- end
-
create_group_path
end
diff --git a/app/services/groups/transfer_service.rb b/app/services/groups/transfer_service.rb
index 98e7c311572..fe7e07ef9f0 100644
--- a/app/services/groups/transfer_service.rb
+++ b/app/services/groups/transfer_service.rb
@@ -43,7 +43,6 @@ module Groups
def ensure_allowed_transfer
raise_transfer_error(:group_is_already_root) if group_is_already_root?
- raise_transfer_error(:database_not_supported) unless Group.supports_nested_objects?
raise_transfer_error(:same_parent_as_current) if same_parent?
raise_transfer_error(:invalid_policies) unless valid_policies?
raise_transfer_error(:namespace_with_same_path) if namespace_with_same_path?
diff --git a/app/services/members/destroy_service.rb b/app/services/members/destroy_service.rb
index c8d5e563cd8..0164760920f 100644
--- a/app/services/members/destroy_service.rb
+++ b/app/services/members/destroy_service.rb
@@ -31,7 +31,7 @@ module Members
return unless member.is_a?(GroupMember) && member.user && member.group
delete_project_members(member)
- delete_subgroup_members(member) if Group.supports_nested_objects?
+ delete_subgroup_members(member)
end
def delete_project_members(member)
diff --git a/app/services/notification_service.rb b/app/services/notification_service.rb
index a55771ed538..21fab22e0d4 100644
--- a/app/services/notification_service.rb
+++ b/app/services/notification_service.rb
@@ -595,7 +595,7 @@ class NotificationService
end
def deliver_access_request_email(recipient, member)
- mailer.member_access_requested_email(member.real_source_type, member.id, recipient.user.notification_email).deliver_later
+ mailer.member_access_requested_email(member.real_source_type, member.id, recipient.user.id).deliver_later
end
def fallback_to_group_owners_maintainers?(recipients, member)
diff --git a/app/services/users/refresh_authorized_projects_service.rb b/app/services/users/refresh_authorized_projects_service.rb
index 4a26d2be2af..ae67b4f5256 100644
--- a/app/services/users/refresh_authorized_projects_service.rb
+++ b/app/services/users/refresh_authorized_projects_service.rb
@@ -102,13 +102,7 @@ module Users
end
def fresh_authorizations
- klass = if Group.supports_nested_objects?
- Gitlab::ProjectAuthorizations::WithNestedGroups
- else
- Gitlab::ProjectAuthorizations::WithoutNestedGroups
- end
-
- klass.new(user).calculate
+ Gitlab::ProjectAuthorizations.new(user).calculate
end
end
end
diff --git a/app/views/groups/settings/_advanced.html.haml b/app/views/groups/settings/_advanced.html.haml
index 5d211d0e186..d1eb6478997 100644
--- a/app/views/groups/settings/_advanced.html.haml
+++ b/app/views/groups/settings/_advanced.html.haml
@@ -23,20 +23,19 @@
= f.submit 'Change group path', class: 'btn btn-warning'
-- if supports_nested_groups?
- .sub-section
- %h4.warning-title Transfer group
- = form_for @group, url: transfer_group_path(@group), method: :put do |f|
- .form-group
- = dropdown_tag('Select parent group', options: { toggle_class: 'js-groups-dropdown', title: 'Parent Group', filter: true, dropdown_class: 'dropdown-open-top dropdown-group-transfer', placeholder: 'Search groups', data: { data: parent_group_options(@group) } })
- = hidden_field_tag 'new_parent_group_id'
+.sub-section
+ %h4.warning-title Transfer group
+ = form_for @group, url: transfer_group_path(@group), method: :put do |f|
+ .form-group
+ = dropdown_tag('Select parent group', options: { toggle_class: 'js-groups-dropdown', title: 'Parent Group', filter: true, dropdown_class: 'dropdown-open-top dropdown-group-transfer', placeholder: 'Search groups', data: { data: parent_group_options(@group) } })
+ = hidden_field_tag 'new_parent_group_id'
- %ul
- %li Be careful. Changing a group's parent can have unintended #{link_to 'side effects', 'https://docs.gitlab.com/ce/user/project/index.html#redirects-when-changing-repository-paths', target: 'blank'}.
- %li You can only transfer the group to a group you manage.
- %li You will need to update your local repositories to point to the new location.
- %li If the parent group's visibility is lower than the group current visibility, visibility levels for subgroups and projects will be changed to match the new parent group's visibility.
- = f.submit 'Transfer group', class: 'btn btn-warning'
+ %ul
+ %li Be careful. Changing a group's parent can have unintended #{link_to 'side effects', 'https://docs.gitlab.com/ce/user/project/index.html#redirects-when-changing-repository-paths', target: 'blank'}.
+ %li You can only transfer the group to a group you manage.
+ %li You will need to update your local repositories to point to the new location.
+ %li If the parent group's visibility is lower than the group current visibility, visibility levels for subgroups and projects will be changed to match the new parent group's visibility.
+ = f.submit 'Transfer group', class: 'btn btn-warning'
.sub-section
%h4.danger-title= _('Remove group')
diff --git a/app/views/layouts/nav/sidebar/_project.html.haml b/app/views/layouts/nav/sidebar/_project.html.haml
index d1634eb62c0..92dd558885a 100644
--- a/app/views/layouts/nav/sidebar/_project.html.haml
+++ b/app/views/layouts/nav/sidebar/_project.html.haml
@@ -9,7 +9,7 @@
= @project.name
%ul.sidebar-top-level-items
= nav_link(path: sidebar_projects_paths, html_options: { class: 'home' }) do
- = link_to project_path(@project), class: 'shortcuts-project qa-link-project' do
+ = link_to project_path(@project), class: 'shortcuts-project', data: { qa_selector: 'project_link' } do
.nav-icon-container
= sprite_icon('home')
%span.nav-item-name
@@ -26,7 +26,7 @@
%span= _('Details')
= nav_link(path: 'projects#activity') do
- = link_to activity_project_path(@project), title: _('Activity'), class: 'shortcuts-project-activity qa-activity-link' do
+ = link_to activity_project_path(@project), title: _('Activity'), class: 'shortcuts-project-activity', data: { qa_selector: 'activity_link' } do
%span= _('Activity')
- if project_nav_tab?(:releases)
@@ -146,7 +146,7 @@
- if project_nav_tab? :merge_requests
= nav_link(controller: @project.issues_enabled? ? :merge_requests : [:merge_requests, :labels, :milestones]) do
- = link_to project_merge_requests_path(@project), class: 'shortcuts-merge_requests qa-merge-requests-link' do
+ = link_to project_merge_requests_path(@project), class: 'shortcuts-merge_requests', data: { qa_selector: 'merge_requests_link' } do
.nav-icon-container
= sprite_icon('git-merge')
%span.nav-item-name#js-onboarding-mr-link
@@ -277,7 +277,7 @@
- if project_nav_tab? :wiki
- wiki_url = project_wiki_path(@project, :home)
= nav_link(controller: :wikis) do
- = link_to wiki_url, class: 'shortcuts-wiki qa-wiki-link' do
+ = link_to wiki_url, class: 'shortcuts-wiki', data: { qa_selector: 'wiki_link' } do
.nav-icon-container
= sprite_icon('book')
%span.nav-item-name
diff --git a/app/views/projects/settings/ci_cd/_autodevops_form.html.haml b/app/views/projects/settings/ci_cd/_autodevops_form.html.haml
index fe74dc122c3..04b77fb987a 100644
--- a/app/views/projects/settings/ci_cd/_autodevops_form.html.haml
+++ b/app/views/projects/settings/ci_cd/_autodevops_form.html.haml
@@ -8,7 +8,7 @@
.card.auto-devops-card
.card-body
.form-check
- = form.check_box :enabled, class: 'form-check-input js-toggle-extra-settings', checked: auto_devops_enabled
+ = form.check_box :enabled, class: 'form-check-input js-toggle-extra-settings', checked: auto_devops_enabled, data: { qa_selector: 'enable_autodevops_checkbox' }
= form.label :enabled, class: 'form-check-label' do
%strong= s_('CICD|Default to Auto DevOps pipeline')
- if auto_devops_enabled
@@ -42,4 +42,4 @@
= s_('CICD|Automatic deployment to staging, manual deployment to production')
= link_to icon('question-circle'), help_page_path('topics/autodevops/index.md', anchor: 'incremental-rollout-to-production'), target: '_blank'
- = f.submit _('Save changes'), class: "btn btn-success prepend-top-15"
+ = f.submit _('Save changes'), class: "btn btn-success prepend-top-15", data: { qa_selector: 'save_changes_button' }
diff --git a/app/views/projects/settings/ci_cd/show.html.haml b/app/views/projects/settings/ci_cd/show.html.haml
index 5e3e1076c2c..293f0a241eb 100644
--- a/app/views/projects/settings/ci_cd/show.html.haml
+++ b/app/views/projects/settings/ci_cd/show.html.haml
@@ -16,7 +16,7 @@
.settings-content
= render 'form'
-%section.qa-autodevops-settings.settings#autodevops-settings.no-animate{ class: ('expanded' if expanded) }
+%section.settings#autodevops-settings.no-animate{ class: ('expanded' if expanded), data: { qa_selector: 'autodevops_settings_content' } }
.settings-header
%h4
= s_('CICD|Auto DevOps')
@@ -30,7 +30,7 @@
= render_if_exists 'projects/settings/ci_cd/protected_environments', expanded: expanded
-%section.qa-runners-settings.settings.no-animate#js-runners-settings{ class: ('expanded' if expanded) }
+%section.settings.no-animate#js-runners-settings{ class: ('expanded' if expanded), data: { qa_selector: 'runners_settings_content' } }
.settings-header
%h4
= _("Runners")
@@ -41,7 +41,7 @@
.settings-content
= render 'projects/runners/index'
-%section.qa-variables-settings.settings.no-animate{ class: ('expanded' if expanded) }
+%section.settings.no-animate{ class: ('expanded' if expanded), data: { qa_selector: 'variables_settings_content' } }
.settings-header
= render 'ci/variables/header', expanded: expanded
.settings-content
diff --git a/app/views/shared/notes/_hints.html.haml b/app/views/shared/notes/_hints.html.haml
index fae7d6526e8..72ede50dd8c 100644
--- a/app/views/shared/notes/_hints.html.haml
+++ b/app/views/shared/notes/_hints.html.haml
@@ -1,14 +1,13 @@
- supports_quick_actions = local_assigns.fetch(:supports_quick_actions, false)
.comment-toolbar.clearfix
.toolbar-text
- = link_to _('Markdown'), help_page_path('user/markdown'), target: '_blank', tabindex: -1
+ - md_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer" tabindex="-1">'.html_safe % { url: help_page_path('user/markdown') }
+ - actions_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer" tabindex="-1">'.html_safe % { url: help_page_path('user/project/quick_actions') }
+ - link_end = '</a>'.html_safe
- if supports_quick_actions
- and
- = link_to _('quick actions'), help_page_path('user/project/quick_actions'), target: '_blank', tabindex: -1
- are
+ = s_('Editor|%{mdLinkStart}Markdown%{mdLinkEnd} and %{actionsLinkStart}quick actions%{actionsLinkEnd} are supported').html_safe % { mdLinkStart: md_link_start, mdLinkEnd: link_end, actionsLinkStart: actions_link_start, actionsLinkEnd: link_end }
- else
- is
- supported
+ = s_('Editor|%{mdLinkStart}Markdown is supported%{mdLinkEnd}').html_safe % { mdLinkStart: md_link_start, mdLinkEnd: link_end }
%span.uploading-container
%span.uploading-progress-container.hide
diff --git a/changelogs/unreleased/32495-improve-slack-notification-on-pipeline-status.yml b/changelogs/unreleased/32495-improve-slack-notification-on-pipeline-status.yml
new file mode 100644
index 00000000000..b7b39303c2e
--- /dev/null
+++ b/changelogs/unreleased/32495-improve-slack-notification-on-pipeline-status.yml
@@ -0,0 +1,5 @@
+---
+title: Improve pipeline status Slack notifications
+merge_request: 27683
+author:
+type: added
diff --git a/changelogs/unreleased/59325-units-are-not-shown-on-the-performance-dashboard-2.yml b/changelogs/unreleased/59325-units-are-not-shown-on-the-performance-dashboard-2.yml
new file mode 100644
index 00000000000..38cfa0f273e
--- /dev/null
+++ b/changelogs/unreleased/59325-units-are-not-shown-on-the-performance-dashboard-2.yml
@@ -0,0 +1,5 @@
+---
+title: 'fix: updates to include units for the y axis label'
+merge_request: 30330
+author:
+type: fixed
diff --git a/changelogs/unreleased/63568-access-email-notifications-custom-email.yml b/changelogs/unreleased/63568-access-email-notifications-custom-email.yml
new file mode 100644
index 00000000000..ece6442d7cf
--- /dev/null
+++ b/changelogs/unreleased/63568-access-email-notifications-custom-email.yml
@@ -0,0 +1,5 @@
+---
+title: Respect group notification email when sending group access notifications
+merge_request: 31089
+author:
+type: fixed
diff --git a/changelogs/unreleased/64257-warden_set_user_fix.yml b/changelogs/unreleased/64257-warden_set_user_fix.yml
new file mode 100644
index 00000000000..7b6818876fb
--- /dev/null
+++ b/changelogs/unreleased/64257-warden_set_user_fix.yml
@@ -0,0 +1,5 @@
+---
+title: Ensure Warden triggers after_authentication callback
+merge_request: 31138
+author:
+type: fixed
diff --git a/changelogs/unreleased/64972-fix-unicorn-workers-metric.yml b/changelogs/unreleased/64972-fix-unicorn-workers-metric.yml
new file mode 100644
index 00000000000..f80111f0bd9
--- /dev/null
+++ b/changelogs/unreleased/64972-fix-unicorn-workers-metric.yml
@@ -0,0 +1,5 @@
+---
+title: Fix pid discovery for Unicorn processes in `PidProvider`
+merge_request: 31056
+author:
+type: fixed
diff --git a/changelogs/unreleased/delete-designs-v2.yml b/changelogs/unreleased/delete-designs-v2.yml
new file mode 100644
index 00000000000..a678e4f93b9
--- /dev/null
+++ b/changelogs/unreleased/delete-designs-v2.yml
@@ -0,0 +1,4 @@
+---
+title: Adds event enum column to DesignsVersions join table
+merge_request: 30745
+type: added
diff --git a/changelogs/unreleased/dm-submodule-links-nil.yml b/changelogs/unreleased/dm-submodule-links-nil.yml
new file mode 100644
index 00000000000..c09ca41d01d
--- /dev/null
+++ b/changelogs/unreleased/dm-submodule-links-nil.yml
@@ -0,0 +1,5 @@
+---
+title: Fix error rendering submodules in MR diffs when there is no .gitmodules
+merge_request: 31162
+author:
+type: fixed
diff --git a/changelogs/unreleased/extract_auto_deploy_into_base_image.yml b/changelogs/unreleased/extract_auto_deploy_into_base_image.yml
new file mode 100644
index 00000000000..ff0d1f3bd71
--- /dev/null
+++ b/changelogs/unreleased/extract_auto_deploy_into_base_image.yml
@@ -0,0 +1,5 @@
+---
+title: Extract Auto DevOps deploy functions into a base image
+merge_request: 30404
+author:
+type: changed
diff --git a/changelogs/unreleased/mh-editor-indents.yml b/changelogs/unreleased/mh-editor-indents.yml
new file mode 100644
index 00000000000..a282c0f505d
--- /dev/null
+++ b/changelogs/unreleased/mh-editor-indents.yml
@@ -0,0 +1,5 @@
+---
+title: Markdown editors now have indentation shortcuts and auto-indentation
+merge_request: 28914
+author:
+type: added
diff --git a/changelogs/unreleased/remove_deployment_metrics_deployment_platform_fallback.yml b/changelogs/unreleased/remove_deployment_metrics_deployment_platform_fallback.yml
new file mode 100644
index 00000000000..d32cbd1d8e0
--- /dev/null
+++ b/changelogs/unreleased/remove_deployment_metrics_deployment_platform_fallback.yml
@@ -0,0 +1,6 @@
+---
+title: Remove incorrect fallback when determining which cluster to use when retrieving
+ MR performance metrics
+merge_request: 31126
+author:
+type: changed
diff --git a/config/prometheus/cluster_metrics.yml b/config/prometheus/cluster_metrics.yml
index 3df76b0974f..f2a41e4c337 100644
--- a/config/prometheus/cluster_metrics.yml
+++ b/config/prometheus/cluster_metrics.yml
@@ -2,12 +2,12 @@
priority: 1
metrics:
- title: "CPU Usage"
- y_label: "CPU"
+ y_label: "CPU (cores)"
required_metrics: ['container_cpu_usage_seconds_total']
weight: 1
queries:
- query_range: 'avg(sum(rate(container_cpu_usage_seconds_total{id="/"}[15m])) by (job)) without (job)'
- label: Usage
+ label: Usage (cores)
unit: "cores"
appearance:
line:
@@ -15,7 +15,7 @@
area:
opacity: 0
- query_range: 'sum(kube_pod_container_resource_requests_cpu_cores{kubernetes_namespace="gitlab-managed-apps"})'
- label: Requested
+ label: Requested (cores)
unit: "cores"
appearance:
line:
@@ -23,7 +23,7 @@
area:
opacity: 0
- query_range: 'sum(kube_node_status_capacity_cpu_cores{kubernetes_namespace="gitlab-managed-apps"})'
- label: Capacity
+ label: Capacity (cores)
unit: "cores"
appearance:
line:
@@ -32,12 +32,12 @@
area:
opacity: 0
- title: "Memory usage"
- y_label: "Memory"
+ y_label: "Memory (GiB)"
required_metrics: ['container_memory_usage_bytes']
weight: 1
queries:
- query_range: 'avg(sum(container_memory_usage_bytes{id="/"}) by (job)) without (job) / 2^30'
- label: Usage
+ label: Usage (GiB)
unit: "GiB"
appearance:
line:
@@ -45,7 +45,7 @@
area:
opacity: 0
- query_range: 'sum(kube_pod_container_resource_requests_memory_bytes{kubernetes_namespace="gitlab-managed-apps"})/2^30'
- label: Requested
+ label: Requested (GiB)
unit: "GiB"
appearance:
line:
@@ -53,7 +53,7 @@
area:
opacity: 0
- query_range: 'sum(kube_node_status_capacity_memory_bytes{kubernetes_namespace="gitlab-managed-apps"})/2^30'
- label: Capacity
+ label: Capacity (GiB)
unit: "GiB"
appearance:
line:
diff --git a/config/prometheus/common_metrics.yml b/config/prometheus/common_metrics.yml
index f9ce5a6f365..32475ef8380 100644
--- a/config/prometheus/common_metrics.yml
+++ b/config/prometheus/common_metrics.yml
@@ -21,16 +21,16 @@ panel_groups:
metrics:
- id: response_metrics_nginx_ingress_latency_pod_average
query_range: 'avg(nginx_upstream_response_msecs_avg{upstream=~"%{kube_namespace}-%{ci_environment_slug}-.*"})'
- label: Pod average
+ label: Pod average (ms)
unit: ms
- title: "HTTP Error Rate"
type: "area-chart"
- y_label: "HTTP Errors"
+ y_label: "HTTP Errors (%)"
weight: 1
metrics:
- id: response_metrics_nginx_ingress_http_error_rate
query_range: 'sum(rate(nginx_upstream_responses_total{status_code="5xx", upstream=~"%{kube_namespace}-%{ci_environment_slug}-.*"}[2m])) / sum(rate(nginx_upstream_responses_total{upstream=~"%{kube_namespace}-%{ci_environment_slug}-.*"}[2m])) * 100'
- label: 5xx Errors
+ label: 5xx Errors (%)
unit: "%"
# NGINX Ingress metrics for post-0.16.0 versions
- group: Response metrics (NGINX Ingress)
@@ -52,16 +52,16 @@ panel_groups:
metrics:
- id: response_metrics_nginx_ingress_16_latency_pod_average
query_range: 'sum(rate(nginx_ingress_controller_ingress_upstream_latency_seconds_sum{namespace="%{kube_namespace}",ingress=~".*%{ci_environment_slug}.*"}[2m])) / sum(rate(nginx_ingress_controller_ingress_upstream_latency_seconds_count{namespace="%{kube_namespace}",ingress=~".*%{ci_environment_slug}.*"}[2m])) * 1000'
- label: Pod average
+ label: Pod average (ms)
unit: ms
- title: "HTTP Error Rate"
type: "area-chart"
- y_label: "HTTP Errors"
+ y_label: "HTTP Errors (%)"
weight: 1
metrics:
- id: response_metrics_nginx_ingress_16_http_error_rate
query_range: 'sum(rate(nginx_ingress_controller_requests{status=~"5.*",namespace="%{kube_namespace}",ingress=~".*%{ci_environment_slug}.*"}[2m])) / sum(rate(nginx_ingress_controller_requests{namespace="%{kube_namespace}",ingress=~".*%{ci_environment_slug}.*"}[2m])) * 100'
- label: 5xx Errors
+ label: 5xx Errors (%)
unit: "%"
- group: Response metrics (HA Proxy)
priority: 10
@@ -82,7 +82,7 @@ panel_groups:
metrics:
- id: response_metrics_ha_proxy_http_error_rate
query_range: 'sum(rate(haproxy_frontend_http_responses_total{code="5xx",%{environment_filter}}[2m])) / sum(rate(haproxy_frontend_http_responses_total{%{environment_filter}}[2m]))'
- label: HTTP Errors
+ label: HTTP Errors (%)
unit: "%"
- group: Response metrics (AWS ELB)
priority: 10
@@ -94,7 +94,7 @@ panel_groups:
metrics:
- id: response_metrics_aws_elb_throughput_requests
query_range: 'sum(aws_elb_request_count_sum{%{environment_filter}}) / 60'
- label: Total
+ label: Total (req/sec)
unit: req / sec
- title: "Latency"
type: "area-chart"
@@ -103,7 +103,7 @@ panel_groups:
metrics:
- id: response_metrics_aws_elb_latency_average
query_range: 'avg(aws_elb_latency_average{%{environment_filter}}) * 1000'
- label: Average
+ label: Average (ms)
unit: ms
- title: "HTTP Error Rate"
type: "area-chart"
@@ -112,7 +112,7 @@ panel_groups:
metrics:
- id: response_metrics_aws_elb_http_error_rate
query_range: 'sum(aws_elb_httpcode_backend_5_xx_sum{%{environment_filter}}) / sum(aws_elb_request_count_sum{%{environment_filter}})'
- label: HTTP Errors
+ label: HTTP Errors (%)
unit: "%"
- group: Response metrics (NGINX)
priority: 10
@@ -133,9 +133,9 @@ panel_groups:
metrics:
- id: response_metrics_nginx_latency
query_range: 'avg(nginx_server_requestMsec{%{environment_filter}})'
- label: Upstream
+ label: Upstream (ms)
unit: ms
- - title: "HTTP Error Rate"
+ - title: "HTTP Error Rate (Errors / Sec)"
type: "area-chart"
y_label: "HTTP 500 Errors / Sec"
weight: 1
@@ -149,12 +149,12 @@ panel_groups:
panels:
- title: "Memory Usage (Total)"
type: "area-chart"
- y_label: "Total Memory Used"
+ y_label: "Total Memory Used (GB)"
weight: 4
metrics:
- id: system_metrics_kubernetes_container_memory_total
query_range: 'avg(sum(container_memory_usage_bytes{container_name!="POD",pod_name=~"^%{ci_environment_slug}-(.*)",namespace="%{kube_namespace}"}) by (job)) without (job) /1024/1024/1024'
- label: Total
+ label: Total (GB)
unit: GB
- title: "Core Usage (Total)"
type: "area-chart"
@@ -163,25 +163,25 @@ panel_groups:
metrics:
- id: system_metrics_kubernetes_container_cores_total
query_range: 'avg(sum(rate(container_cpu_usage_seconds_total{container_name!="POD",pod_name=~"^%{ci_environment_slug}-(.*)",namespace="%{kube_namespace}"}[15m])) by (job)) without (job)'
- label: Total
+ label: Total (cores)
unit: "cores"
- title: "Memory Usage (Pod average)"
type: "area-chart"
- y_label: "Memory Used per Pod"
+ y_label: "Memory Used per Pod (MB)"
weight: 2
metrics:
- id: system_metrics_kubernetes_container_memory_average
query_range: 'avg(sum(container_memory_usage_bytes{container_name!="POD",pod_name=~"^%{ci_environment_slug}-([^c].*|c([^a]|a([^n]|n([^a]|a([^r]|r[^y])))).*|)-(.*)",namespace="%{kube_namespace}"}) by (job)) without (job) / count(avg(container_memory_usage_bytes{container_name!="POD",pod_name=~"^%{ci_environment_slug}-([^c].*|c([^a]|a([^n]|n([^a]|a([^r]|r[^y])))).*|)-(.*)",namespace="%{kube_namespace}"}) without (job)) /1024/1024'
- label: Pod average
+ label: Pod average (MB)
unit: MB
- title: "Canary: Memory Usage (Pod Average)"
type: "area-chart"
- y_label: "Memory Used per Pod"
+ y_label: "Memory Used per Pod (MB)"
weight: 2
metrics:
- id: system_metrics_kubernetes_container_memory_average_canary
query_range: 'avg(sum(container_memory_usage_bytes{container_name!="POD",pod_name=~"^%{ci_environment_slug}-canary-(.*)",namespace="%{kube_namespace}"}) by (job)) without (job) / count(avg(container_memory_usage_bytes{container_name!="POD",pod_name=~"^%{ci_environment_slug}-canary-(.*)",namespace="%{kube_namespace}"}) without (job)) /1024/1024'
- label: Pod average
+ label: Pod average (MB)
unit: MB
track: canary
- title: "Core Usage (Pod Average)"
@@ -191,7 +191,7 @@ panel_groups:
metrics:
- id: system_metrics_kubernetes_container_core_usage
query_range: 'avg(sum(rate(container_cpu_usage_seconds_total{container_name!="POD",pod_name=~"^%{ci_environment_slug}-([^c].*|c([^a]|a([^n]|n([^a]|a([^r]|r[^y])))).*|)-(.*)",namespace="%{kube_namespace}"}[15m])) by (job)) without (job) / count(sum(rate(container_cpu_usage_seconds_total{container_name!="POD",pod_name=~"^%{ci_environment_slug}-([^c].*|c([^a]|a([^n]|n([^a]|a([^r]|r[^y])))).*|)-(.*)",namespace="%{kube_namespace}"}[15m])) by (pod_name))'
- label: Pod average
+ label: Pod average (cores)
unit: "cores"
- title: "Canary: Core Usage (Pod Average)"
type: "area-chart"
@@ -200,7 +200,7 @@ panel_groups:
metrics:
- id: system_metrics_kubernetes_container_core_usage_canary
query_range: 'avg(sum(rate(container_cpu_usage_seconds_total{container_name!="POD",pod_name=~"^%{ci_environment_slug}-canary-(.*)",namespace="%{kube_namespace}"}[15m])) by (job)) without (job) / count(sum(rate(container_cpu_usage_seconds_total{container_name!="POD",pod_name=~"^%{ci_environment_slug}-canary-(.*)",namespace="%{kube_namespace}"}[15m])) by (pod_name))'
- label: Pod average
+ label: Pod average (cores)
unit: "cores"
track: canary
- title: "Knative function invocations"
diff --git a/db/migrate/20190709220014_import_common_metrics_y_axis.rb b/db/migrate/20190709220014_import_common_metrics_y_axis.rb
new file mode 100644
index 00000000000..89ecf32ecc1
--- /dev/null
+++ b/db/migrate/20190709220014_import_common_metrics_y_axis.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+class ImportCommonMetricsYAxis < ActiveRecord::Migration[5.1]
+ DOWNTIME = false
+
+ def up
+ ::Gitlab::DatabaseImporters::CommonMetrics::Importer.new.execute
+ end
+
+ def down
+ # no-op
+ end
+end
diff --git a/db/migrate/20190715140740_add_event_type_to_design_management_designs_versions.rb b/db/migrate/20190715140740_add_event_type_to_design_management_designs_versions.rb
new file mode 100644
index 00000000000..81a8b0a3271
--- /dev/null
+++ b/db/migrate/20190715140740_add_event_type_to_design_management_designs_versions.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+# This migration sets up a event enum on the DesignsVersions join table
+class AddEventTypeToDesignManagementDesignsVersions < ActiveRecord::Migration[5.2]
+ include Gitlab::Database::MigrationHelpers
+
+ # Set this constant to true if this migration requires downtime.
+ DOWNTIME = false
+
+ # We disable these cops here because adding this column is safe. The table does not
+ # have any data in it.
+ # rubocop: disable Migration/AddIndex
+ # rubocop: disable Migration/AddColumn
+ def up
+ add_column(:design_management_designs_versions, :event, :integer,
+ limit: 2,
+ null: false,
+ default: 0)
+ add_index(:design_management_designs_versions, :event)
+ end
+
+ # rubocop: disable Migration/RemoveIndex
+ def down
+ remove_index(:design_management_designs_versions, :event)
+ remove_column(:design_management_designs_versions, :event)
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index dbfc5959d9d..67479937b47 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -1097,8 +1097,10 @@ ActiveRecord::Schema.define(version: 2019_07_25_012225) do
create_table "design_management_designs_versions", id: false, force: :cascade do |t|
t.bigint "design_id", null: false
t.bigint "version_id", null: false
+ t.integer "event", limit: 2, default: 0, null: false
t.index ["design_id", "version_id"], name: "design_management_designs_versions_uniqueness", unique: true
t.index ["design_id"], name: "index_design_management_designs_versions_on_design_id"
+ t.index ["event"], name: "index_design_management_designs_versions_on_event"
t.index ["version_id"], name: "index_design_management_designs_versions_on_version_id"
end
diff --git a/doc/ci/README.md b/doc/ci/README.md
index 7048ceaac41..6923d07bb1d 100644
--- a/doc/ci/README.md
+++ b/doc/ci/README.md
@@ -13,6 +13,11 @@ through the [continuous methodologies](introduction/index.md#introduction-to-cic
- Continuous Delivery (CD)
- Continuous Deployment (CD)
+NOTE: **Out-of-the-box management systems can decrease hours spent on maintaining toolchains by 10% or more.**
+Watch our
+["Mastering continuous software development"](https://about.gitlab.com/webcast/mastering-ci-cd/)
+webcast to learn about continuous methods and how GitLab’s built-in CI can help you simplify and scale software development.
+
## Overview
Continuous Integration works by pushing small code chunks to your
@@ -155,6 +160,7 @@ for your CI/CD infrastructure:
- [Why we chose GitLab CI for our CI/CD solution](https://about.gitlab.com/2016/10/17/gitlab-ci-oohlala/)
- [Building our web-app on GitLab CI](https://about.gitlab.com/2016/07/22/building-our-web-app-on-gitlab-ci/)
+- [5 Teams that made the switch to GitLab CI/CD](https://about.gitlab.com/2019/04/25/5-teams-that-made-the-switch-to-gitlab-ci-cd/)
See also the [Why CI/CD?](https://docs.google.com/presentation/d/1OGgk2Tcxbpl7DJaIOzCX4Vqg3dlwfELC3u2jEeCBbDk) presentation.
diff --git a/doc/ci/introduction/index.md b/doc/ci/introduction/index.md
index 6401ff90a0a..366aca3442e 100644
--- a/doc/ci/introduction/index.md
+++ b/doc/ci/introduction/index.md
@@ -9,6 +9,11 @@ In this document we'll present an overview of the concepts of Continuous Integra
Continuous Delivery, and Continuous Deployment, as well as an introduction to
GitLab CI/CD.
+NOTE: **Out-of-the-box management systems can decrease hours spent on maintaining toolchains by 10% or more.**
+Watch our
+["Mastering continuous software development"](https://about.gitlab.com/webcast/mastering-ci-cd/)
+webcast to learn about continuous methods and how GitLab’s built-in CI can help you simplify and scale software development.
+
## Introduction to CI/CD methodologies
The continuous methodologies of software development are based on
diff --git a/doc/ci/pipelines.md b/doc/ci/pipelines.md
index 98f30350968..be8f66c741f 100644
--- a/doc/ci/pipelines.md
+++ b/doc/ci/pipelines.md
@@ -6,6 +6,11 @@ type: reference
> Introduced in GitLab 8.8.
+NOTE: **Tip:**
+Watch our
+["Mastering continuous software development"](https://about.gitlab.com/webcast/mastering-ci-cd/)
+webcast to see a comprehensive demo of GitLab CI/CD pipeline.
+
## Introduction
Pipelines are the top-level component of continuous integration, delivery, and deployment.
diff --git a/doc/development/README.md b/doc/development/README.md
index ea5d9e10e2c..99c88146be5 100644
--- a/doc/development/README.md
+++ b/doc/development/README.md
@@ -113,6 +113,10 @@ description: 'Learn how to contribute to GitLab.'
- [Database helper modules](database_helpers.md)
- [Code comments](code_comments.md)
+## Case studies
+
+- [Database case study: Filtering by label](filtering_by_label.md)
+
## Integration guides
- [Jira Connect app](integrations/jira_connect.md)
diff --git a/doc/development/database_review.md b/doc/development/database_review.md
index 1413c2f69fb..3d10a0c84e5 100644
--- a/doc/development/database_review.md
+++ b/doc/development/database_review.md
@@ -68,6 +68,17 @@ make sure you have applied the ~database label and rerun the
`danger-review` CI job, or pick someone from the
[`@gl-database` team](https://gitlab.com/groups/gl-database/-/group_members).
+### How to prepare for speedy database reviews
+
+In order to make reviewing easier and therefore faster, please consider preparing a comment
+and details for a database reviewer:
+
+- Provide queries in SQL form rather than ActiveRecord.
+- Format any queries with a SQL query formatter, for example with [sqlformat.darold.net](http://sqlformat.darold.net).
+- Consider providing query plans via a link to [explain.depesz.com](https://explain.depesz.com) or another tool instead of textual form.
+- For query changes, it is best to provide the SQL query along with a plan *before* and *after* the change. This helps to spot differences quickly.
+- When providing query plans, make sure to use good parameter values, so that the query executed is a good example and also hits enough data. Usually, the `gitlab-org` namespace (`namespace_id = 9970`) and the `gitlab-org/gitlab-ce` project (`project_id = 13083`) provides enough data to serve as a good example.
+
### How to review for database
- Check migrations
diff --git a/doc/development/filtering_by_label.md b/doc/development/filtering_by_label.md
new file mode 100644
index 00000000000..6e6b71b1787
--- /dev/null
+++ b/doc/development/filtering_by_label.md
@@ -0,0 +1,166 @@
+# Filtering by label
+
+## Introduction
+
+GitLab has [labels](../user/project/labels.md) that can be assigned to issues,
+merge requests, and epics. Labels on those objects are a many-to-many relation
+through the polymorphic `label_links` table.
+
+To filter these objects by multiple labels - for instance, 'all open
+issues with the label ~Plan and the label ~backend' - we generate a
+query containing a `GROUP BY` clause. In a simple form, this looks like:
+
+```sql
+SELECT
+ issues.*
+FROM
+ issues
+ INNER JOIN label_links ON label_links.target_id = issues.id
+ AND label_links.target_type = 'Issue'
+ INNER JOIN labels ON labels.id = label_links.label_id
+WHERE
+ issues.project_id = 13083
+ AND (issues.state IN ('opened'))
+ AND labels.title IN ('Plan',
+ 'backend')
+GROUP BY
+ issues.id
+HAVING (COUNT(DISTINCT labels.title) = 2)
+ORDER BY
+ issues.updated_at DESC,
+ issues.id DESC
+LIMIT 20 OFFSET 0
+```
+
+In particular, note that:
+
+1. We `GROUP BY issues.id` so that we can ...
+2. Use the `HAVING (COUNT(DISTINCT labels.title) = 2)` condition to ensure that
+ all matched issues have both labels.
+
+This is more complicated than is ideal. It makes the query construction more
+prone to errors (such as
+[gitlab-org/gitlab-ce#15557](https://gitlab.com/gitlab-org/gitlab-ce/issues/15557)).
+
+## Attempt A: WHERE EXISTS
+
+### Attempt A1: use multiple subqueries with WHERE EXISTS
+
+In
+[gitlab-org/gitlab-ce#37137](https://gitlab.com/gitlab-org/gitlab-ce/issues/37137)
+and its associated merge request
+[gitlab-org/gitlab-ce!14022](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/14022),
+we tried to replace the `GROUP BY` with multiple uses of `WHERE EXISTS`. For the
+example above, this would give:
+
+```sql
+WHERE (EXISTS (
+ SELECT
+ TRUE
+ FROM
+ label_links
+ INNER JOIN labels ON labels.id = label_links.label_id
+ WHERE
+ labels.title = 'Plan'
+ AND target_type = 'Issue'
+ AND target_id = issues.id))
+AND (EXISTS (
+ SELECT
+ TRUE
+ FROM
+ label_links
+ INNER JOIN labels ON labels.id = label_links.label_id
+ WHERE
+ labels.title = 'backend'
+ AND target_type = 'Issue'
+ AND target_id = issues.id))
+```
+
+While this worked without schema changes, and did improve readability somewhat,
+it did not improve query performance.
+
+## Attempt B: Denormalize using an array column
+
+Having [removed MySQL support in GitLab
+12.1](https://about.gitlab.com/2019/06/27/removing-mysql-support/), using
+[Postgres's arrays](https://www.postgresql.org/docs/9.6/arrays.html) became more
+tractable as we didn't have to support two databases. We discussed denormalizing
+the `label_links` table for querying in
+[gitlab-org/gitlab-ce#49651](https://gitlab.com/gitlab-org/gitlab-ce/issues/49651),
+with two options: label IDs and titles.
+
+We can think of both of those as array columns on `issues`, `merge_requests`,
+and `epics`: `issues.label_ids` would be an array column of label IDs, and
+`issues.label_titles` would be an array of label titles.
+
+These array columns can be complemented with [GIN
+indexes](https://www.postgresql.org/docs/9.6/gin-intro.html) to improve
+matching.
+
+### Attempt B1: store label IDs for each object
+
+This has some strong advantages over titles:
+
+1. Unless a label is deleted, or a project is moved, we never need to
+ bulk-update the denormalized column.
+2. It uses less storage than the titles.
+
+Unfortunately, our application design makes this hard. If we were able to query
+just by label ID easily, we wouldn't need the `INNER JOIN labels` in the initial
+query at the start of this document. GitLab allows users to filter by label
+title across projects and even across groups, so a filter by the label ~Plan may
+include labels with multiple distinct IDs.
+
+We do not want users to have to know about the different IDs, which means that
+given this data set:
+
+| Project | ~Plan label ID | ~backend label ID |
+| --- | --- | --- |
+| A | 11 | 12 |
+| B | 21 | 22 |
+| C | 31 | 32 |
+
+We would need something like:
+
+```sql
+WHERE
+ label_ids @> ARRAY[11, 12]
+ OR label_ids @> ARRAY[21, 22]
+ OR label_ids @> ARRAY[31, 32]
+```
+
+This can get even more complicated when we consider that in some cases, there
+might be two ~backend labels - with different IDs - that could apply to the same
+object, so the number of combinations would balloon further.
+
+### Attempt B2: store label titles for each object
+
+From the perspective of updating the labelable object, this is the worst
+option. We have to bulk update the objects when:
+
+1. The objects are moved from one project to another.
+1. The project is moved from one group to another.
+1. The label is renamed.
+1. The label is deleted.
+
+It also uses much more storage. Querying is simple, though:
+
+```sql
+WHERE
+ label_titles @> ARRAY['Plan', 'backend']
+```
+
+And our [tests in
+gitlab-org/gitlab-ce#49651](https://gitlab.com/gitlab-org/gitlab-ce/issues/49651#note_188777346)
+showed that this could be fast.
+
+However, at present, the disadvantages outweigh the advantages.
+
+## Conclusion
+
+We have yet to find a method that is demonstratably better than the current
+method, when considering:
+
+1. Query performance.
+1. Readability.
+1. Ease of maintaining schema consistency.
diff --git a/doc/user/project/integrations/prometheus.md b/doc/user/project/integrations/prometheus.md
index ba982c9cf6f..e609fe43507 100644
--- a/doc/user/project/integrations/prometheus.md
+++ b/doc/user/project/integrations/prometheus.md
@@ -323,8 +323,9 @@ Once enabled, an issue will be opened automatically when an alert is triggered w
- `starts_at`: Alert start time via `startsAt`
- `full_query`: Alert query extracted from `generatorURL`
- Optional list of attached annotations extracted from `annotations/*`
+- Alert [GFM](../../markdown.md): GitLab Flavored Markdown from `annotations/gitlab_incident_markdown`
-To further customize the issue, you can add labels, mentions, or any other supported [quick action](../quick_actions.md) in the selected issue template.
+To further customize the issue, you can add labels, mentions, or any other supported [quick action](../quick_actions.md) in the selected issue template, which will apply to all incidents. To limit quick actions or other information to only specific types of alerts, use the `annotations/gitlab_incident_markdown` field.
Since [version 12.2](https://gitlab.com/gitlab-org/gitlab-ce/issues/63373), GitLab will tag each incident issue with the `incident` label automatically. If the label does not yet exist, it will be created automatically as well.
diff --git a/lib/api/entities.rb b/lib/api/entities.rb
index 10b4f8934d7..2e78331df6c 100644
--- a/lib/api/entities.rb
+++ b/lib/api/entities.rb
@@ -366,10 +366,7 @@ module API
end
expose :request_access_enabled
expose :full_name, :full_path
-
- if ::Group.supports_nested_objects?
- expose :parent_id
- end
+ expose :parent_id
expose :custom_attributes, using: 'API::Entities::CustomAttribute', if: :with_custom_attributes
diff --git a/lib/api/groups.rb b/lib/api/groups.rb
index ec1020c7c78..f545f33c06b 100644
--- a/lib/api/groups.rb
+++ b/lib/api/groups.rb
@@ -114,10 +114,7 @@ module API
params do
requires :name, type: String, desc: 'The name of the group'
requires :path, type: String, desc: 'The path of the group'
-
- if ::Group.supports_nested_objects?
- optional :parent_id, type: Integer, desc: 'The parent group id for creating nested group'
- end
+ optional :parent_id, type: Integer, desc: 'The parent group id for creating nested group'
use :optional_params
end
diff --git a/lib/api/job_artifacts.rb b/lib/api/job_artifacts.rb
index e7fed55170e..b35aa952f81 100644
--- a/lib/api/job_artifacts.rb
+++ b/lib/api/job_artifacts.rb
@@ -27,7 +27,7 @@ module API
requirements: { ref_name: /.+/ } do
authorize_download_artifacts!
- latest_build = user_project.latest_successful_build_for!(params[:job], params[:ref_name])
+ latest_build = user_project.latest_successful_build_for_ref!(params[:job], params[:ref_name])
present_carrierwave_file!(latest_build.artifacts_file)
end
@@ -45,7 +45,7 @@ module API
requirements: { ref_name: /.+/ } do
authorize_download_artifacts!
- build = user_project.latest_successful_build_for!(params[:job], params[:ref_name])
+ build = user_project.latest_successful_build_for_ref!(params[:job], params[:ref_name])
path = Gitlab::Ci::Build::Artifacts::Path
.new(params[:artifact_path])
diff --git a/lib/api/validations/types/labels_list.rb b/lib/api/validations/types/labels_list.rb
index 47cd83c29cf..60277b99106 100644
--- a/lib/api/validations/types/labels_list.rb
+++ b/lib/api/validations/types/labels_list.rb
@@ -10,7 +10,7 @@ module API
when String
value.split(',').map(&:strip)
when Array
- value.map { |v| v.to_s.split(',').map(&:strip) }.flatten
+ value.flat_map { |v| v.to_s.split(',').map(&:strip) }
when LabelsList
value
else
diff --git a/lib/banzai/reference_redactor.rb b/lib/banzai/reference_redactor.rb
index eb5c35da375..936436982e7 100644
--- a/lib/banzai/reference_redactor.rb
+++ b/lib/banzai/reference_redactor.rb
@@ -33,7 +33,7 @@ module Banzai
#
# data - An Array of a Hashes mapping an HTML document to nodes to redact.
def redact_document_nodes(all_document_nodes)
- all_nodes = all_document_nodes.map { |x| x[:nodes] }.flatten
+ all_nodes = all_document_nodes.flat_map { |x| x[:nodes] }
visible = nodes_visible_to_user(all_nodes)
metadata = []
diff --git a/lib/gitlab/auth/activity.rb b/lib/gitlab/auth/activity.rb
index 558628b5422..988ff196193 100644
--- a/lib/gitlab/auth/activity.rb
+++ b/lib/gitlab/auth/activity.rb
@@ -37,14 +37,17 @@ module Gitlab
def user_authenticated!
self.class.user_authenticated_counter_increment!
+
+ case @opts[:message]
+ when :two_factor_authenticated
+ self.class.user_two_factor_authenticated_counter_increment!
+ end
end
def user_session_override!
self.class.user_session_override_counter_increment!
case @opts[:message]
- when :two_factor_authenticated
- self.class.user_two_factor_authenticated_counter_increment!
when :sessionless_sign_in
self.class.user_sessionless_authentication_counter_increment!
end
diff --git a/lib/gitlab/background_migration/backfill_project_repositories.rb b/lib/gitlab/background_migration/backfill_project_repositories.rb
index c8d83cc1803..1d9aa050041 100644
--- a/lib/gitlab/background_migration/backfill_project_repositories.rb
+++ b/lib/gitlab/background_migration/backfill_project_repositories.rb
@@ -40,7 +40,7 @@ module Gitlab
end
def reload!
- @shards = Hash[*Shard.all.map { |shard| [shard.name, shard.id] }.flatten]
+ @shards = Hash[*Shard.all.flat_map { |shard| [shard.name, shard.id] }]
end
end
diff --git a/lib/gitlab/badge/coverage/report.rb b/lib/gitlab/badge/coverage/report.rb
index 7f7cc62c8ef..15cccc6f287 100644
--- a/lib/gitlab/badge/coverage/report.rb
+++ b/lib/gitlab/badge/coverage/report.rb
@@ -14,7 +14,7 @@ module Gitlab
@ref = ref
@job = job
- @pipeline = @project.ci_pipelines.latest_successful_for(@ref)
+ @pipeline = @project.ci_pipelines.latest_successful_for_ref(@ref)
end
def entity
diff --git a/lib/gitlab/ci/config/normalizer.rb b/lib/gitlab/ci/config/normalizer.rb
index 191f5d09645..99356226ef9 100644
--- a/lib/gitlab/ci/config/normalizer.rb
+++ b/lib/gitlab/ci/config/normalizer.rb
@@ -46,7 +46,7 @@ module Gitlab
parallelized_job_names = @parallelized_jobs.keys.map(&:to_s)
parallelized_config.each_with_object({}) do |(job_name, config), hash|
if config[:dependencies] && (intersection = config[:dependencies] & parallelized_job_names).any?
- parallelized_deps = intersection.map { |dep| @parallelized_jobs[dep.to_sym].map(&:first) }.flatten
+ parallelized_deps = intersection.flat_map { |dep| @parallelized_jobs[dep.to_sym].map(&:first) }
deps = config[:dependencies] - intersection + parallelized_deps
hash[job_name] = config.merge(dependencies: deps)
else
diff --git a/lib/gitlab/ci/status/factory.rb b/lib/gitlab/ci/status/factory.rb
index 3446644eff8..2a0bf060c9b 100644
--- a/lib/gitlab/ci/status/factory.rb
+++ b/lib/gitlab/ci/status/factory.rb
@@ -34,11 +34,9 @@ module Gitlab
def extended_statuses
return @extended_statuses if defined?(@extended_statuses)
- groups = self.class.extended_statuses.map do |group|
+ @extended_statuses = self.class.extended_statuses.flat_map do |group|
Array(group).find { |status| status.matches?(@subject, @user) }
- end
-
- @extended_statuses = groups.flatten.compact
+ end.compact
end
def self.extended_statuses
diff --git a/lib/gitlab/ci/templates/Auto-DevOps.gitlab-ci.yml b/lib/gitlab/ci/templates/Auto-DevOps.gitlab-ci.yml
index 7b9a169a91f..5c1c0c142e5 100644
--- a/lib/gitlab/ci/templates/Auto-DevOps.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Auto-DevOps.gitlab-ci.yml
@@ -50,9 +50,6 @@ variables:
POSTGRES_DB: $CI_ENVIRONMENT_SLUG
POSTGRES_VERSION: 9.6.2
- KUBERNETES_VERSION: 1.11.10
- HELM_VERSION: 2.14.0
-
DOCKER_DRIVER: overlay2
ROLLOUT_RESOURCE_TYPE: deployment
diff --git a/lib/gitlab/ci/templates/Jobs/Deploy.gitlab-ci.yml b/lib/gitlab/ci/templates/Jobs/Deploy.gitlab-ci.yml
index 6ead127e7b6..a8ec2d4781d 100644
--- a/lib/gitlab/ci/templates/Jobs/Deploy.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Jobs/Deploy.gitlab-ci.yml
@@ -1,14 +1,17 @@
+.auto-deploy:
+ image: "registry.gitlab.com/gitlab-org/cluster-integration/auto-deploy-image:v0.1.0"
+
review:
+ extends: .auto-deploy
stage: review
script:
- - check_kube_domain
- - install_dependencies
- - download_chart
- - ensure_namespace
- - initialize_tiller
- - create_secret
- - deploy
- - persist_environment_url
+ - auto-deploy check_kube_domain
+ - auto-deploy download_chart
+ - auto-deploy ensure_namespace
+ - auto-deploy initialize_tiller
+ - auto-deploy create_secret
+ - auto-deploy deploy
+ - auto-deploy persist_environment_url
environment:
name: review/$CI_COMMIT_REF_NAME
url: http://$CI_PROJECT_ID-$CI_ENVIRONMENT_SLUG.$KUBE_INGRESS_BASE_DOMAIN
@@ -27,13 +30,13 @@ review:
- $REVIEW_DISABLED
stop_review:
+ extends: .auto-deploy
stage: cleanup
variables:
GIT_STRATEGY: none
script:
- - install_dependencies
- - initialize_tiller
- - delete
+ - auto-deploy initialize_tiller
+ - auto-deploy delete
environment:
name: review/$CI_COMMIT_REF_NAME
action: stop
@@ -57,15 +60,15 @@ stop_review:
# STAGING_ENABLED.
staging:
+ extends: .auto-deploy
stage: staging
script:
- - check_kube_domain
- - install_dependencies
- - download_chart
- - ensure_namespace
- - initialize_tiller
- - create_secret
- - deploy
+ - auto-deploy check_kube_domain
+ - auto-deploy download_chart
+ - auto-deploy ensure_namespace
+ - auto-deploy initialize_tiller
+ - auto-deploy create_secret
+ - auto-deploy deploy
environment:
name: staging
url: http://$CI_PROJECT_PATH_SLUG-staging.$KUBE_INGRESS_BASE_DOMAIN
@@ -81,15 +84,15 @@ staging:
# CANARY_ENABLED.
canary:
+ extends: .auto-deploy
stage: canary
script:
- - check_kube_domain
- - install_dependencies
- - download_chart
- - ensure_namespace
- - initialize_tiller
- - create_secret
- - deploy canary
+ - auto-deploy check_kube_domain
+ - auto-deploy download_chart
+ - auto-deploy ensure_namespace
+ - auto-deploy initialize_tiller
+ - auto-deploy create_secret
+ - auto-deploy deploy canary
environment:
name: production
url: http://$CI_PROJECT_PATH_SLUG.$KUBE_INGRESS_BASE_DOMAIN
@@ -102,18 +105,18 @@ canary:
- $CANARY_ENABLED
.production: &production_template
+ extends: .auto-deploy
stage: production
script:
- - check_kube_domain
- - install_dependencies
- - download_chart
- - ensure_namespace
- - initialize_tiller
- - create_secret
- - deploy
- - delete canary
- - delete rollout
- - persist_environment_url
+ - auto-deploy check_kube_domain
+ - auto-deploy download_chart
+ - auto-deploy ensure_namespace
+ - auto-deploy initialize_tiller
+ - auto-deploy create_secret
+ - auto-deploy deploy
+ - auto-deploy delete canary
+ - auto-deploy delete rollout
+ - auto-deploy persist_environment_url
environment:
name: production
url: http://$CI_PROJECT_PATH_SLUG.$KUBE_INGRESS_BASE_DOMAIN
@@ -152,17 +155,17 @@ production_manual:
# This job implements incremental rollout on for every push to `master`.
.rollout: &rollout_template
+ extends: .auto-deploy
script:
- - check_kube_domain
- - install_dependencies
- - download_chart
- - ensure_namespace
- - initialize_tiller
- - create_secret
- - deploy rollout $ROLLOUT_PERCENTAGE
- - scale stable $((100-ROLLOUT_PERCENTAGE))
- - delete canary
- - persist_environment_url
+ - auto-deploy check_kube_domain
+ - auto-deploy download_chart
+ - auto-deploy ensure_namespace
+ - auto-deploy initialize_tiller
+ - auto-deploy create_secret
+ - auto-deploy deploy rollout $ROLLOUT_PERCENTAGE
+ - auto-deploy scale stable $((100-ROLLOUT_PERCENTAGE))
+ - auto-deploy delete canary
+ - auto-deploy persist_environment_url
environment:
name: production
url: http://$CI_PROJECT_PATH_SLUG.$KUBE_INGRESS_BASE_DOMAIN
@@ -240,331 +243,3 @@ rollout 100%:
<<: *manual_rollout_template
<<: *production_template
allow_failure: false
-
-.deploy_helpers: &deploy_helpers |
- [[ "$TRACE" ]] && set -x
- export RELEASE_NAME=${HELM_RELEASE_NAME:-$CI_ENVIRONMENT_SLUG}
- auto_database_url=postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${RELEASE_NAME}-postgres:5432/${POSTGRES_DB}
- export DATABASE_URL=${DATABASE_URL-$auto_database_url}
- export TILLER_NAMESPACE=$KUBE_NAMESPACE
-
- function get_replicas() {
- track="${1:-stable}"
- percentage="${2:-100}"
-
- env_track=$( echo $track | tr -s '[:lower:]' '[:upper:]' )
- env_slug=$( echo ${CI_ENVIRONMENT_SLUG//-/_} | tr -s '[:lower:]' '[:upper:]' )
-
- if [[ "$track" == "stable" ]] || [[ "$track" == "rollout" ]]; then
- # for stable track get number of replicas from `PRODUCTION_REPLICAS`
- eval new_replicas=\$${env_slug}_REPLICAS
- if [[ -z "$new_replicas" ]]; then
- new_replicas=$REPLICAS
- fi
- else
- # for all tracks get number of replicas from `CANARY_PRODUCTION_REPLICAS`
- eval new_replicas=\$${env_track}_${env_slug}_REPLICAS
- if [[ -z "$new_replicas" ]]; then
- eval new_replicas=\${env_track}_REPLICAS
- fi
- fi
-
- replicas="${new_replicas:-1}"
- replicas="$(($replicas * $percentage / 100))"
-
- # always return at least one replicas
- if [[ $replicas -gt 0 ]]; then
- echo "$replicas"
- else
- echo 1
- fi
- }
-
- # Extracts variables prefixed with K8S_SECRET_
- # and creates a Kubernetes secret.
- #
- # e.g. If we have the following environment variables:
- # K8S_SECRET_A=value1
- # K8S_SECRET_B=multi\ word\ value
- #
- # Then we will create a secret with the following key-value pairs:
- # data:
- # A: dmFsdWUxCg==
- # B: bXVsdGkgd29yZCB2YWx1ZQo=
- function create_application_secret() {
- track="${1-stable}"
- export APPLICATION_SECRET_NAME=$(application_secret_name "$track")
-
- env | sed -n "s/^K8S_SECRET_\(.*\)$/\1/p" > k8s_prefixed_variables
-
- kubectl create secret \
- -n "$KUBE_NAMESPACE" generic "$APPLICATION_SECRET_NAME" \
- --from-env-file k8s_prefixed_variables -o yaml --dry-run |
- kubectl replace -n "$KUBE_NAMESPACE" --force -f -
-
- export APPLICATION_SECRET_CHECKSUM=$(cat k8s_prefixed_variables | sha256sum | cut -d ' ' -f 1)
-
- rm k8s_prefixed_variables
- }
-
- function deploy_name() {
- name="$RELEASE_NAME"
- track="${1-stable}"
-
- if [[ "$track" != "stable" ]]; then
- name="$name-$track"
- fi
-
- echo $name
- }
-
- function application_secret_name() {
- track="${1-stable}"
- name=$(deploy_name "$track")
-
- echo "${name}-secret"
- }
-
- function deploy() {
- track="${1-stable}"
- percentage="${2:-100}"
- name=$(deploy_name "$track")
-
- if [[ -z "$CI_COMMIT_TAG" ]]; then
- image_repository=${CI_APPLICATION_REPOSITORY:-$CI_REGISTRY_IMAGE/$CI_COMMIT_REF_SLUG}
- image_tag=${CI_APPLICATION_TAG:-$CI_COMMIT_SHA}
- else
- image_repository=${CI_APPLICATION_REPOSITORY:-$CI_REGISTRY_IMAGE}
- image_tag=${CI_APPLICATION_TAG:-$CI_COMMIT_TAG}
- fi
-
- service_enabled="true"
- postgres_enabled="$POSTGRES_ENABLED"
-
- # if track is different than stable,
- # re-use all attached resources
- if [[ "$track" != "stable" ]]; then
- service_enabled="false"
- postgres_enabled="false"
- fi
-
- replicas=$(get_replicas "$track" "$percentage")
-
- if [[ "$CI_PROJECT_VISIBILITY" != "public" ]]; then
- secret_name='gitlab-registry'
- else
- secret_name=''
- fi
-
- create_application_secret "$track"
-
- env_slug=$(echo ${CI_ENVIRONMENT_SLUG//-/_} | tr -s '[:lower:]' '[:upper:]')
- eval env_ADDITIONAL_HOSTS=\$${env_slug}_ADDITIONAL_HOSTS
- if [ -n "$env_ADDITIONAL_HOSTS" ]; then
- additional_hosts="{$env_ADDITIONAL_HOSTS}"
- elif [ -n "$ADDITIONAL_HOSTS" ]; then
- additional_hosts="{$ADDITIONAL_HOSTS}"
- fi
-
- if [[ -n "$DB_INITIALIZE" && -z "$(helm ls -q "^$name$")" ]]; then
- echo "Deploying first release with database initialization..."
- helm upgrade --install \
- --wait \
- --set service.enabled="$service_enabled" \
- --set gitlab.app="$CI_PROJECT_PATH_SLUG" \
- --set gitlab.env="$CI_ENVIRONMENT_SLUG" \
- --set releaseOverride="$RELEASE_NAME" \
- --set image.repository="$image_repository" \
- --set image.tag="$image_tag" \
- --set image.pullPolicy=IfNotPresent \
- --set image.secrets[0].name="$secret_name" \
- --set application.track="$track" \
- --set application.database_url="$DATABASE_URL" \
- --set application.secretName="$APPLICATION_SECRET_NAME" \
- --set application.secretChecksum="$APPLICATION_SECRET_CHECKSUM" \
- --set service.commonName="le-$CI_PROJECT_ID.$KUBE_INGRESS_BASE_DOMAIN" \
- --set service.url="$CI_ENVIRONMENT_URL" \
- --set service.additionalHosts="$additional_hosts" \
- --set replicaCount="$replicas" \
- --set postgresql.enabled="$postgres_enabled" \
- --set postgresql.nameOverride="postgres" \
- --set postgresql.postgresUser="$POSTGRES_USER" \
- --set postgresql.postgresPassword="$POSTGRES_PASSWORD" \
- --set postgresql.postgresDatabase="$POSTGRES_DB" \
- --set postgresql.imageTag="$POSTGRES_VERSION" \
- --set application.initializeCommand="$DB_INITIALIZE" \
- $HELM_UPGRADE_EXTRA_ARGS \
- --namespace="$KUBE_NAMESPACE" \
- "$name" \
- chart/
-
- echo "Deploying second release..."
- helm upgrade --reuse-values \
- --wait \
- --set application.initializeCommand="" \
- --set application.migrateCommand="$DB_MIGRATE" \
- $HELM_UPGRADE_EXTRA_ARGS \
- --namespace="$KUBE_NAMESPACE" \
- "$name" \
- chart/
- else
- echo "Deploying new release..."
- helm upgrade --install \
- --wait \
- --set service.enabled="$service_enabled" \
- --set gitlab.app="$CI_PROJECT_PATH_SLUG" \
- --set gitlab.env="$CI_ENVIRONMENT_SLUG" \
- --set releaseOverride="$RELEASE_NAME" \
- --set image.repository="$image_repository" \
- --set image.tag="$image_tag" \
- --set image.pullPolicy=IfNotPresent \
- --set image.secrets[0].name="$secret_name" \
- --set application.track="$track" \
- --set application.database_url="$DATABASE_URL" \
- --set application.secretName="$APPLICATION_SECRET_NAME" \
- --set application.secretChecksum="$APPLICATION_SECRET_CHECKSUM" \
- --set service.commonName="le-$CI_PROJECT_ID.$KUBE_INGRESS_BASE_DOMAIN" \
- --set service.url="$CI_ENVIRONMENT_URL" \
- --set service.additionalHosts="$additional_hosts" \
- --set replicaCount="$replicas" \
- --set postgresql.enabled="$postgres_enabled" \
- --set postgresql.nameOverride="postgres" \
- --set postgresql.postgresUser="$POSTGRES_USER" \
- --set postgresql.postgresPassword="$POSTGRES_PASSWORD" \
- --set postgresql.postgresDatabase="$POSTGRES_DB" \
- --set postgresql.imageTag="$POSTGRES_VERSION" \
- --set application.migrateCommand="$DB_MIGRATE" \
- $HELM_UPGRADE_EXTRA_ARGS \
- --namespace="$KUBE_NAMESPACE" \
- "$name" \
- chart/
- fi
-
- if [[ -z "$ROLLOUT_STATUS_DISABLED" ]]; then
- kubectl rollout status -n "$KUBE_NAMESPACE" -w "$ROLLOUT_RESOURCE_TYPE/$name"
- fi
- }
-
- function scale() {
- track="${1-stable}"
- percentage="${2-100}"
- name=$(deploy_name "$track")
-
- replicas=$(get_replicas "$track" "$percentage")
-
- if [[ -n "$(helm ls -q "^$name$")" ]]; then
- helm upgrade --reuse-values \
- --wait \
- --set replicaCount="$replicas" \
- --namespace="$KUBE_NAMESPACE" \
- "$name" \
- chart/
- fi
- }
-
- function install_dependencies() {
- apk add -U openssl curl tar gzip bash ca-certificates git
- curl -sSL -o /etc/apk/keys/sgerrand.rsa.pub https://alpine-pkgs.sgerrand.com/sgerrand.rsa.pub
- curl -sSL -O https://github.com/sgerrand/alpine-pkg-glibc/releases/download/2.28-r0/glibc-2.28-r0.apk
- apk add glibc-2.28-r0.apk
- rm glibc-2.28-r0.apk
-
- curl -sS "https://kubernetes-helm.storage.googleapis.com/helm-v${HELM_VERSION}-linux-amd64.tar.gz" | tar zx
- mv linux-amd64/helm /usr/bin/
- mv linux-amd64/tiller /usr/bin/
- helm version --client
- tiller -version
-
- curl -sSL -o /usr/bin/kubectl "https://storage.googleapis.com/kubernetes-release/release/v${KUBERNETES_VERSION}/bin/linux/amd64/kubectl"
- chmod +x /usr/bin/kubectl
- kubectl version --client
- }
-
- function download_chart() {
- if [[ ! -d chart ]]; then
- auto_chart=${AUTO_DEVOPS_CHART:-gitlab/auto-deploy-app}
- auto_chart_name=$(basename $auto_chart)
- auto_chart_name=${auto_chart_name%.tgz}
- auto_chart_name=${auto_chart_name%.tar.gz}
- else
- auto_chart="chart"
- auto_chart_name="chart"
- fi
-
- helm init --client-only
- helm repo add ${AUTO_DEVOPS_CHART_REPOSITORY_NAME:-gitlab} ${AUTO_DEVOPS_CHART_REPOSITORY:-https://charts.gitlab.io} ${AUTO_DEVOPS_CHART_REPOSITORY_USERNAME:+"--username" "$AUTO_DEVOPS_CHART_REPOSITORY_USERNAME"} ${AUTO_DEVOPS_CHART_REPOSITORY_PASSWORD:+"--password" "$AUTO_DEVOPS_CHART_REPOSITORY_PASSWORD"}
- if [[ ! -d "$auto_chart" ]]; then
- helm fetch ${auto_chart} --untar
- fi
- if [ "$auto_chart_name" != "chart" ]; then
- mv ${auto_chart_name} chart
- fi
-
- helm dependency update chart/
- helm dependency build chart/
- }
-
- function ensure_namespace() {
- kubectl get namespace "$KUBE_NAMESPACE" || kubectl create namespace "$KUBE_NAMESPACE"
- }
-
- function check_kube_domain() {
- if [[ -z "$KUBE_INGRESS_BASE_DOMAIN" ]]; then
- echo "In order to deploy or use Review Apps,"
- echo "KUBE_INGRESS_BASE_DOMAIN variables must be set"
- echo "From 11.8, you can set KUBE_INGRESS_BASE_DOMAIN in cluster settings"
- echo "or by defining a variable at group or project level."
- echo "You can also manually add it in .gitlab-ci.yml"
- false
- else
- true
- fi
- }
-
- function initialize_tiller() {
- echo "Checking Tiller..."
-
- export HELM_HOST="localhost:44134"
- tiller -listen ${HELM_HOST} -alsologtostderr > /dev/null 2>&1 &
- echo "Tiller is listening on ${HELM_HOST}"
-
- if ! helm version --debug; then
- echo "Failed to init Tiller."
- return 1
- fi
- echo ""
- }
-
- function create_secret() {
- echo "Create secret..."
- if [[ "$CI_PROJECT_VISIBILITY" == "public" ]]; then
- return
- fi
-
- kubectl create secret -n "$KUBE_NAMESPACE" \
- docker-registry gitlab-registry \
- --docker-server="$CI_REGISTRY" \
- --docker-username="${CI_DEPLOY_USER:-$CI_REGISTRY_USER}" \
- --docker-password="${CI_DEPLOY_PASSWORD:-$CI_REGISTRY_PASSWORD}" \
- --docker-email="$GITLAB_USER_EMAIL" \
- -o yaml --dry-run | kubectl replace -n "$KUBE_NAMESPACE" --force -f -
- }
-
- function persist_environment_url() {
- echo $CI_ENVIRONMENT_URL > environment_url.txt
- }
-
- function delete() {
- track="${1-stable}"
- name=$(deploy_name "$track")
-
- if [[ -n "$(helm ls -q "^$name$")" ]]; then
- helm delete --purge "$name"
- fi
-
- secret_name=$(application_secret_name "$track")
- kubectl delete secret --ignore-not-found -n "$KUBE_NAMESPACE" "$secret_name"
- }
-
-before_script:
- - *deploy_helpers
diff --git a/lib/gitlab/object_hierarchy.rb b/lib/gitlab/object_hierarchy.rb
index 38b32770e90..c06f106ffe1 100644
--- a/lib/gitlab/object_hierarchy.rb
+++ b/lib/gitlab/object_hierarchy.rb
@@ -32,11 +32,6 @@ module Gitlab
# Returns the maximum depth starting from the base
# A base object with no children has a maximum depth of `1`
def max_descendants_depth
- unless hierarchy_supported?
- # This makes the return value consistent with the case where hierarchy is supported
- return descendants_base.exists? ? 1 : nil
- end
-
base_and_descendants(with_depth: true).maximum(DEPTH_COLUMN)
end
@@ -66,8 +61,6 @@ module Gitlab
# each parent.
# rubocop: disable CodeReuse/ActiveRecord
def base_and_ancestors(upto: nil, hierarchy_order: nil)
- return ancestors_base unless hierarchy_supported?
-
recursive_query = base_and_ancestors_cte(upto, hierarchy_order).apply_to(model.all)
recursive_query = recursive_query.order(depth: hierarchy_order) if hierarchy_order
@@ -81,10 +74,6 @@ module Gitlab
# When `with_depth` is `true`, a `depth` column is included where it starts with `1` for the base objects
# and incremented as we go down the descendant tree
def base_and_descendants(with_depth: false)
- unless hierarchy_supported?
- return with_depth ? descendants_base.select("1 as #{DEPTH_COLUMN}", objects_table[Arel.star]) : descendants_base
- end
-
read_only(base_and_descendants_cte(with_depth: with_depth).apply_to(model.all))
end
@@ -112,8 +101,6 @@ module Gitlab
# If nested objects are not supported, ancestors_base is returned.
# rubocop: disable CodeReuse/ActiveRecord
def all_objects
- return ancestors_base unless hierarchy_supported?
-
ancestors = base_and_ancestors_cte
descendants = base_and_descendants_cte
@@ -135,10 +122,6 @@ module Gitlab
private
- def hierarchy_supported?
- Gitlab::Database.postgresql?
- end
-
# rubocop: disable CodeReuse/ActiveRecord
def base_and_ancestors_cte(stop_id = nil, hierarchy_order = nil)
cte = SQL::RecursiveCTE.new(:base_and_ancestors)
diff --git a/lib/gitlab/project_authorizations.rb b/lib/gitlab/project_authorizations.rb
new file mode 100644
index 00000000000..a9270cd536e
--- /dev/null
+++ b/lib/gitlab/project_authorizations.rb
@@ -0,0 +1,121 @@
+# frozen_string_literal: true
+
+# This class relies on Common Table Expressions to efficiently get all data,
+# including data for nested groups.
+module Gitlab
+ class ProjectAuthorizations
+ attr_reader :user
+
+ # user - The User object for which to calculate the authorizations.
+ def initialize(user)
+ @user = user
+ end
+
+ def calculate
+ cte = recursive_cte
+ cte_alias = cte.table.alias(Group.table_name)
+ projects = Project.arel_table
+ links = ProjectGroupLink.arel_table
+
+ relations = [
+ # The project a user has direct access to.
+ user.projects.select_for_project_authorization,
+
+ # The personal projects of the user.
+ user.personal_projects.select_as_maintainer_for_project_authorization,
+
+ # Projects that belong directly to any of the groups the user has
+ # access to.
+ Namespace
+ .unscoped
+ .select([alias_as_column(projects[:id], 'project_id'),
+ cte_alias[:access_level]])
+ .from(cte_alias)
+ .joins(:projects),
+
+ # Projects shared with any of the namespaces the user has access to.
+ Namespace
+ .unscoped
+ .select([
+ links[:project_id],
+ least(cte_alias[:access_level], links[:group_access], 'access_level')
+ ])
+ .from(cte_alias)
+ .joins('INNER JOIN project_group_links ON project_group_links.group_id = namespaces.id')
+ .joins('INNER JOIN projects ON projects.id = project_group_links.project_id')
+ .joins('INNER JOIN namespaces p_ns ON p_ns.id = projects.namespace_id')
+ .where('p_ns.share_with_group_lock IS FALSE')
+ ]
+
+ ProjectAuthorization
+ .unscoped
+ .with
+ .recursive(cte.to_arel)
+ .select_from_union(relations)
+ end
+
+ private
+
+ # Builds a recursive CTE that gets all the groups the current user has
+ # access to, including any nested groups.
+ def recursive_cte
+ cte = Gitlab::SQL::RecursiveCTE.new(:namespaces_cte)
+ members = Member.arel_table
+ namespaces = Namespace.arel_table
+
+ # Namespaces the user is a member of.
+ cte << user.groups
+ .select([namespaces[:id], members[:access_level]])
+ .except(:order)
+
+ # Sub groups of any groups the user is a member of.
+ cte << Group.select([
+ namespaces[:id],
+ greatest(members[:access_level], cte.table[:access_level], 'access_level')
+ ])
+ .joins(join_cte(cte))
+ .joins(join_members)
+ .except(:order)
+
+ cte
+ end
+
+ # Builds a LEFT JOIN to join optional memberships onto the CTE.
+ def join_members
+ members = Member.arel_table
+ namespaces = Namespace.arel_table
+
+ cond = members[:source_id]
+ .eq(namespaces[:id])
+ .and(members[:source_type].eq('Namespace'))
+ .and(members[:requested_at].eq(nil))
+ .and(members[:user_id].eq(user.id))
+
+ Arel::Nodes::OuterJoin.new(members, Arel::Nodes::On.new(cond))
+ end
+
+ # Builds an INNER JOIN to join namespaces onto the CTE.
+ def join_cte(cte)
+ namespaces = Namespace.arel_table
+ cond = cte.table[:id].eq(namespaces[:parent_id])
+
+ Arel::Nodes::InnerJoin.new(cte.table, Arel::Nodes::On.new(cond))
+ end
+
+ def greatest(left, right, column_alias)
+ sql_function('GREATEST', [left, right], column_alias)
+ end
+
+ def least(left, right, column_alias)
+ sql_function('LEAST', [left, right], column_alias)
+ end
+
+ def sql_function(name, args, column_alias)
+ alias_as_column(Arel::Nodes::NamedFunction.new(name, args), column_alias)
+ end
+
+ def alias_as_column(value, alias_to)
+ Arel::Nodes::As.new(value, Arel::Nodes::SqlLiteral.new(alias_to))
+ end
+ end
+end
diff --git a/lib/gitlab/project_authorizations/with_nested_groups.rb b/lib/gitlab/project_authorizations/with_nested_groups.rb
deleted file mode 100644
index 2372a316ab0..00000000000
--- a/lib/gitlab/project_authorizations/with_nested_groups.rb
+++ /dev/null
@@ -1,125 +0,0 @@
-# frozen_string_literal: true
-
-module Gitlab
- module ProjectAuthorizations
- # Calculating new project authorizations when supporting nested groups.
- #
- # This class relies on Common Table Expressions to efficiently get all data,
- # including data for nested groups. As a result this class can only be used
- # on PostgreSQL.
- class WithNestedGroups
- attr_reader :user
-
- # user - The User object for which to calculate the authorizations.
- def initialize(user)
- @user = user
- end
-
- def calculate
- cte = recursive_cte
- cte_alias = cte.table.alias(Group.table_name)
- projects = Project.arel_table
- links = ProjectGroupLink.arel_table
-
- relations = [
- # The project a user has direct access to.
- user.projects.select_for_project_authorization,
-
- # The personal projects of the user.
- user.personal_projects.select_as_maintainer_for_project_authorization,
-
- # Projects that belong directly to any of the groups the user has
- # access to.
- Namespace
- .unscoped
- .select([alias_as_column(projects[:id], 'project_id'),
- cte_alias[:access_level]])
- .from(cte_alias)
- .joins(:projects),
-
- # Projects shared with any of the namespaces the user has access to.
- Namespace
- .unscoped
- .select([links[:project_id],
- least(cte_alias[:access_level],
- links[:group_access],
- 'access_level')])
- .from(cte_alias)
- .joins('INNER JOIN project_group_links ON project_group_links.group_id = namespaces.id')
- .joins('INNER JOIN projects ON projects.id = project_group_links.project_id')
- .joins('INNER JOIN namespaces p_ns ON p_ns.id = projects.namespace_id')
- .where('p_ns.share_with_group_lock IS FALSE')
- ]
-
- ProjectAuthorization
- .unscoped
- .with
- .recursive(cte.to_arel)
- .select_from_union(relations)
- end
-
- private
-
- # Builds a recursive CTE that gets all the groups the current user has
- # access to, including any nested groups.
- def recursive_cte
- cte = Gitlab::SQL::RecursiveCTE.new(:namespaces_cte)
- members = Member.arel_table
- namespaces = Namespace.arel_table
-
- # Namespaces the user is a member of.
- cte << user.groups
- .select([namespaces[:id], members[:access_level]])
- .except(:order)
-
- # Sub groups of any groups the user is a member of.
- cte << Group.select([namespaces[:id],
- greatest(members[:access_level],
- cte.table[:access_level], 'access_level')])
- .joins(join_cte(cte))
- .joins(join_members)
- .except(:order)
-
- cte
- end
-
- # Builds a LEFT JOIN to join optional memberships onto the CTE.
- def join_members
- members = Member.arel_table
- namespaces = Namespace.arel_table
-
- cond = members[:source_id]
- .eq(namespaces[:id])
- .and(members[:source_type].eq('Namespace'))
- .and(members[:requested_at].eq(nil))
- .and(members[:user_id].eq(user.id))
-
- Arel::Nodes::OuterJoin.new(members, Arel::Nodes::On.new(cond))
- end
-
- # Builds an INNER JOIN to join namespaces onto the CTE.
- def join_cte(cte)
- namespaces = Namespace.arel_table
- cond = cte.table[:id].eq(namespaces[:parent_id])
-
- Arel::Nodes::InnerJoin.new(cte.table, Arel::Nodes::On.new(cond))
- end
-
- def greatest(left, right, column_alias)
- sql_function('GREATEST', [left, right], column_alias)
- end
-
- def least(left, right, column_alias)
- sql_function('LEAST', [left, right], column_alias)
- end
-
- def sql_function(name, args, column_alias)
- alias_as_column(Arel::Nodes::NamedFunction.new(name, args), column_alias)
- end
-
- def alias_as_column(value, alias_to)
- Arel::Nodes::As.new(value, Arel::Nodes::SqlLiteral.new(alias_to))
- end
- end
- end
-end
diff --git a/lib/gitlab/project_authorizations/without_nested_groups.rb b/lib/gitlab/project_authorizations/without_nested_groups.rb
deleted file mode 100644
index 50b41b17649..00000000000
--- a/lib/gitlab/project_authorizations/without_nested_groups.rb
+++ /dev/null
@@ -1,35 +0,0 @@
-# frozen_string_literal: true
-
-module Gitlab
- module ProjectAuthorizations
- # Calculating new project authorizations when not supporting nested groups.
- class WithoutNestedGroups
- attr_reader :user
-
- # user - The User object for which to calculate the authorizations.
- def initialize(user)
- @user = user
- end
-
- def calculate
- relations = [
- # Projects the user is a direct member of
- user.projects.select_for_project_authorization,
-
- # Personal projects
- user.personal_projects.select_as_maintainer_for_project_authorization,
-
- # Projects of groups the user is a member of
- user.groups_projects.select_for_project_authorization,
-
- # Projects shared with groups the user is a member of
- user.groups.joins(:shared_projects).select_for_project_authorization
- ]
-
- ProjectAuthorization
- .unscoped
- .select_from_union(relations)
- end
- end
- end
-end
diff --git a/lib/gitlab/submodule_links.rb b/lib/gitlab/submodule_links.rb
index a6c0369d864..18fd604a3b0 100644
--- a/lib/gitlab/submodule_links.rb
+++ b/lib/gitlab/submodule_links.rb
@@ -9,7 +9,7 @@ module Gitlab
end
def for(submodule, sha)
- submodule_url = submodule_url_for(sha)[submodule.path]
+ submodule_url = submodule_url_for(sha, submodule.path)
SubmoduleHelper.submodule_links_for_url(submodule.id, submodule_url, repository)
end
@@ -17,10 +17,15 @@ module Gitlab
attr_reader :repository
- def submodule_url_for(sha)
- strong_memoize(:"submodule_links_for_#{sha}") do
+ def submodule_urls_for(sha)
+ strong_memoize(:"submodule_urls_for_#{sha}") do
repository.submodule_urls_for(sha)
end
end
+
+ def submodule_url_for(sha, path)
+ urls = submodule_urls_for(sha)
+ urls && urls[path]
+ end
end
end
diff --git a/lib/prometheus/pid_provider.rb b/lib/prometheus/pid_provider.rb
index c92522c73c5..e0f7e7e0a9e 100644
--- a/lib/prometheus/pid_provider.rb
+++ b/lib/prometheus/pid_provider.rb
@@ -1,7 +1,5 @@
# frozen_string_literal: true
-require 'prometheus/client/support/unicorn'
-
module Prometheus
module PidProvider
extend self
@@ -10,29 +8,38 @@ module Prometheus
if Sidekiq.server?
'sidekiq'
elsif defined?(Unicorn::Worker)
- "unicorn_#{unicorn_worker_id}"
+ unicorn_worker_id
elsif defined?(::Puma)
- "puma_#{puma_worker_id}"
+ puma_worker_id
else
- "process_#{Process.pid}"
+ unknown_process_id
end
end
private
- # This is not fully accurate as we don't really know if the nil returned
- # is actually means we're on master or not.
- # Follow up issue was created to address this problem and
- # to introduce more structrured approach to a current process discovery:
- # https://gitlab.com/gitlab-org/gitlab-ce/issues/64740
def unicorn_worker_id
- ::Prometheus::Client::Support::Unicorn.worker_id || 'master'
+ if matches = process_name.match(/unicorn.*worker\[([0-9]+)\]/)
+ "unicorn_#{matches[1]}"
+ elsif process_name =~ /unicorn/
+ "unicorn_master"
+ else
+ unknown_process_id
+ end
end
- # See the comment for #unicorn_worker_id
def puma_worker_id
- match = process_name.match(/cluster worker ([0-9]+):/)
- match ? match[1] : 'master'
+ if matches = process_name.match(/puma.*cluster worker ([0-9]+):/)
+ "puma_#{matches[1]}"
+ elsif process_name =~ /puma/
+ "puma_master"
+ else
+ unknown_process_id
+ end
+ end
+
+ def unknown_process_id
+ "process_#{Process.pid}"
end
def process_name
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index ed71a4b42d9..58c75ee2319 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -2020,6 +2020,57 @@ msgstr ""
msgid "Chat"
msgstr ""
+msgid "ChatMessage|%{project_link}: Pipeline %{pipeline_link} of %{ref_type} %{branch_link} by %{user_combined_name} %{humanized_status} in %{duration}"
+msgstr ""
+
+msgid "ChatMessage|Branch"
+msgstr ""
+
+msgid "ChatMessage|Commit"
+msgstr ""
+
+msgid "ChatMessage|Failed job"
+msgstr ""
+
+msgid "ChatMessage|Failed stage"
+msgstr ""
+
+msgid "ChatMessage|Invalid CI config YAML file"
+msgstr ""
+
+msgid "ChatMessage|Pipeline #%{pipeline_id} %{humanized_status} in %{duration}"
+msgstr ""
+
+msgid "ChatMessage|Pipeline %{pipeline_link} of %{ref_type} %{branch_link} by %{user_combined_name} %{humanized_status}"
+msgstr ""
+
+msgid "ChatMessage|Tag"
+msgstr ""
+
+msgid "ChatMessage|and [%{count} more](%{pipeline_failed_jobs_url})"
+msgstr ""
+
+msgid "ChatMessage|failed"
+msgstr ""
+
+msgid "ChatMessage|has failed"
+msgstr ""
+
+msgid "ChatMessage|has passed"
+msgstr ""
+
+msgid "ChatMessage|has passed with warnings"
+msgstr ""
+
+msgid "ChatMessage|in %{duration}"
+msgstr ""
+
+msgid "ChatMessage|in %{project_link}"
+msgstr ""
+
+msgid "ChatMessage|passed"
+msgstr ""
+
msgid "Check again"
msgstr ""
@@ -3941,6 +3992,12 @@ msgstr ""
msgid "Edit public deploy key"
msgstr ""
+msgid "Editor|%{mdLinkStart}Markdown is supported%{mdLinkEnd}"
+msgstr ""
+
+msgid "Editor|%{mdLinkStart}Markdown%{mdLinkEnd} and %{actionsLinkStart}quick actions%{actionsLinkEnd} are supported"
+msgstr ""
+
msgid "Email"
msgstr ""
@@ -6382,18 +6439,12 @@ msgstr ""
msgid "Mark to do as done"
msgstr ""
-msgid "Markdown"
-msgstr ""
-
msgid "Markdown Help"
msgstr ""
msgid "Markdown enabled"
msgstr ""
-msgid "Markdown is supported"
-msgstr ""
-
msgid "Marks this issue as a duplicate of %{duplicate_reference}."
msgstr ""
@@ -13314,9 +13365,6 @@ msgstr ""
msgid "project avatar"
msgstr ""
-msgid "quick actions"
-msgstr ""
-
msgid "register"
msgstr ""
diff --git a/package.json b/package.json
index 4264064c93d..773918524f9 100644
--- a/package.json
+++ b/package.json
@@ -38,7 +38,7 @@
"@babel/preset-env": "^7.4.4",
"@gitlab/csslab": "^1.9.0",
"@gitlab/svgs": "^1.67.0",
- "@gitlab/ui": "^5.7.1",
+ "@gitlab/ui": "^5.9.0",
"apollo-cache-inmemory": "^1.5.1",
"apollo-client": "^2.5.1",
"apollo-link": "^1.2.11",
@@ -99,7 +99,7 @@
"mermaid": "^8.2.3",
"monaco-editor": "^0.15.6",
"monaco-editor-webpack-plugin": "^1.7.0",
- "mousetrap": "^1.4.6",
+ "mousetrap": "1.4.6",
"pdfjs-dist": "^2.0.943",
"pikaday": "^1.6.1",
"popper.js": "^1.14.7",
diff --git a/qa/qa/page/project/issue/show.rb b/qa/qa/page/project/issue/show.rb
index b59540d0377..507dccb52d0 100644
--- a/qa/qa/page/project/issue/show.rb
+++ b/qa/qa/page/project/issue/show.rb
@@ -70,7 +70,10 @@ module QA
end
def select_labels_and_refresh(labels)
- click_element(:edit_link_labels)
+ Support::Retrier.retry_until do
+ click_element(:edit_link_labels)
+ has_element?(:dropdown_menu_labels, text: labels.first)
+ end
labels.each do |label|
within_element(:dropdown_menu_labels, text: label) do
diff --git a/qa/qa/page/project/settings/ci_cd.rb b/qa/qa/page/project/settings/ci_cd.rb
index b8c5c563da6..ae826fb3a32 100644
--- a/qa/qa/page/project/settings/ci_cd.rb
+++ b/qa/qa/page/project/settings/ci_cd.rb
@@ -8,33 +8,32 @@ module QA
include Common
view 'app/views/projects/settings/ci_cd/show.html.haml' do
- element :autodevops_settings
- element :runners_settings
- element :variables_settings
+ element :autodevops_settings_content
+ element :runners_settings_content
+ element :variables_settings_content
end
view 'app/views/projects/settings/ci_cd/_autodevops_form.html.haml' do
- element :enable_auto_devops_field, 'check_box :enabled' # rubocop:disable QA/ElementWithPattern
- element :enable_auto_devops_button, "%strong= s_('CICD|Default to Auto DevOps pipeline')" # rubocop:disable QA/ElementWithPattern
- element :save_changes_button, "submit _('Save changes')" # rubocop:disable QA/ElementWithPattern
+ element :enable_autodevops_checkbox
+ element :save_changes_button
end
def expand_runners_settings(&block)
- expand_section(:runners_settings) do
+ expand_section(:runners_settings_content) do
Settings::Runners.perform(&block)
end
end
def expand_ci_variables(&block)
- expand_section(:variables_settings) do
+ expand_section(:variables_settings_content) do
Settings::CiVariables.perform(&block)
end
end
def enable_auto_devops
- expand_section(:autodevops_settings) do
- check 'Default to Auto DevOps pipeline'
- click_on 'Save changes'
+ expand_section(:autodevops_settings_content) do
+ check_element :enable_autodevops_checkbox
+ click_element :save_changes_button
end
end
end
diff --git a/qa/qa/page/project/sub_menus/project.rb b/qa/qa/page/project/sub_menus/project.rb
index 5e0ee3c274a..6f1bc131f84 100644
--- a/qa/qa/page/project/sub_menus/project.rb
+++ b/qa/qa/page/project/sub_menus/project.rb
@@ -10,7 +10,7 @@ module QA
def self.included(base)
base.class_eval do
view 'app/views/layouts/nav/sidebar/_project.html.haml' do
- element :link_project
+ element :project_link
end
end
end
@@ -18,7 +18,7 @@ module QA
def click_project
retry_on_exception do
within_sidebar do
- click_element(:link_project)
+ click_element(:project_link)
end
end
end
diff --git a/spec/controllers/boards/issues_controller_spec.rb b/spec/controllers/boards/issues_controller_spec.rb
index 0db58fbefc1..d54f7ad33cf 100644
--- a/spec/controllers/boards/issues_controller_spec.rb
+++ b/spec/controllers/boards/issues_controller_spec.rb
@@ -85,7 +85,7 @@ describe Boards::IssuesController do
expect { list_issues(user: user, board: group_board, list: list3) }.not_to exceed_query_limit(control_count + (2 * 8 - 1))
end
- it 'avoids N+1 database queries when adding a subgroup, project, and issue', :nested_groups do
+ it 'avoids N+1 database queries when adding a subgroup, project, and issue' do
create(:project, group: sub_group_1)
create(:labeled_issue, project: project, labels: [development])
control_count = ActiveRecord::QueryRecorder.new { list_issues(user: user, board: group_board, list: list3) }.count
diff --git a/spec/controllers/concerns/group_tree_spec.rb b/spec/controllers/concerns/group_tree_spec.rb
index aa3cd690e3f..835c3d9b3af 100644
--- a/spec/controllers/concerns/group_tree_spec.rb
+++ b/spec/controllers/concerns/group_tree_spec.rb
@@ -30,7 +30,7 @@ describe GroupTree do
expect(assigns(:groups)).to contain_exactly(other_group)
end
- context 'for subgroups', :nested_groups do
+ context 'for subgroups' do
it 'only renders root groups when no parent was given' do
create(:group, :public, parent: group)
@@ -85,7 +85,7 @@ describe GroupTree do
expect(json_response.first['id']).to eq(group.id)
end
- context 'nested groups', :nested_groups do
+ context 'nested groups' do
it 'expands the tree when filtering' do
subgroup = create(:group, :public, parent: group, name: 'filter')
diff --git a/spec/controllers/dashboard/groups_controller_spec.rb b/spec/controllers/dashboard/groups_controller_spec.rb
index 48373d29412..20a0951423b 100644
--- a/spec/controllers/dashboard/groups_controller_spec.rb
+++ b/spec/controllers/dashboard/groups_controller_spec.rb
@@ -26,7 +26,7 @@ describe Dashboard::GroupsController do
expect(assigns(:groups)).to contain_exactly(member_of_group)
end
- context 'when rendering an expanded hierarchy with public groups you are not a member of', :nested_groups do
+ context 'when rendering an expanded hierarchy with public groups you are not a member of' do
let!(:top_level_result) { create(:group, name: 'chef-top') }
let!(:top_level_a) { create(:group, name: 'top-a') }
let!(:sub_level_result_a) { create(:group, name: 'chef-sub-a', parent: top_level_a) }
diff --git a/spec/controllers/groups/children_controller_spec.rb b/spec/controllers/groups/children_controller_spec.rb
index 02fb971bd9a..bced300a24c 100644
--- a/spec/controllers/groups/children_controller_spec.rb
+++ b/spec/controllers/groups/children_controller_spec.rb
@@ -46,7 +46,7 @@ describe Groups::ChildrenController do
end
end
- context 'for subgroups', :nested_groups do
+ context 'for subgroups' do
let!(:public_subgroup) { create(:group, :public, parent: group) }
let!(:private_subgroup) { create(:group, :private, parent: group) }
let!(:public_project) { create(:project, :public, namespace: group) }
@@ -292,7 +292,7 @@ describe Groups::ChildrenController do
end
end
- context 'with subgroups and projects', :nested_groups do
+ context 'with subgroups and projects' do
let!(:first_page_subgroups) { create_list(:group, per_page, :public, parent: group) }
let!(:other_subgroup) { create(:group, :public, parent: group) }
let!(:next_page_projects) { create_list(:project, per_page, :public, namespace: group) }
diff --git a/spec/controllers/groups/labels_controller_spec.rb b/spec/controllers/groups/labels_controller_spec.rb
index 3cc6fc6f066..98a4c50fc49 100644
--- a/spec/controllers/groups/labels_controller_spec.rb
+++ b/spec/controllers/groups/labels_controller_spec.rb
@@ -24,7 +24,7 @@ describe Groups::LabelsController do
expect(label_ids).to match_array([label_1.title, group_label_1.title])
end
- context 'with ancestor group', :nested_groups do
+ context 'with ancestor group' do
set(:subgroup) { create(:group, parent: group) }
set(:subgroup_label_1) { create(:group_label, group: subgroup, title: 'subgroup_label_1') }
@@ -32,7 +32,7 @@ describe Groups::LabelsController do
subgroup.add_owner(user)
end
- it 'returns ancestor group labels', :nested_groups do
+ it 'returns ancestor group labels' do
get :index, params: { group_id: subgroup, include_ancestor_groups: true, only_group_labels: true }, format: :json
label_ids = json_response.map {|label| label['title']}
diff --git a/spec/controllers/groups_controller_spec.rb b/spec/controllers/groups_controller_spec.rb
index d2faef5b12b..404e61c5271 100644
--- a/spec/controllers/groups_controller_spec.rb
+++ b/spec/controllers/groups_controller_spec.rb
@@ -89,7 +89,7 @@ describe GroupsController do
end
describe 'GET #new' do
- context 'when creating subgroups', :nested_groups do
+ context 'when creating subgroups' do
[true, false].each do |can_create_group_status|
context "and can_create_group is #{can_create_group_status}" do
before do
@@ -166,7 +166,7 @@ describe GroupsController do
end
end
- context 'when creating subgroups', :nested_groups do
+ context 'when creating subgroups' do
[true, false].each do |can_create_group_status|
context "and can_create_group is #{can_create_group_status}" do
context 'and logged in as Owner' do
@@ -584,7 +584,7 @@ describe GroupsController do
end
end
- describe 'PUT transfer', :postgresql do
+ describe 'PUT transfer' do
before do
sign_in(user)
end
diff --git a/spec/controllers/import/bitbucket_controller_spec.rb b/spec/controllers/import/bitbucket_controller_spec.rb
index 64a66502732..38388c21749 100644
--- a/spec/controllers/import/bitbucket_controller_spec.rb
+++ b/spec/controllers/import/bitbucket_controller_spec.rb
@@ -231,7 +231,7 @@ describe Import::BitbucketController do
end
end
- context 'user has chosen an existing nested namespace and name for the project', :postgresql do
+ context 'user has chosen an existing nested namespace and name for the project' do
let(:parent_namespace) { create(:group, name: 'foo') }
let(:nested_namespace) { create(:group, name: 'bar', parent: parent_namespace) }
let(:test_name) { 'test_name' }
@@ -250,7 +250,7 @@ describe Import::BitbucketController do
end
end
- context 'user has chosen a non-existent nested namespaces and name for the project', :postgresql do
+ context 'user has chosen a non-existent nested namespaces and name for the project' do
let(:test_name) { 'test_name' }
it 'takes the selected namespace and name' do
@@ -281,7 +281,7 @@ describe Import::BitbucketController do
end
end
- context 'user has chosen existent and non-existent nested namespaces and name for the project', :postgresql do
+ context 'user has chosen existent and non-existent nested namespaces and name for the project' do
let(:test_name) { 'test_name' }
let!(:parent_namespace) { create(:group, name: 'foo') }
diff --git a/spec/controllers/import/gitlab_controller_spec.rb b/spec/controllers/import/gitlab_controller_spec.rb
index 5af7572e74e..e465eca6c71 100644
--- a/spec/controllers/import/gitlab_controller_spec.rb
+++ b/spec/controllers/import/gitlab_controller_spec.rb
@@ -197,7 +197,7 @@ describe Import::GitlabController do
end
end
- context 'user has chosen an existing nested namespace for the project', :postgresql do
+ context 'user has chosen an existing nested namespace for the project' do
let(:parent_namespace) { create(:group, name: 'foo') }
let(:nested_namespace) { create(:group, name: 'bar', parent: parent_namespace) }
@@ -215,7 +215,7 @@ describe Import::GitlabController do
end
end
- context 'user has chosen a non-existent nested namespaces for the project', :postgresql do
+ context 'user has chosen a non-existent nested namespaces for the project' do
let(:test_name) { 'test_name' }
it 'takes the selected namespace and name' do
@@ -246,7 +246,7 @@ describe Import::GitlabController do
end
end
- context 'user has chosen existent and non-existent nested namespaces and name for the project', :postgresql do
+ context 'user has chosen existent and non-existent nested namespaces and name for the project' do
let(:test_name) { 'test_name' }
let!(:parent_namespace) { create(:group, name: 'foo') }
diff --git a/spec/controllers/projects/merge_requests_controller_spec.rb b/spec/controllers/projects/merge_requests_controller_spec.rb
index f11880122b1..fa71d9b61b1 100644
--- a/spec/controllers/projects/merge_requests_controller_spec.rb
+++ b/spec/controllers/projects/merge_requests_controller_spec.rb
@@ -885,10 +885,9 @@ describe Projects::MergeRequestsController do
environment2 = create(:environment, project: forked)
create(:deployment, :succeed, environment: environment2, sha: sha, ref: 'master', deployable: build)
- # TODO address the last 11 queries
+ # TODO address the last 5 queries
# See https://gitlab.com/gitlab-org/gitlab-ce/issues/63952 (5 queries)
- # And https://gitlab.com/gitlab-org/gitlab-ce/issues/64105 (6 queries)
- leeway = 11
+ leeway = 5
expect { get_ci_environments_status }.not_to exceed_all_query_limit(control_count + leeway)
end
end
diff --git a/spec/controllers/projects/milestones_controller_spec.rb b/spec/controllers/projects/milestones_controller_spec.rb
index 767cee7d54a..9b2025b836c 100644
--- a/spec/controllers/projects/milestones_controller_spec.rb
+++ b/spec/controllers/projects/milestones_controller_spec.rb
@@ -115,7 +115,7 @@ describe Projects::MilestonesController do
end
end
- context 'with nested groups', :nested_groups do
+ context 'with nested groups' do
let!(:subgroup) { create(:group, :public, parent: group) }
let!(:subgroup_milestone) { create(:milestone, group: subgroup) }
diff --git a/spec/factories/abuse_reports.rb b/spec/factories/abuse_reports.rb
index 021971ac421..578af9ed895 100644
--- a/spec/factories/abuse_reports.rb
+++ b/spec/factories/abuse_reports.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :abuse_report do
reporter factory: :user
diff --git a/spec/factories/appearances.rb b/spec/factories/appearances.rb
index dd5129229d4..bdd5964fb93 100644
--- a/spec/factories/appearances.rb
+++ b/spec/factories/appearances.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
# Read about factories at https://github.com/thoughtbot/factory_bot
FactoryBot.define do
diff --git a/spec/factories/application_settings.rb b/spec/factories/application_settings.rb
index 00c063c49f8..90b6b9e648a 100644
--- a/spec/factories/application_settings.rb
+++ b/spec/factories/application_settings.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :application_setting do
default_projects_limit 42
diff --git a/spec/factories/award_emoji.rb b/spec/factories/award_emoji.rb
index 43753fa650c..a8bb806381e 100644
--- a/spec/factories/award_emoji.rb
+++ b/spec/factories/award_emoji.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :award_emoji do
name "thumbsup"
diff --git a/spec/factories/badge.rb b/spec/factories/badge.rb
index b87ece946cb..1d4e29014cc 100644
--- a/spec/factories/badge.rb
+++ b/spec/factories/badge.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
trait :base_badge do
link_url { generate(:url) }
diff --git a/spec/factories/boards.rb b/spec/factories/boards.rb
index 6524bb4830c..a5aff5c7504 100644
--- a/spec/factories/boards.rb
+++ b/spec/factories/boards.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :board do
transient do
diff --git a/spec/factories/broadcast_messages.rb b/spec/factories/broadcast_messages.rb
index 1a2be5e9552..2a30e2034b1 100644
--- a/spec/factories/broadcast_messages.rb
+++ b/spec/factories/broadcast_messages.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :broadcast_message do
message "MyText"
diff --git a/spec/factories/chat_names.rb b/spec/factories/chat_names.rb
index 56993e5da18..07bf990162f 100644
--- a/spec/factories/chat_names.rb
+++ b/spec/factories/chat_names.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :chat_name, class: ChatName do
user factory: :user
diff --git a/spec/factories/chat_teams.rb b/spec/factories/chat_teams.rb
index d048c46d6b6..52628e6d53d 100644
--- a/spec/factories/chat_teams.rb
+++ b/spec/factories/chat_teams.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :chat_team, class: ChatTeam do
sequence(:team_id) { |n| "abcdefghijklm#{n}" }
diff --git a/spec/factories/ci/bridge.rb b/spec/factories/ci/bridge.rb
index 7cb5900f2b7..6491b9dca19 100644
--- a/spec/factories/ci/bridge.rb
+++ b/spec/factories/ci/bridge.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :ci_bridge, class: Ci::Bridge do
name 'bridge'
diff --git a/spec/factories/ci/build_trace_chunks.rb b/spec/factories/ci/build_trace_chunks.rb
index 3e8e2736423..492dc47f083 100644
--- a/spec/factories/ci/build_trace_chunks.rb
+++ b/spec/factories/ci/build_trace_chunks.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :ci_build_trace_chunk, class: Ci::BuildTraceChunk do
build factory: :ci_build
diff --git a/spec/factories/ci/build_trace_section_names.rb b/spec/factories/ci/build_trace_section_names.rb
index ce07e716dde..e52694ef3dc 100644
--- a/spec/factories/ci/build_trace_section_names.rb
+++ b/spec/factories/ci/build_trace_section_names.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :ci_build_trace_section_name, class: Ci::BuildTraceSectionName do
sequence(:name) { |n| "section_#{n}" }
diff --git a/spec/factories/ci/builds.rb b/spec/factories/ci/builds.rb
index 5f7c75a3a92..e3b7c64176a 100644
--- a/spec/factories/ci/builds.rb
+++ b/spec/factories/ci/builds.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
include ActionDispatch::TestProcess
FactoryBot.define do
diff --git a/spec/factories/ci/group_variables.rb b/spec/factories/ci/group_variables.rb
index 9bf520a2c0a..13c2b78e61b 100644
--- a/spec/factories/ci/group_variables.rb
+++ b/spec/factories/ci/group_variables.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :ci_group_variable, class: Ci::GroupVariable do
sequence(:key) { |n| "VARIABLE_#{n}" }
diff --git a/spec/factories/ci/job_artifacts.rb b/spec/factories/ci/job_artifacts.rb
index 542fa9775cd..2d68a8e9fe3 100644
--- a/spec/factories/ci/job_artifacts.rb
+++ b/spec/factories/ci/job_artifacts.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
include ActionDispatch::TestProcess
FactoryBot.define do
diff --git a/spec/factories/ci/pipeline_schedule.rb b/spec/factories/ci/pipeline_schedule.rb
index 4b83ba2ac1b..8fae6986869 100644
--- a/spec/factories/ci/pipeline_schedule.rb
+++ b/spec/factories/ci/pipeline_schedule.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :ci_pipeline_schedule, class: Ci::PipelineSchedule do
cron '0 1 * * *'
diff --git a/spec/factories/ci/pipeline_schedule_variables.rb b/spec/factories/ci/pipeline_schedule_variables.rb
index c85b97fbfc7..fd7cfada65b 100644
--- a/spec/factories/ci/pipeline_schedule_variables.rb
+++ b/spec/factories/ci/pipeline_schedule_variables.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :ci_pipeline_schedule_variable, class: Ci::PipelineScheduleVariable do
sequence(:key) { |n| "VARIABLE_#{n}" }
diff --git a/spec/factories/ci/pipeline_variables.rb b/spec/factories/ci/pipeline_variables.rb
index b18055d7b3a..af0982124d7 100644
--- a/spec/factories/ci/pipeline_variables.rb
+++ b/spec/factories/ci/pipeline_variables.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :ci_pipeline_variable, class: Ci::PipelineVariable do
sequence(:key) { |n| "VARIABLE_#{n}" }
diff --git a/spec/factories/ci/pipelines.rb b/spec/factories/ci/pipelines.rb
index aa5ccbda6cd..9652b0000a9 100644
--- a/spec/factories/ci/pipelines.rb
+++ b/spec/factories/ci/pipelines.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :ci_empty_pipeline, class: Ci::Pipeline do
source :push
diff --git a/spec/factories/ci/runner_projects.rb b/spec/factories/ci/runner_projects.rb
index ec15972c423..bc28544a839 100644
--- a/spec/factories/ci/runner_projects.rb
+++ b/spec/factories/ci/runner_projects.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :ci_runner_project, class: Ci::RunnerProject do
runner factory: [:ci_runner, :project]
diff --git a/spec/factories/ci/runners.rb b/spec/factories/ci/runners.rb
index 24e70913b87..1e4344b814d 100644
--- a/spec/factories/ci/runners.rb
+++ b/spec/factories/ci/runners.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :ci_runner, class: Ci::Runner do
sequence(:description) { |n| "My runner#{n}" }
diff --git a/spec/factories/ci/stages.rb b/spec/factories/ci/stages.rb
index ce61e6bf759..88ff8d7dc53 100644
--- a/spec/factories/ci/stages.rb
+++ b/spec/factories/ci/stages.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :ci_stage, class: Ci::LegacyStage do
skip_create
diff --git a/spec/factories/ci/trigger_requests.rb b/spec/factories/ci/trigger_requests.rb
index 0e9fc3d0014..d63bf9868c9 100644
--- a/spec/factories/ci/trigger_requests.rb
+++ b/spec/factories/ci/trigger_requests.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :ci_trigger_request, class: Ci::TriggerRequest do
trigger factory: :ci_trigger
diff --git a/spec/factories/ci/triggers.rb b/spec/factories/ci/triggers.rb
index 742d9efba2d..6f628ed5435 100644
--- a/spec/factories/ci/triggers.rb
+++ b/spec/factories/ci/triggers.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :ci_trigger_without_token, class: Ci::Trigger do
owner
diff --git a/spec/factories/ci/variables.rb b/spec/factories/ci/variables.rb
index 97a7c9ba252..55d11085040 100644
--- a/spec/factories/ci/variables.rb
+++ b/spec/factories/ci/variables.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :ci_variable, class: Ci::Variable do
sequence(:key) { |n| "VARIABLE_#{n}" }
diff --git a/spec/factories/clusters/applications/helm.rb b/spec/factories/clusters/applications/helm.rb
index d78f01828d7..7fe9ea6801a 100644
--- a/spec/factories/clusters/applications/helm.rb
+++ b/spec/factories/clusters/applications/helm.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :clusters_applications_helm, class: Clusters::Applications::Helm do
cluster factory: %i(cluster provided_by_gcp)
diff --git a/spec/factories/clusters/clusters.rb b/spec/factories/clusters/clusters.rb
index 171f5256d2b..b0d14b672f4 100644
--- a/spec/factories/clusters/clusters.rb
+++ b/spec/factories/clusters/clusters.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :cluster, class: Clusters::Cluster do
user
diff --git a/spec/factories/clusters/platforms/kubernetes.rb b/spec/factories/clusters/platforms/kubernetes.rb
index bf30a9c3a61..d5dc288fddb 100644
--- a/spec/factories/clusters/platforms/kubernetes.rb
+++ b/spec/factories/clusters/platforms/kubernetes.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :cluster_platform_kubernetes, class: Clusters::Platforms::Kubernetes do
cluster
diff --git a/spec/factories/clusters/providers/gcp.rb b/spec/factories/clusters/providers/gcp.rb
index 186c7c8027c..22462651b6a 100644
--- a/spec/factories/clusters/providers/gcp.rb
+++ b/spec/factories/clusters/providers/gcp.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :cluster_provider_gcp, class: Clusters::Providers::Gcp do
cluster
diff --git a/spec/factories/commit_statuses.rb b/spec/factories/commit_statuses.rb
index 848a31e96c1..a76da30217e 100644
--- a/spec/factories/commit_statuses.rb
+++ b/spec/factories/commit_statuses.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :commit_status, class: CommitStatus do
name 'default'
diff --git a/spec/factories/commits.rb b/spec/factories/commits.rb
index 2bcc4b6cf52..d1554426a76 100644
--- a/spec/factories/commits.rb
+++ b/spec/factories/commits.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require_relative '../support/helpers/repo_helpers'
FactoryBot.define do
diff --git a/spec/factories/container_repositories.rb b/spec/factories/container_repositories.rb
index 00fad7975c9..a9771200d6e 100644
--- a/spec/factories/container_repositories.rb
+++ b/spec/factories/container_repositories.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :container_repository do
name 'test_image'
diff --git a/spec/factories/conversational_development_index_metrics.rb b/spec/factories/conversational_development_index_metrics.rb
index abf37fb861e..ea5816684c6 100644
--- a/spec/factories/conversational_development_index_metrics.rb
+++ b/spec/factories/conversational_development_index_metrics.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :conversational_development_index_metric, class: ConversationalDevelopmentIndex::Metric do
leader_issues 9.256
diff --git a/spec/factories/deploy_keys_projects.rb b/spec/factories/deploy_keys_projects.rb
index 4350652fb79..7f82902dee7 100644
--- a/spec/factories/deploy_keys_projects.rb
+++ b/spec/factories/deploy_keys_projects.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :deploy_keys_project do
deploy_key
diff --git a/spec/factories/deploy_tokens.rb b/spec/factories/deploy_tokens.rb
index 017e866e69c..a96258f5cbe 100644
--- a/spec/factories/deploy_tokens.rb
+++ b/spec/factories/deploy_tokens.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :deploy_token do
token { SecureRandom.hex(50) }
diff --git a/spec/factories/deployments.rb b/spec/factories/deployments.rb
index 1c7787bc1a6..89ff1c527df 100644
--- a/spec/factories/deployments.rb
+++ b/spec/factories/deployments.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :deployment, class: Deployment do
sha 'b83d6e391c22777fca1ed3012fce84f633d7fed0'
diff --git a/spec/factories/emails.rb b/spec/factories/emails.rb
index feacd5ccf15..284ba631c37 100644
--- a/spec/factories/emails.rb
+++ b/spec/factories/emails.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :email do
user
diff --git a/spec/factories/environments.rb b/spec/factories/environments.rb
index 9d9e3d693b8..b5c8f0ca4f0 100644
--- a/spec/factories/environments.rb
+++ b/spec/factories/environments.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :environment, class: Environment do
sequence(:name) { |n| "environment#{n}" }
diff --git a/spec/factories/events.rb b/spec/factories/events.rb
index bf8411b1894..b15eb1592fc 100644
--- a/spec/factories/events.rb
+++ b/spec/factories/events.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :event do
project
diff --git a/spec/factories/file_uploaders.rb b/spec/factories/file_uploaders.rb
index 8404985bfea..ec8f5c9af2d 100644
--- a/spec/factories/file_uploaders.rb
+++ b/spec/factories/file_uploaders.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :file_uploader do
skip_create
diff --git a/spec/factories/fork_network_members.rb b/spec/factories/fork_network_members.rb
index 850e3f158f1..d34de72ab60 100644
--- a/spec/factories/fork_network_members.rb
+++ b/spec/factories/fork_network_members.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :fork_network_member do
association :project
diff --git a/spec/factories/fork_networks.rb b/spec/factories/fork_networks.rb
index 813b1943eb2..12ea688bbce 100644
--- a/spec/factories/fork_networks.rb
+++ b/spec/factories/fork_networks.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :fork_network do
association :root_project, factory: :project
diff --git a/spec/factories/gitaly/commit.rb b/spec/factories/gitaly/commit.rb
index 5034c3d0e48..954b5338846 100644
--- a/spec/factories/gitaly/commit.rb
+++ b/spec/factories/gitaly/commit.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
sequence(:gitaly_commit_id) { Digest::SHA1.hexdigest(Time.now.to_f.to_s) }
diff --git a/spec/factories/gitaly/commit_author.rb b/spec/factories/gitaly/commit_author.rb
index aaf634ce08b..51dcd8a623b 100644
--- a/spec/factories/gitaly/commit_author.rb
+++ b/spec/factories/gitaly/commit_author.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :gitaly_commit_author, class: Gitaly::CommitAuthor do
skip_create
diff --git a/spec/factories/gitaly/tag.rb b/spec/factories/gitaly/tag.rb
index e99776d524a..a7a84753090 100644
--- a/spec/factories/gitaly/tag.rb
+++ b/spec/factories/gitaly/tag.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :gitaly_tag, class: Gitaly::Tag do
skip_create
diff --git a/spec/factories/gpg_key_subkeys.rb b/spec/factories/gpg_key_subkeys.rb
index 6c7db5379a9..9daf26d930d 100644
--- a/spec/factories/gpg_key_subkeys.rb
+++ b/spec/factories/gpg_key_subkeys.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :gpg_key_subkey do
gpg_key
diff --git a/spec/factories/gpg_keys.rb b/spec/factories/gpg_keys.rb
index 3c0f43cc1b6..9f321643174 100644
--- a/spec/factories/gpg_keys.rb
+++ b/spec/factories/gpg_keys.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require_relative '../support/helpers/gpg_helpers'
FactoryBot.define do
diff --git a/spec/factories/gpg_signature.rb b/spec/factories/gpg_signature.rb
index b89e6ffc4b3..a0fc1740d77 100644
--- a/spec/factories/gpg_signature.rb
+++ b/spec/factories/gpg_signature.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :gpg_signature do
commit_sha { Digest::SHA1.hexdigest(SecureRandom.hex) }
diff --git a/spec/factories/group_custom_attributes.rb b/spec/factories/group_custom_attributes.rb
index d2f45d5d3ce..895bc42c84b 100644
--- a/spec/factories/group_custom_attributes.rb
+++ b/spec/factories/group_custom_attributes.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :group_custom_attribute do
group
diff --git a/spec/factories/group_members.rb b/spec/factories/group_members.rb
index 077c6ddc5ae..3bf9cdef253 100644
--- a/spec/factories/group_members.rb
+++ b/spec/factories/group_members.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :group_member do
access_level { GroupMember::OWNER }
diff --git a/spec/factories/groups.rb b/spec/factories/groups.rb
index b67ab955ffc..334c0f369cd 100644
--- a/spec/factories/groups.rb
+++ b/spec/factories/groups.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :group, class: Group, parent: :namespace do
sequence(:name) { |n| "group#{n}" }
diff --git a/spec/factories/identities.rb b/spec/factories/identities.rb
index 122d0d42938..21cfe7fe623 100644
--- a/spec/factories/identities.rb
+++ b/spec/factories/identities.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :identity do
provider 'ldapmain'
diff --git a/spec/factories/import_export_uploads.rb b/spec/factories/import_export_uploads.rb
index 7750d49b1d0..8521411e0e8 100644
--- a/spec/factories/import_export_uploads.rb
+++ b/spec/factories/import_export_uploads.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :import_export_upload do
project { create(:project) }
diff --git a/spec/factories/import_states.rb b/spec/factories/import_states.rb
index d6de26dccbc..8e778200389 100644
--- a/spec/factories/import_states.rb
+++ b/spec/factories/import_states.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :import_state, class: ProjectImportState do
status :none
diff --git a/spec/factories/instance_configuration.rb b/spec/factories/instance_configuration.rb
index 31866a9c221..daa0be3f404 100644
--- a/spec/factories/instance_configuration.rb
+++ b/spec/factories/instance_configuration.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :instance_configuration do
skip_create
diff --git a/spec/factories/internal_ids.rb b/spec/factories/internal_ids.rb
index fbde07a391a..df5c5beeb42 100644
--- a/spec/factories/internal_ids.rb
+++ b/spec/factories/internal_ids.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :internal_id do
project
diff --git a/spec/factories/issues.rb b/spec/factories/issues.rb
index ab27fee33dc..434225f7022 100644
--- a/spec/factories/issues.rb
+++ b/spec/factories/issues.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :issue do
title { generate(:title) }
diff --git a/spec/factories/keys.rb b/spec/factories/keys.rb
index 3f0c60f32b7..087d2521836 100644
--- a/spec/factories/keys.rb
+++ b/spec/factories/keys.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require_relative '../support/helpers/key_generator_helper'
FactoryBot.define do
diff --git a/spec/factories/label_links.rb b/spec/factories/label_links.rb
index 007847d9cf4..9b7c0a158bd 100644
--- a/spec/factories/label_links.rb
+++ b/spec/factories/label_links.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :label_link do
label
diff --git a/spec/factories/label_priorities.rb b/spec/factories/label_priorities.rb
index c4824faad53..2f9f2ddfa89 100644
--- a/spec/factories/label_priorities.rb
+++ b/spec/factories/label_priorities.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :label_priority do
project
diff --git a/spec/factories/labels.rb b/spec/factories/labels.rb
index f759b6d499d..3eed750be03 100644
--- a/spec/factories/labels.rb
+++ b/spec/factories/labels.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
trait :base_label do
title { generate(:label_title) }
diff --git a/spec/factories/lfs_file_locks.rb b/spec/factories/lfs_file_locks.rb
index b9d24f82b65..73675d076ab 100644
--- a/spec/factories/lfs_file_locks.rb
+++ b/spec/factories/lfs_file_locks.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :lfs_file_lock do
user
diff --git a/spec/factories/lfs_objects.rb b/spec/factories/lfs_objects.rb
index 08ac7fb69e7..631d87cfb12 100644
--- a/spec/factories/lfs_objects.rb
+++ b/spec/factories/lfs_objects.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
include ActionDispatch::TestProcess
FactoryBot.define do
diff --git a/spec/factories/lfs_objects_projects.rb b/spec/factories/lfs_objects_projects.rb
index 4804d0bb884..7b55cc57f75 100644
--- a/spec/factories/lfs_objects_projects.rb
+++ b/spec/factories/lfs_objects_projects.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :lfs_objects_project do
lfs_object
diff --git a/spec/factories/lists.rb b/spec/factories/lists.rb
index 210c58b21e9..e68611ec518 100644
--- a/spec/factories/lists.rb
+++ b/spec/factories/lists.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :list do
board
diff --git a/spec/factories/merge_requests.rb b/spec/factories/merge_requests.rb
index 0b6a43b13a9..3d12ff98257 100644
--- a/spec/factories/merge_requests.rb
+++ b/spec/factories/merge_requests.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :merge_request do
title { generate(:title) }
diff --git a/spec/factories/merge_requests_closing_issues.rb b/spec/factories/merge_requests_closing_issues.rb
index ee0606a72b6..94f8b27358c 100644
--- a/spec/factories/merge_requests_closing_issues.rb
+++ b/spec/factories/merge_requests_closing_issues.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :merge_requests_closing_issues do
issue
diff --git a/spec/factories/milestones.rb b/spec/factories/milestones.rb
index 027349b2f8e..7d623000fc9 100644
--- a/spec/factories/milestones.rb
+++ b/spec/factories/milestones.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :milestone do
title
diff --git a/spec/factories/namespaces.rb b/spec/factories/namespaces.rb
index 0cfc6e3aa46..09dbe16ef9e 100644
--- a/spec/factories/namespaces.rb
+++ b/spec/factories/namespaces.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :namespace do
sequence(:name) { |n| "namespace#{n}" }
diff --git a/spec/factories/notes.rb b/spec/factories/notes.rb
index c51f2f958f9..5b9a7e6f864 100644
--- a/spec/factories/notes.rb
+++ b/spec/factories/notes.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require_relative '../support/helpers/repo_helpers'
include ActionDispatch::TestProcess
diff --git a/spec/factories/notification_settings.rb b/spec/factories/notification_settings.rb
index 5116ef33f5d..c16b0e456ba 100644
--- a/spec/factories/notification_settings.rb
+++ b/spec/factories/notification_settings.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :notification_setting do
source factory: :project
diff --git a/spec/factories/oauth_access_grants.rb b/spec/factories/oauth_access_grants.rb
index 02c51cd9899..7a46ae6d71d 100644
--- a/spec/factories/oauth_access_grants.rb
+++ b/spec/factories/oauth_access_grants.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :oauth_access_grant do
resource_owner_id { create(:user).id }
diff --git a/spec/factories/oauth_access_tokens.rb b/spec/factories/oauth_access_tokens.rb
index eabfd6cd830..8d1075dacbb 100644
--- a/spec/factories/oauth_access_tokens.rb
+++ b/spec/factories/oauth_access_tokens.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :oauth_access_token do
resource_owner
diff --git a/spec/factories/oauth_applications.rb b/spec/factories/oauth_applications.rb
index 4427da1d6c7..4748b320298 100644
--- a/spec/factories/oauth_applications.rb
+++ b/spec/factories/oauth_applications.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :oauth_application, class: 'Doorkeeper::Application', aliases: [:application] do
sequence(:name) { |n| "OAuth App #{n}" }
diff --git a/spec/factories/pages_domains.rb b/spec/factories/pages_domains.rb
index e441dfcf229..ee5be82cd19 100644
--- a/spec/factories/pages_domains.rb
+++ b/spec/factories/pages_domains.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :pages_domain, class: 'PagesDomain' do
sequence(:domain) { |n| "my#{n}.domain.com" }
diff --git a/spec/factories/personal_access_tokens.rb b/spec/factories/personal_access_tokens.rb
index e7fd22a96b2..cc9b2328705 100644
--- a/spec/factories/personal_access_tokens.rb
+++ b/spec/factories/personal_access_tokens.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :personal_access_token do
user
diff --git a/spec/factories/pool_repositories.rb b/spec/factories/pool_repositories.rb
index 8cac666069c..7a8946d47b0 100644
--- a/spec/factories/pool_repositories.rb
+++ b/spec/factories/pool_repositories.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :pool_repository do
shard { Shard.by_name("default") }
diff --git a/spec/factories/programming_languages.rb b/spec/factories/programming_languages.rb
index d3511d42b6c..ee8e7765ec9 100644
--- a/spec/factories/programming_languages.rb
+++ b/spec/factories/programming_languages.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :programming_language do
name 'Ruby'
diff --git a/spec/factories/project_auto_devops.rb b/spec/factories/project_auto_devops.rb
index 1de42512402..4cc59c7095c 100644
--- a/spec/factories/project_auto_devops.rb
+++ b/spec/factories/project_auto_devops.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :project_auto_devops do
project
diff --git a/spec/factories/project_custom_attributes.rb b/spec/factories/project_custom_attributes.rb
index 099d2d7ff19..c9ed86cc0ac 100644
--- a/spec/factories/project_custom_attributes.rb
+++ b/spec/factories/project_custom_attributes.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :project_custom_attribute do
project
diff --git a/spec/factories/project_deploy_tokens.rb b/spec/factories/project_deploy_tokens.rb
index 4866cb58d88..fbf5454b0fe 100644
--- a/spec/factories/project_deploy_tokens.rb
+++ b/spec/factories/project_deploy_tokens.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :project_deploy_token do
project
diff --git a/spec/factories/project_group_links.rb b/spec/factories/project_group_links.rb
index 59c77627ee5..b02d167a950 100644
--- a/spec/factories/project_group_links.rb
+++ b/spec/factories/project_group_links.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :project_group_link do
project
diff --git a/spec/factories/project_hooks.rb b/spec/factories/project_hooks.rb
index a448d565e4b..96c9742c7d0 100644
--- a/spec/factories/project_hooks.rb
+++ b/spec/factories/project_hooks.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :project_hook do
url { generate(:url) }
diff --git a/spec/factories/project_members.rb b/spec/factories/project_members.rb
index c72e0487895..6dcac0400ca 100644
--- a/spec/factories/project_members.rb
+++ b/spec/factories/project_members.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :project_member do
user
diff --git a/spec/factories/project_statistics.rb b/spec/factories/project_statistics.rb
index 3d4174eb852..f084d9d5cbf 100644
--- a/spec/factories/project_statistics.rb
+++ b/spec/factories/project_statistics.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :project_statistics do
project
diff --git a/spec/factories/project_wikis.rb b/spec/factories/project_wikis.rb
index 4d21ed47f39..401402614f4 100644
--- a/spec/factories/project_wikis.rb
+++ b/spec/factories/project_wikis.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :project_wiki do
skip_create
diff --git a/spec/factories/projects.rb b/spec/factories/projects.rb
index 0e8810b73a1..afe27aaf1fb 100644
--- a/spec/factories/projects.rb
+++ b/spec/factories/projects.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require_relative '../support/helpers/test_env'
FactoryBot.define do
diff --git a/spec/factories/protected_branches.rb b/spec/factories/protected_branches.rb
index 5457c0d2a8f..741615bc0d3 100644
--- a/spec/factories/protected_branches.rb
+++ b/spec/factories/protected_branches.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :protected_branch do
name
diff --git a/spec/factories/protected_tags.rb b/spec/factories/protected_tags.rb
index 2b81d089549..6ff2a245b58 100644
--- a/spec/factories/protected_tags.rb
+++ b/spec/factories/protected_tags.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :protected_tag do
name
diff --git a/spec/factories/redirect_routes.rb b/spec/factories/redirect_routes.rb
index 774232d0b34..8fa0aec007c 100644
--- a/spec/factories/redirect_routes.rb
+++ b/spec/factories/redirect_routes.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :redirect_route do
sequence(:path) { |n| "redirect#{n}" }
diff --git a/spec/factories/releases.rb b/spec/factories/releases.rb
index 4cacc77c182..34794f57284 100644
--- a/spec/factories/releases.rb
+++ b/spec/factories/releases.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :release do
tag "v1.1.0"
diff --git a/spec/factories/remote_mirrors.rb b/spec/factories/remote_mirrors.rb
index adc7da27522..ff1d751c86c 100644
--- a/spec/factories/remote_mirrors.rb
+++ b/spec/factories/remote_mirrors.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :remote_mirror, class: 'RemoteMirror' do
association :project, :repository
diff --git a/spec/factories/repository_languages.rb b/spec/factories/repository_languages.rb
index 1757ba6766c..b2b17ebbce2 100644
--- a/spec/factories/repository_languages.rb
+++ b/spec/factories/repository_languages.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :repository_language do
project
diff --git a/spec/factories/sent_notifications.rb b/spec/factories/sent_notifications.rb
index b0174dd06b7..11116af7dbb 100644
--- a/spec/factories/sent_notifications.rb
+++ b/spec/factories/sent_notifications.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :sent_notification do
project
diff --git a/spec/factories/sequences.rb b/spec/factories/sequences.rb
index f2b6e7a11f9..b6f2d6d8389 100644
--- a/spec/factories/sequences.rb
+++ b/spec/factories/sequences.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
sequence(:username) { |n| "user#{n}" }
sequence(:name) { |n| "John Doe#{n}" }
diff --git a/spec/factories/service_hooks.rb b/spec/factories/service_hooks.rb
index c907862b4f6..ff819f4f8d0 100644
--- a/spec/factories/service_hooks.rb
+++ b/spec/factories/service_hooks.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :service_hook do
url { generate(:url) }
diff --git a/spec/factories/services.rb b/spec/factories/services.rb
index daf842e3075..5ef39b3e818 100644
--- a/spec/factories/services.rb
+++ b/spec/factories/services.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :service do
project
diff --git a/spec/factories/shards.rb b/spec/factories/shards.rb
index c095fa5f0a0..c30a38180e8 100644
--- a/spec/factories/shards.rb
+++ b/spec/factories/shards.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :shard do
name "default"
diff --git a/spec/factories/snippets.rb b/spec/factories/snippets.rb
index dc12b562108..9c3a0fbe9b3 100644
--- a/spec/factories/snippets.rb
+++ b/spec/factories/snippets.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :snippet do
author
diff --git a/spec/factories/spam_logs.rb b/spec/factories/spam_logs.rb
index a467f850a80..42a856832e7 100644
--- a/spec/factories/spam_logs.rb
+++ b/spec/factories/spam_logs.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :spam_log do
user
diff --git a/spec/factories/subscriptions.rb b/spec/factories/subscriptions.rb
index 8f7ab74ec70..2b652cd57bf 100644
--- a/spec/factories/subscriptions.rb
+++ b/spec/factories/subscriptions.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :subscription do
project
diff --git a/spec/factories/system_hooks.rb b/spec/factories/system_hooks.rb
index 9e00eeb6ef1..a2d163a060f 100644
--- a/spec/factories/system_hooks.rb
+++ b/spec/factories/system_hooks.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :system_hook do
url { generate(:url) }
diff --git a/spec/factories/system_note_metadata.rb b/spec/factories/system_note_metadata.rb
index e913068da40..8cd4b77799c 100644
--- a/spec/factories/system_note_metadata.rb
+++ b/spec/factories/system_note_metadata.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :system_note_metadata do
note
diff --git a/spec/factories/term_agreements.rb b/spec/factories/term_agreements.rb
index 3c4eebd0196..b7e259bd44b 100644
--- a/spec/factories/term_agreements.rb
+++ b/spec/factories/term_agreements.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :term_agreement do
term
diff --git a/spec/factories/terms.rb b/spec/factories/terms.rb
index 5ffca365a5f..b890261d293 100644
--- a/spec/factories/terms.rb
+++ b/spec/factories/terms.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :term, class: ApplicationSetting::Term do
terms "Lorem ipsum dolor sit amet, consectetur adipiscing elit."
diff --git a/spec/factories/timelogs.rb b/spec/factories/timelogs.rb
index b45f06b9a0a..056a8833c46 100644
--- a/spec/factories/timelogs.rb
+++ b/spec/factories/timelogs.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
# Read about factories at https://github.com/thoughtbot/factory_bot
FactoryBot.define do
diff --git a/spec/factories/todos.rb b/spec/factories/todos.rb
index ed3d87eb76b..2ff024112a4 100644
--- a/spec/factories/todos.rb
+++ b/spec/factories/todos.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :todo do
project
diff --git a/spec/factories/trending_project.rb b/spec/factories/trending_project.rb
index f7c634fd21f..354b8c1e002 100644
--- a/spec/factories/trending_project.rb
+++ b/spec/factories/trending_project.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
# TrendingProject
factory :trending_project, class: 'TrendingProject' do
diff --git a/spec/factories/u2f_registrations.rb b/spec/factories/u2f_registrations.rb
index 26090b08966..c968468834b 100644
--- a/spec/factories/u2f_registrations.rb
+++ b/spec/factories/u2f_registrations.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :u2f_registration do
certificate { FFaker::BaconIpsum.characters(728) }
diff --git a/spec/factories/uploads.rb b/spec/factories/uploads.rb
index 426abdc2a6c..2ede92c8af0 100644
--- a/spec/factories/uploads.rb
+++ b/spec/factories/uploads.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :upload do
model { build(:project) }
diff --git a/spec/factories/user_agent_details.rb b/spec/factories/user_agent_details.rb
index 7183a8e1140..055aea50585 100644
--- a/spec/factories/user_agent_details.rb
+++ b/spec/factories/user_agent_details.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :user_agent_detail do
ip_address '127.0.0.1'
diff --git a/spec/factories/user_callouts.rb b/spec/factories/user_callouts.rb
index 528e442c14b..c4a217fd357 100644
--- a/spec/factories/user_callouts.rb
+++ b/spec/factories/user_callouts.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :user_callout do
feature_name :gke_cluster_integration
diff --git a/spec/factories/user_custom_attributes.rb b/spec/factories/user_custom_attributes.rb
index a184a2e0f17..7bd5c06f4ef 100644
--- a/spec/factories/user_custom_attributes.rb
+++ b/spec/factories/user_custom_attributes.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :user_custom_attribute do
user
diff --git a/spec/factories/users.rb b/spec/factories/users.rb
index 4f3392cdcbf..b2c8bdab013 100644
--- a/spec/factories/users.rb
+++ b/spec/factories/users.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :user, aliases: [:author, :assignee, :recipient, :owner, :resource_owner] do
email { generate(:email) }
diff --git a/spec/factories/users_star_projects.rb b/spec/factories/users_star_projects.rb
index 6afd08a2084..a1299024fe4 100644
--- a/spec/factories/users_star_projects.rb
+++ b/spec/factories/users_star_projects.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :users_star_project do
project
diff --git a/spec/factories/web_hook_log.rb b/spec/factories/web_hook_log.rb
index 17837260a4b..5750af85662 100644
--- a/spec/factories/web_hook_log.rb
+++ b/spec/factories/web_hook_log.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :web_hook_log do
web_hook factory: :project_hook
diff --git a/spec/factories/wiki_directories.rb b/spec/factories/wiki_directories.rb
index b105c82b19d..de23cf110b5 100644
--- a/spec/factories/wiki_directories.rb
+++ b/spec/factories/wiki_directories.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
FactoryBot.define do
factory :wiki_directory do
skip_create
diff --git a/spec/factories/wiki_pages.rb b/spec/factories/wiki_pages.rb
index ae257d769e8..761ba58edb2 100644
--- a/spec/factories/wiki_pages.rb
+++ b/spec/factories/wiki_pages.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'ostruct'
FactoryBot.define do
diff --git a/spec/features/contextual_sidebar_spec.rb b/spec/features/contextual_sidebar_spec.rb
index 88da1b7966b..9807818bef7 100644
--- a/spec/features/contextual_sidebar_spec.rb
+++ b/spec/features/contextual_sidebar_spec.rb
@@ -20,7 +20,7 @@ describe 'Contextual sidebar', :js do
expect(page).to have_selector('.is-showing-fly-out')
- find('.qa-link-project').hover
+ find('a[data-qa-selector="project_link"]').hover
expect(page).not_to have_selector('.is-showing-fly-out')
@@ -30,7 +30,7 @@ describe 'Contextual sidebar', :js do
expect(page).to have_selector('.is-showing-fly-out')
- find('.qa-link-project').hover
+ find('a[data-qa-selector="project_link"]').hover
expect(page).to have_selector('.is-showing-fly-out')
end
diff --git a/spec/features/dashboard/groups_list_spec.rb b/spec/features/dashboard/groups_list_spec.rb
index fb76e2b0014..bdab3c63244 100644
--- a/spec/features/dashboard/groups_list_spec.rb
+++ b/spec/features/dashboard/groups_list_spec.rb
@@ -27,7 +27,7 @@ describe 'Dashboard Groups page', :js do
expect(page).not_to have_content(another_group.name)
end
- it 'shows subgroups the user is member of', :nested_groups do
+ it 'shows subgroups the user is member of' do
group.add_owner(user)
nested_group.add_owner(user)
@@ -40,7 +40,7 @@ describe 'Dashboard Groups page', :js do
expect(page).to have_content(nested_group.name)
end
- context 'when filtering groups', :nested_groups do
+ context 'when filtering groups' do
before do
group.add_owner(user)
nested_group.add_owner(user)
@@ -79,7 +79,7 @@ describe 'Dashboard Groups page', :js do
end
end
- context 'with subgroups', :nested_groups do
+ context 'with subgroups' do
let!(:subgroup) { create(:group, :public, parent: group) }
before do
diff --git a/spec/features/groups/empty_states_spec.rb b/spec/features/groups/empty_states_spec.rb
index e4eb0d355d1..3fbc0f78d38 100644
--- a/spec/features/groups/empty_states_spec.rb
+++ b/spec/features/groups/empty_states_spec.rb
@@ -110,7 +110,7 @@ describe 'Group empty states' do
end
context 'group without a project' do
- context 'group has a subgroup', :nested_groups do
+ context 'group has a subgroup' do
let(:subgroup) { create(:group, parent: group) }
let(:subgroup_project) { create(:project, namespace: subgroup) }
diff --git a/spec/features/groups/group_settings_spec.rb b/spec/features/groups/group_settings_spec.rb
index 676769c25fe..257aeae7e23 100644
--- a/spec/features/groups/group_settings_spec.rb
+++ b/spec/features/groups/group_settings_spec.rb
@@ -121,7 +121,7 @@ describe 'Edit group settings' do
expect(find(:css, '.group-root-path').text).to eq(root_url)
end
- it 'has a parent group URL label for a subgroup group', :postgresql do
+ it 'has a parent group URL label for a subgroup group' do
subgroup = create(:group, parent: group)
visit edit_group_path(subgroup)
diff --git a/spec/features/groups/issues_spec.rb b/spec/features/groups/issues_spec.rb
index 0ada530781c..a16004c79ca 100644
--- a/spec/features/groups/issues_spec.rb
+++ b/spec/features/groups/issues_spec.rb
@@ -50,7 +50,7 @@ describe 'Group issues page' do
end
end
- context 'issues list', :nested_groups do
+ context 'issues list' do
let(:subgroup) { create(:group, parent: group) }
let(:subgroup_project) { create(:project, :public, group: subgroup)}
let(:user_in_group) { create(:group_member, :maintainer, user: create(:user), group: group ).user }
diff --git a/spec/features/groups/members/list_members_spec.rb b/spec/features/groups/members/list_members_spec.rb
index 4ba7161601e..ffff755793f 100644
--- a/spec/features/groups/members/list_members_spec.rb
+++ b/spec/features/groups/members/list_members_spec.rb
@@ -13,7 +13,7 @@ describe 'Groups > Members > List members' do
sign_in(user1)
end
- it 'show members from current group and parent', :nested_groups do
+ it 'show members from current group and parent' do
group.add_developer(user1)
nested_group.add_developer(user2)
@@ -23,7 +23,7 @@ describe 'Groups > Members > List members' do
expect(second_row.text).to include(user2.name)
end
- it 'show user once if member of both current group and parent', :nested_groups do
+ it 'show user once if member of both current group and parent' do
group.add_developer(user1)
nested_group.add_developer(user1)
diff --git a/spec/features/groups/share_lock_spec.rb b/spec/features/groups/share_lock_spec.rb
index 704d9f12888..86b523fbdd9 100644
--- a/spec/features/groups/share_lock_spec.rb
+++ b/spec/features/groups/share_lock_spec.rb
@@ -9,7 +9,7 @@ describe 'Group share with group lock' do
sign_in(root_owner)
end
- context 'with a subgroup', :nested_groups do
+ context 'with a subgroup' do
let!(:subgroup) { create(:group, parent: root_group) }
context 'when enabling the parent group share with group lock' do
diff --git a/spec/features/groups/show_spec.rb b/spec/features/groups/show_spec.rb
index bed998a0859..0d78bd23973 100644
--- a/spec/features/groups/show_spec.rb
+++ b/spec/features/groups/show_spec.rb
@@ -75,11 +75,7 @@ describe 'Group show page' do
sign_in(owner)
end
- context 'when subgroups are supported', :nested_groups do
- before do
- allow(Group).to receive(:supports_nested_objects?) { true }
- end
-
+ context 'when subgroups are supported' do
it 'allows creating subgroups' do
visit path
@@ -87,19 +83,6 @@ describe 'Group show page' do
.to have_css("li[data-text='New subgroup']", visible: false)
end
end
-
- context 'when subgroups are not supported' do
- before do
- allow(Group).to receive(:supports_nested_objects?) { false }
- end
-
- it 'does not allow creating subgroups' do
- visit path
-
- expect(page)
- .not_to have_selector("li[data-text='New subgroup']", visible: false)
- end
- end
end
context 'for maintainers' do
@@ -107,11 +90,7 @@ describe 'Group show page' do
sign_in(maintainer)
end
- context 'when subgroups are supported', :nested_groups do
- before do
- allow(Group).to receive(:supports_nested_objects?) { true }
- end
-
+ context 'when subgroups are supported' do
context 'when subgroup_creation_level is set to maintainers' do
before do
relaxed_group.add_maintainer(maintainer)
@@ -141,19 +120,6 @@ describe 'Group show page' do
end
end
end
-
- context 'when subgroups are not supported' do
- before do
- allow(Group).to receive(:supports_nested_objects?) { false }
- end
-
- it 'does not allow creating subgroups' do
- visit path
-
- expect(page)
- .not_to have_selector("li[data-text='New subgroup']", visible: false)
- end
- end
end
end
diff --git a/spec/features/groups_spec.rb b/spec/features/groups_spec.rb
index 8e7f78cab81..ad645643919 100644
--- a/spec/features/groups_spec.rb
+++ b/spec/features/groups_spec.rb
@@ -105,7 +105,7 @@ describe 'Group' do
end
end
- describe 'create a nested group', :nested_groups, :js do
+ describe 'create a nested group', :js do
let(:group) { create(:group, path: 'foo') }
context 'as admin' do
@@ -231,7 +231,7 @@ describe 'Group' do
end
end
- describe 'group page with nested groups', :nested_groups, :js do
+ describe 'group page with nested groups', :js do
let!(:group) { create(:group) }
let!(:nested_group) { create(:group, parent: group) }
let!(:project) { create(:project, namespace: group) }
diff --git a/spec/features/ide_spec.rb b/spec/features/ide_spec.rb
index 6eb59ef72c2..65989c36c1e 100644
--- a/spec/features/ide_spec.rb
+++ b/spec/features/ide_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe 'IDE', :js do
- describe 'sub-groups', :nested_groups do
+ describe 'sub-groups' do
let(:user) { create(:user) }
let(:group) { create(:group) }
let(:subgroup) { create(:group, parent: group) }
diff --git a/spec/features/import/manifest_import_spec.rb b/spec/features/import/manifest_import_spec.rb
index a90cdd8d920..90b499efd72 100644
--- a/spec/features/import/manifest_import_spec.rb
+++ b/spec/features/import/manifest_import_spec.rb
@@ -1,6 +1,6 @@
require 'spec_helper'
-describe 'Import multiple repositories by uploading a manifest file', :js, :postgresql do
+describe 'Import multiple repositories by uploading a manifest file', :js do
include Select2Helper
let(:user) { create(:admin) }
diff --git a/spec/features/labels_hierarchy_spec.rb b/spec/features/labels_hierarchy_spec.rb
index 489651fea15..45bd2218ee6 100644
--- a/spec/features/labels_hierarchy_spec.rb
+++ b/spec/features/labels_hierarchy_spec.rb
@@ -1,6 +1,6 @@
require 'spec_helper'
-describe 'Labels Hierarchy', :js, :nested_groups do
+describe 'Labels Hierarchy', :js do
include FilteredSearchHelpers
let!(:user) { create(:user) }
diff --git a/spec/features/markdown/metrics_spec.rb b/spec/features/markdown/metrics_spec.rb
new file mode 100644
index 00000000000..aa53ac50c78
--- /dev/null
+++ b/spec/features/markdown/metrics_spec.rb
@@ -0,0 +1,60 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe 'Metrics rendering', :js, :use_clean_rails_memory_store_caching do
+ include PrometheusHelpers
+
+ let(:user) { create(:user) }
+ let(:project) { create(:prometheus_project) }
+ let(:environment) { create(:environment, project: project) }
+ let(:issue) { create(:issue, project: project, description: description) }
+ let(:description) { "See [metrics dashboard](#{metrics_url}) for info." }
+ let(:metrics_url) { metrics_project_environment_url(project, environment) }
+
+ before do
+ configure_host
+ import_common_metrics
+ stub_any_prometheus_request_with_response
+
+ project.add_developer(user)
+
+ sign_in(user)
+ end
+
+ after do
+ restore_host
+ end
+
+ context 'with deployments and related deployable present' do
+ it 'shows embedded metrics' do
+ visit project_issue_path(project, issue)
+
+ expect(page).to have_css('div.prometheus-graph')
+ expect(page).to have_text('Memory Usage (Total)')
+ expect(page).to have_text('Core Usage (Total)')
+ end
+ end
+
+ def import_common_metrics
+ ::Gitlab::DatabaseImporters::CommonMetrics::Importer.new.execute
+ end
+
+ def configure_host
+ @original_default_host = default_url_options[:host]
+ @original_gitlab_url = Gitlab.config.gitlab[:url]
+
+ # Ensure we create a metrics url with the right host.
+ # Configure host for route helpers in specs (also updates root_url):
+ default_url_options[:host] = Capybara.server_host
+
+ # Ensure we identify urls with the appropriate host.
+ # Configure host to include port in app:
+ Gitlab.config.gitlab[:url] = root_url.chomp('/')
+ end
+
+ def restore_host
+ default_url_options[:host] = @original_default_host
+ Gitlab.config.gitlab[:url] = @original_gitlab_url
+ end
+end
diff --git a/spec/features/oauth_login_spec.rb b/spec/features/oauth_login_spec.rb
index 86331728f88..54705cd51b0 100644
--- a/spec/features/oauth_login_spec.rb
+++ b/spec/features/oauth_login_spec.rb
@@ -34,6 +34,7 @@ describe 'OAuth Login', :js, :allow_forgery_protection do
before do
stub_omniauth_config(provider)
+ expect(ActiveSession).to receive(:cleanup).with(user).at_least(:once).and_call_original
end
context 'when two-factor authentication is disabled' do
diff --git a/spec/features/projects/artifacts/user_downloads_artifacts_spec.rb b/spec/features/projects/artifacts/user_downloads_artifacts_spec.rb
index 5cb015e80be..69296ef00fd 100644
--- a/spec/features/projects/artifacts/user_downloads_artifacts_spec.rb
+++ b/spec/features/projects/artifacts/user_downloads_artifacts_spec.rb
@@ -1,8 +1,8 @@
require "spec_helper"
describe "User downloads artifacts" do
- set(:project) { create(:project, :public) }
- set(:pipeline) { create(:ci_empty_pipeline, status: :success, project: project) }
+ set(:project) { create(:project, :repository, :public) }
+ set(:pipeline) { create(:ci_empty_pipeline, status: :success, sha: project.commit.id, project: project) }
set(:job) { create(:ci_build, :artifacts, :success, pipeline: pipeline) }
shared_examples "downloading" do
diff --git a/spec/features/projects/members/invite_group_spec.rb b/spec/features/projects/members/invite_group_spec.rb
index 7432c600c1e..c5423ec4662 100644
--- a/spec/features/projects/members/invite_group_spec.rb
+++ b/spec/features/projects/members/invite_group_spec.rb
@@ -58,7 +58,7 @@ describe 'Project > Members > Invite group', :js do
end
end
- context 'for a project in a subgroup', :nested_groups do
+ context 'for a project in a subgroup' do
let!(:group_to_share_with) { create(:group) }
let(:root_group) { create(:group) }
let(:subgroup) { create(:group, parent: root_group) }
@@ -181,7 +181,7 @@ describe 'Project > Members > Invite group', :js do
group_to_share_with.add_maintainer(maintainer)
end
- it 'the groups dropdown does not show ancestors', :nested_groups do
+ it 'the groups dropdown does not show ancestors' do
visit project_settings_members_path(project)
click_on 'invite-group-tab'
diff --git a/spec/features/projects/new_project_spec.rb b/spec/features/projects/new_project_spec.rb
index 7602935b47e..8cdaed43fbc 100644
--- a/spec/features/projects/new_project_spec.rb
+++ b/spec/features/projects/new_project_spec.rb
@@ -294,7 +294,7 @@ describe 'New project' do
end
end
- context 'from manifest file', :postgresql do
+ context 'from manifest file' do
before do
first('.import_manifest').click
end
diff --git a/spec/features/projects/settings/pipelines_settings_spec.rb b/spec/features/projects/settings/pipelines_settings_spec.rb
index bf0c0de89b2..31fdd308292 100644
--- a/spec/features/projects/settings/pipelines_settings_spec.rb
+++ b/spec/features/projects/settings/pipelines_settings_spec.rb
@@ -126,7 +126,7 @@ describe "Projects > Settings > Pipelines settings" do
end
end
- context 'when auto devops is turned on group parent level', :nested_groups do
+ context 'when auto devops is turned on group parent level' do
before do
group = create(:group, parent: create(:group, :auto_devops_enabled))
project.update!(namespace: group)
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 2fdbc04fa62..9af2e47a334 100644
--- a/spec/features/projects/settings/user_transfers_a_project_spec.rb
+++ b/spec/features/projects/settings/user_transfers_a_project_spec.rb
@@ -68,7 +68,7 @@ describe 'Projects > Settings > User transfers a project', :js do
end
end
- context 'when nested groups are available', :nested_groups do
+ context 'when nested groups are available' do
it 'allows transferring a project to a subgroup' do
subgroup = create(:group, parent: group)
diff --git a/spec/features/projects/sub_group_issuables_spec.rb b/spec/features/projects/sub_group_issuables_spec.rb
index 50e7e934cf6..8afbcf72ca7 100644
--- a/spec/features/projects/sub_group_issuables_spec.rb
+++ b/spec/features/projects/sub_group_issuables_spec.rb
@@ -1,6 +1,6 @@
require 'spec_helper'
-describe 'Subgroup Issuables', :js, :nested_groups do
+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/user_creates_project_spec.rb b/spec/features/projects/user_creates_project_spec.rb
index c0932539131..19262a635ac 100644
--- a/spec/features/projects/user_creates_project_spec.rb
+++ b/spec/features/projects/user_creates_project_spec.rb
@@ -26,7 +26,7 @@ describe 'User creates a project', :js do
expect(page).to have_content(project.url_to_repo)
end
- context 'in a subgroup they do not own', :nested_groups do
+ context 'in a subgroup they do not own' do
let(:parent) { create(:group) }
let!(:subgroup) { create(:group, parent: parent) }
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 aac095bfa6b..80741ace5d6 100644
--- a/spec/features/projects/wiki/user_creates_wiki_page_spec.rb
+++ b/spec/features/projects/wiki/user_creates_wiki_page_spec.rb
@@ -132,9 +132,15 @@ describe "User creates wiki page" do
fill_in(:wiki_content, with: ascii_content)
- page.within(".wiki-form") do
- click_button("Create page")
- end
+ # This is the dumbest bug in the world:
+ # When the #wiki_content textarea is filled in, JS captures the `Enter` keydown event in order to do
+ # auto-indentation and manually inserts a newline. However, for whatever reason, when you try to click on the
+ # submit button in Capybara, it will not trigger the `click` event if a \n or \r character has been manually
+ # added to the textarea. It will, however, trigger ALL OTHER EVENTS, including `mouseover`/down/up, focus, and
+ # blur. Just not `click`. But only when you manually insert \n or \r - if you manually insert any other sequence
+ # then `click` is fired normally. And it's only Capybara. Browsers and JSDOM don't have this issue.
+ # So that's why the next line performs the click via JS.
+ page.execute_script("document.querySelector('.qa-create-page-button').click()")
page.within ".md" do
expect(page).to have_selector(".katex", count: 3).and have_content("2+2 is 4")
diff --git a/spec/features/projects_spec.rb b/spec/features/projects_spec.rb
index b5112758475..d1e2d17e9cc 100644
--- a/spec/features/projects_spec.rb
+++ b/spec/features/projects_spec.rb
@@ -314,7 +314,7 @@ describe 'Project' do
end
end
- context 'for subgroups', :js, :nested_groups do
+ context 'for subgroups', :js do
let(:group) { create(:group) }
let(:subgroup) { create(:group, parent: group) }
let(:project) { create(:project, :repository, group: subgroup) }
diff --git a/spec/features/users/login_spec.rb b/spec/features/users/login_spec.rb
index efba303033b..1ea88010c89 100644
--- a/spec/features/users/login_spec.rb
+++ b/spec/features/users/login_spec.rb
@@ -132,7 +132,6 @@ describe 'Login' do
it 'does not show a "You are already signed in." error message' do
expect(authentication_metrics)
.to increment(:user_authenticated_counter)
- .and increment(:user_session_override_counter)
.and increment(:user_two_factor_authenticated_counter)
enter_code(user.current_otp)
@@ -144,7 +143,6 @@ describe 'Login' do
it 'allows login with valid code' do
expect(authentication_metrics)
.to increment(:user_authenticated_counter)
- .and increment(:user_session_override_counter)
.and increment(:user_two_factor_authenticated_counter)
enter_code(user.current_otp)
@@ -170,7 +168,6 @@ describe 'Login' do
it 'allows login with invalid code, then valid code' do
expect(authentication_metrics)
.to increment(:user_authenticated_counter)
- .and increment(:user_session_override_counter)
.and increment(:user_two_factor_authenticated_counter)
enter_code('foo')
@@ -179,6 +176,15 @@ describe 'Login' do
enter_code(user.current_otp)
expect(current_path).to eq root_path
end
+
+ it 'triggers ActiveSession.cleanup for the user' do
+ expect(authentication_metrics)
+ .to increment(:user_authenticated_counter)
+ .and increment(:user_two_factor_authenticated_counter)
+ expect(ActiveSession).to receive(:cleanup).with(user).once.and_call_original
+
+ enter_code(user.current_otp)
+ end
end
context 'using backup code' do
@@ -195,7 +201,6 @@ describe 'Login' do
it 'allows login' do
expect(authentication_metrics)
.to increment(:user_authenticated_counter)
- .and increment(:user_session_override_counter)
.and increment(:user_two_factor_authenticated_counter)
enter_code(codes.sample)
@@ -206,7 +211,6 @@ describe 'Login' do
it 'invalidates the used code' do
expect(authentication_metrics)
.to increment(:user_authenticated_counter)
- .and increment(:user_session_override_counter)
.and increment(:user_two_factor_authenticated_counter)
expect { enter_code(codes.sample) }
@@ -216,7 +220,6 @@ describe 'Login' do
it 'invalidates backup codes twice in a row' do
expect(authentication_metrics)
.to increment(:user_authenticated_counter).twice
- .and increment(:user_session_override_counter).twice
.and increment(:user_two_factor_authenticated_counter).twice
.and increment(:user_session_destroyed_counter)
@@ -230,6 +233,15 @@ describe 'Login' do
expect { enter_code(codes.sample) }
.to change { user.reload.otp_backup_codes.size }.by(-1)
end
+
+ it 'triggers ActiveSession.cleanup for the user' do
+ expect(authentication_metrics)
+ .to increment(:user_authenticated_counter)
+ .and increment(:user_two_factor_authenticated_counter)
+ expect(ActiveSession).to receive(:cleanup).with(user).once.and_call_original
+
+ enter_code(codes.sample)
+ end
end
context 'with invalid code' do
@@ -274,7 +286,7 @@ describe 'Login' do
expect(authentication_metrics)
.to increment(:user_authenticated_counter)
- .and increment(:user_session_override_counter)
+ expect(ActiveSession).to receive(:cleanup).with(user).once.and_call_original
sign_in_using_saml!
@@ -287,8 +299,8 @@ describe 'Login' do
it 'shows 2FA prompt after OAuth login' do
expect(authentication_metrics)
.to increment(:user_authenticated_counter)
- .and increment(:user_session_override_counter)
.and increment(:user_two_factor_authenticated_counter)
+ expect(ActiveSession).to receive(:cleanup).with(user).once.and_call_original
sign_in_using_saml!
@@ -329,6 +341,14 @@ describe 'Login' do
expect(page).not_to have_content(I18n.t('devise.failure.already_authenticated'))
end
+
+ it 'triggers ActiveSession.cleanup for the user' do
+ expect(authentication_metrics)
+ .to increment(:user_authenticated_counter)
+ expect(ActiveSession).to receive(:cleanup).with(user).once.and_call_original
+
+ gitlab_sign_in(user)
+ end
end
context 'with invalid username and password' do
@@ -649,7 +669,6 @@ describe 'Login' do
it 'asks the user to accept the terms' do
expect(authentication_metrics)
.to increment(:user_authenticated_counter)
- .and increment(:user_session_override_counter)
.and increment(:user_two_factor_authenticated_counter)
visit new_user_session_path
@@ -708,7 +727,6 @@ describe 'Login' do
it 'asks the user to accept the terms before setting an email' do
expect(authentication_metrics)
.to increment(:user_authenticated_counter)
- .and increment(:user_session_override_counter)
gitlab_sign_in_via('saml', user, 'my-uid')
diff --git a/spec/finders/autocomplete/users_finder_spec.rb b/spec/finders/autocomplete/users_finder_spec.rb
index bcde115b1a6..f3b54ca0461 100644
--- a/spec/finders/autocomplete/users_finder_spec.rb
+++ b/spec/finders/autocomplete/users_finder_spec.rb
@@ -50,7 +50,7 @@ describe Autocomplete::UsersFinder do
it { is_expected.to match_array([user1]) }
end
- context 'when passed a subgroup', :nested_groups do
+ context 'when passed a subgroup' do
let(:grandparent) { create(:group, :public) }
let(:parent) { create(:group, :public, parent: grandparent) }
let(:child) { create(:group, :public, parent: parent) }
diff --git a/spec/finders/cluster_ancestors_finder_spec.rb b/spec/finders/cluster_ancestors_finder_spec.rb
index 750042b6b54..4aedb41d446 100644
--- a/spec/finders/cluster_ancestors_finder_spec.rb
+++ b/spec/finders/cluster_ancestors_finder_spec.rb
@@ -32,7 +32,7 @@ describe ClusterAncestorsFinder, '#execute' do
is_expected.to eq([project_cluster, group_cluster, instance_cluster])
end
- context 'nested groups', :nested_groups do
+ context 'nested groups' do
let(:group) { create(:group, parent: parent_group) }
let(:parent_group) { create(:group) }
@@ -65,7 +65,7 @@ describe ClusterAncestorsFinder, '#execute' do
is_expected.to eq([group_cluster, instance_cluster])
end
- context 'nested groups', :nested_groups do
+ context 'nested groups' do
let(:group) { create(:group, parent: parent_group) }
let(:parent_group) { create(:group) }
diff --git a/spec/finders/group_descendants_finder_spec.rb b/spec/finders/group_descendants_finder_spec.rb
index c28fd7cad11..5fb6739d6e2 100644
--- a/spec/finders/group_descendants_finder_spec.rb
+++ b/spec/finders/group_descendants_finder_spec.rb
@@ -19,7 +19,7 @@ describe GroupDescendantsFinder do
expect(finder.has_children?).to be_truthy
end
- context 'when there are subgroups', :nested_groups do
+ context 'when there are subgroups' do
it 'is true when there are projects' do
create(:group, parent: group)
@@ -99,7 +99,7 @@ describe GroupDescendantsFinder do
)
end
- context 'with nested groups', :nested_groups do
+ context 'with nested groups' do
let!(:subgroup1) { create(:group, parent: group, name: 'a', path: 'sub-a') }
let!(:subgroup2) { create(:group, parent: group, name: 'z', path: 'sub-z') }
@@ -126,7 +126,7 @@ describe GroupDescendantsFinder do
end
end
- context 'with nested groups', :nested_groups do
+ context 'with nested groups' do
let!(:project) { create(:project, namespace: group) }
let!(:subgroup) { create(:group, :private, parent: group) }
diff --git a/spec/finders/group_members_finder_spec.rb b/spec/finders/group_members_finder_spec.rb
index 8975ea0f063..49b0e14241e 100644
--- a/spec/finders/group_members_finder_spec.rb
+++ b/spec/finders/group_members_finder_spec.rb
@@ -18,7 +18,7 @@ describe GroupMembersFinder, '#execute' do
expect(result.to_a).to match_array([member3, member2, member1])
end
- it 'returns members for nested group', :nested_groups do
+ it 'returns members for nested group' do
group.add_developer(user2)
nested_group.request_access(user4)
member1 = group.add_maintainer(user1)
@@ -30,7 +30,7 @@ describe GroupMembersFinder, '#execute' do
expect(result.to_a).to match_array([member1, member3, member4])
end
- it 'returns members for descendant groups if requested', :nested_groups do
+ it 'returns members for descendant groups if requested' do
member1 = group.add_maintainer(user2)
member2 = group.add_maintainer(user1)
nested_group.add_maintainer(user2)
diff --git a/spec/finders/group_projects_finder_spec.rb b/spec/finders/group_projects_finder_spec.rb
index f8fcc2d0e40..f4bd8a3f6ba 100644
--- a/spec/finders/group_projects_finder_spec.rb
+++ b/spec/finders/group_projects_finder_spec.rb
@@ -19,7 +19,7 @@ describe GroupProjectsFinder do
context "only owned" do
let(:options) { { only_owned: true } }
- context 'with subgroups projects', :nested_groups do
+ context 'with subgroups projects' do
before do
options[:include_subgroups] = true
end
@@ -33,7 +33,7 @@ describe GroupProjectsFinder do
end
context "all" do
- context 'with subgroups projects', :nested_groups do
+ context 'with subgroups projects' do
before do
options[:include_subgroups] = true
end
@@ -78,7 +78,7 @@ describe GroupProjectsFinder do
subgroup_private_project.add_maintainer(current_user)
end
- context 'with subgroups projects', :nested_groups do
+ context 'with subgroups projects' do
before do
options[:include_subgroups] = true
end
@@ -96,7 +96,7 @@ describe GroupProjectsFinder do
current_user.update(external: true)
end
- context 'with subgroups projects', :nested_groups do
+ context 'with subgroups projects' do
before do
options[:include_subgroups] = true
end
@@ -111,7 +111,7 @@ describe GroupProjectsFinder do
end
context "all" do
- context 'with subgroups projects', :nested_groups do
+ context 'with subgroups projects' do
before do
options[:include_subgroups] = true
end
@@ -153,7 +153,7 @@ describe GroupProjectsFinder do
context "only owned" do
let(:options) { { only_owned: true } }
- context 'with subgroups projects', :nested_groups do
+ context 'with subgroups projects' do
before do
options[:include_subgroups] = true
end
diff --git a/spec/finders/groups_finder_spec.rb b/spec/finders/groups_finder_spec.rb
index 367ca43bdfe..c8875d1f92d 100644
--- a/spec/finders/groups_finder_spec.rb
+++ b/spec/finders/groups_finder_spec.rb
@@ -65,7 +65,7 @@ describe GroupsFinder do
end
end
- context 'subgroups', :nested_groups do
+ context 'subgroups' do
let(:user) { create(:user) }
let!(:parent_group) { create(:group, :public) }
let!(:public_subgroup) { create(:group, :public, parent: parent_group) }
diff --git a/spec/finders/issues_finder_spec.rb b/spec/finders/issues_finder_spec.rb
index bf38d083ca6..7fbe27c1939 100644
--- a/spec/finders/issues_finder_spec.rb
+++ b/spec/finders/issues_finder_spec.rb
@@ -51,7 +51,7 @@ describe IssuesFinder do
end
end
- context 'when include_subgroup param is true', :nested_groups do
+ context 'when include_subgroup param is true' do
before do
params[:include_subgroups] = true
end
diff --git a/spec/finders/labels_finder_spec.rb b/spec/finders/labels_finder_spec.rb
index 98b4933fef6..ba41ded112a 100644
--- a/spec/finders/labels_finder_spec.rb
+++ b/spec/finders/labels_finder_spec.rb
@@ -89,7 +89,7 @@ describe LabelsFinder do
end
end
- context 'when including labels from group ancestors', :nested_groups do
+ context 'when including labels from group ancestors' do
it 'returns labels from group and its ancestors' do
private_group_1.add_developer(user)
private_subgroup_1.add_developer(user)
@@ -108,7 +108,7 @@ describe LabelsFinder do
end
end
- context 'when including labels from group descendants', :nested_groups do
+ context 'when including labels from group descendants' do
it 'returns labels from group and its descendants' do
private_group_1.add_developer(user)
private_subgroup_1.add_developer(user)
@@ -128,7 +128,7 @@ describe LabelsFinder do
end
end
- context 'filtering by project_id', :nested_groups do
+ context 'filtering by project_id' do
context 'when include_ancestor_groups is true' do
let!(:sub_project) { create(:project, namespace: private_subgroup_1 ) }
let!(:project_label) { create(:label, project: sub_project, title: 'Label 5') }
diff --git a/spec/finders/members_finder_spec.rb b/spec/finders/members_finder_spec.rb
index 83348457caa..4203f58fe81 100644
--- a/spec/finders/members_finder_spec.rb
+++ b/spec/finders/members_finder_spec.rb
@@ -9,7 +9,7 @@ describe MembersFinder, '#execute' do
set(:user3) { create(:user) }
set(:user4) { create(:user) }
- it 'returns members for project and parent groups', :nested_groups do
+ it 'returns members for project and parent groups' do
nested_group.request_access(user1)
member1 = group.add_maintainer(user2)
member2 = nested_group.add_maintainer(user3)
@@ -20,7 +20,7 @@ describe MembersFinder, '#execute' do
expect(result.to_a).to match_array([member1, member2, member3])
end
- it 'includes nested group members if asked', :nested_groups do
+ it 'includes nested group members if asked' do
project = create(:project, namespace: group)
nested_group.request_access(user1)
member1 = group.add_maintainer(user2)
@@ -32,7 +32,7 @@ describe MembersFinder, '#execute' do
expect(result.to_a).to match_array([member1, member2, member3])
end
- context 'when include_invited_groups_members == true', :nested_groups do
+ context 'when include_invited_groups_members == true' do
subject { described_class.new(project, user2).execute(include_invited_groups_members: true) }
set(:linked_group) { create(:group, :public, :access_requestable) }
@@ -40,7 +40,7 @@ describe MembersFinder, '#execute' do
set(:linked_group_member) { linked_group.add_developer(user1) }
set(:nested_linked_group_member) { nested_linked_group.add_developer(user2) }
- it 'includes all the invited_groups members including members inherited from ancestor groups', :nested_groups do
+ it 'includes all the invited_groups members including members inherited from ancestor groups' do
create(:project_group_link, project: project, group: nested_linked_group)
expect(subject).to contain_exactly(linked_group_member, nested_linked_group_member)
diff --git a/spec/finders/merge_requests_finder_spec.rb b/spec/finders/merge_requests_finder_spec.rb
index da5e9dab058..78224f0b9da 100644
--- a/spec/finders/merge_requests_finder_spec.rb
+++ b/spec/finders/merge_requests_finder_spec.rb
@@ -42,7 +42,7 @@ describe MergeRequestsFinder do
expect(merge_requests).to contain_exactly(merge_request1, merge_request2)
end
- it 'filters by group including subgroups', :nested_groups do
+ it 'filters by group including subgroups' do
params = { group_id: group.id, include_subgroups: true }
merge_requests = described_class.new(user, params).execute
diff --git a/spec/finders/todos_finder_spec.rb b/spec/finders/todos_finder_spec.rb
index 22318a9946a..f7b35e76925 100644
--- a/spec/finders/todos_finder_spec.rb
+++ b/spec/finders/todos_finder_spec.rb
@@ -36,7 +36,7 @@ describe TodosFinder do
expect(todos).to match_array([todo1])
end
- context 'with subgroups', :nested_groups do
+ context 'with subgroups' do
let(:subgroup) { create(:group, parent: group) }
let!(:todo3) { create(:todo, user: user, group: subgroup, target: issue) }
diff --git a/spec/fixtures/security-reports/dependency_list/gl-dependency-scanning-report.json b/spec/fixtures/security-reports/dependency_list/gl-dependency-scanning-report.json
index 1e62d020026..8fb66f6652b 100644
--- a/spec/fixtures/security-reports/dependency_list/gl-dependency-scanning-report.json
+++ b/spec/fixtures/security-reports/dependency_list/gl-dependency-scanning-report.json
@@ -7,7 +7,7 @@
"message": "Vulnerabilities in libxml2 in nokogiri",
"description": " The version of libxml2 packaged with Nokogiri contains several vulnerabilities.\r\n Nokogiri has mitigated these issues by upgrading to libxml 2.9.5.\r\n\r\n It was discovered that a type confusion error existed in libxml2. An\r\n attacker could use this to specially construct XML data that\r\n could cause a denial of service or possibly execute arbitrary\r\n code. (CVE-2017-0663)\r\n\r\n It was discovered that libxml2 did not properly validate parsed entity\r\n references. An attacker could use this to specially construct XML\r\n data that could expose sensitive information. (CVE-2017-7375)\r\n\r\n It was discovered that a buffer overflow existed in libxml2 when\r\n handling HTTP redirects. An attacker could use this to specially\r\n construct XML data that could cause a denial of service or possibly\r\n execute arbitrary code. (CVE-2017-7376)\r\n\r\n Marcel Böhme and Van-Thuan Pham discovered a buffer overflow in\r\n libxml2 when handling elements. An attacker could use this to specially\r\n construct XML data that could cause a denial of service or possibly\r\n execute arbitrary code. (CVE-2017-9047)\r\n\r\n Marcel Böhme and Van-Thuan Pham discovered a buffer overread\r\n in libxml2 when handling elements. An attacker could use this\r\n to specially construct XML data that could cause a denial of\r\n service. (CVE-2017-9048)\r\n\r\n Marcel Böhme and Van-Thuan Pham discovered multiple buffer overreads\r\n in libxml2 when handling parameter-entity references. An attacker\r\n could use these to specially construct XML data that could cause a\r\n denial of service. (CVE-2017-9049, CVE-2017-9050)",
"cve": "rails/Gemfile.lock:nokogiri:gemnasium:06565b64-486d-4326-b906-890d9915804d",
- "severity": "Unknown",
+ "severity": "High",
"solution": "Upgrade to latest version.",
"scanner": {
"id": "gemnasium",
@@ -48,7 +48,7 @@
"message": "Infinite recursion in parameter entities in nokogiri",
"description": "libxml2 incorrectly handles certain parameter entities. An attacker can leverage this with specially constructed XML data to cause libxml2 to consume resources, leading to a denial of service.",
"cve": "rails/Gemfile.lock:nokogiri:gemnasium:6a0d56f6-2441-492a-9b14-edb95ac31919",
- "severity": "Unknown",
+ "severity": "High",
"solution": "Upgrade to latest version.",
"scanner": {
"id": "gemnasium",
diff --git a/spec/frontend/helpers/indent_helper_spec.js b/spec/frontend/helpers/indent_helper_spec.js
new file mode 100644
index 00000000000..fca12f0d1ef
--- /dev/null
+++ b/spec/frontend/helpers/indent_helper_spec.js
@@ -0,0 +1,371 @@
+import IndentHelper from '~/helpers/indent_helper';
+
+function createMockTextarea() {
+ const el = document.createElement('textarea');
+ el.setCursor = pos => el.setSelectionRange(pos, pos);
+ el.setCursorToEnd = () => el.setCursor(el.value.length);
+ el.selection = () => [el.selectionStart, el.selectionEnd];
+ el.cursor = () => {
+ const [start, end] = el.selection();
+ return start === end ? start : undefined;
+ };
+ return el;
+}
+
+describe('indent_helper', () => {
+ let element;
+ let ih;
+
+ beforeEach(() => {
+ element = createMockTextarea();
+ ih = new IndentHelper(element);
+ });
+
+ describe('indents', () => {
+ describe('a single line', () => {
+ it('when on an empty line; and cursor follows', () => {
+ element.value = '';
+ ih.indent();
+ expect(element.value).toBe(' ');
+ expect(element.cursor()).toBe(4);
+ ih.indent();
+ expect(element.value).toBe(' ');
+ expect(element.cursor()).toBe(8);
+ });
+
+ it('when at the start of a line; and cursor stays at start', () => {
+ element.value = 'foobar';
+ element.setCursor(0);
+ ih.indent();
+ expect(element.value).toBe(' foobar');
+ expect(element.cursor()).toBe(4);
+ });
+
+ it('when the cursor is in the middle; and cursor follows', () => {
+ element.value = 'foobar';
+ element.setCursor(3);
+ ih.indent();
+ expect(element.value).toBe(' foobar');
+ expect(element.cursor()).toBe(7);
+ });
+ });
+
+ describe('several lines', () => {
+ it('when everything is selected; and everything remains selected', () => {
+ element.value = 'foo\nbar\nbaz';
+ element.setSelectionRange(0, 11);
+ ih.indent();
+ expect(element.value).toBe(' foo\n bar\n baz');
+ expect(element.selection()).toEqual([0, 23]);
+ });
+
+ it('when all lines are partially selected; and the selection adapts', () => {
+ element.value = 'foo\nbar\nbaz';
+ element.setSelectionRange(2, 9);
+ ih.indent();
+ expect(element.value).toBe(' foo\n bar\n baz');
+ expect(element.selection()).toEqual([6, 21]);
+ });
+
+ it('when some lines are entirely selected; and entire lines remain selected', () => {
+ element.value = 'foo\nbar\nbaz';
+ element.setSelectionRange(4, 11);
+ ih.indent();
+ expect(element.value).toBe('foo\n bar\n baz');
+ expect(element.selection()).toEqual([4, 19]);
+ });
+
+ it('when some lines are partially selected; and the selection adapts', () => {
+ element.value = 'foo\nbar\nbaz';
+ element.setSelectionRange(5, 9);
+ ih.indent();
+ expect(element.value).toBe('foo\n bar\n baz');
+ expect(element.selection()).toEqual([5 + 4, 9 + 2 * 4]);
+ });
+
+ it('having different indentation when some lines are entirely selected; and entire lines remain selected', () => {
+ element.value = ' foo\nbar\n baz';
+ element.setSelectionRange(8, 19);
+ ih.indent();
+ expect(element.value).toBe(' foo\n bar\n baz');
+ expect(element.selection()).toEqual([8, 27]);
+ });
+
+ it('having different indentation when some lines are partially selected; and the selection adapts', () => {
+ element.value = ' foo\nbar\n baz';
+ element.setSelectionRange(9, 14);
+ ih.indent();
+ expect(element.value).toBe(' foo\n bar\n baz');
+ expect(element.selection()).toEqual([13, 22]);
+ });
+ });
+ });
+
+ describe('unindents', () => {
+ describe('a single line', () => {
+ it('but does nothing if there is not indent', () => {
+ element.value = 'foobar';
+ element.setCursor(2);
+ ih.unindent();
+ expect(element.value).toBe('foobar');
+ expect(element.cursor()).toBe(2);
+ });
+
+ it('but does nothing if there is a partial indent', () => {
+ element.value = ' foobar';
+ element.setCursor(1);
+ ih.unindent();
+ expect(element.value).toBe(' foobar');
+ expect(element.cursor()).toBe(1);
+ });
+
+ it('when the cursor is in the line text; cursor follows', () => {
+ element.value = ' foobar';
+ element.setCursor(6);
+ ih.unindent();
+ expect(element.value).toBe('foobar');
+ expect(element.cursor()).toBe(2);
+ });
+
+ it('when the cursor is in the indent; and cursor goes to start', () => {
+ element.value = ' foobar';
+ element.setCursor(2);
+ ih.unindent();
+ expect(element.value).toBe('foobar');
+ expect(element.cursor()).toBe(0);
+ });
+
+ it('when the cursor is at line start; and cursor stays at start', () => {
+ element.value = ' foobar';
+ element.setCursor(0);
+ ih.unindent();
+ expect(element.value).toBe('foobar');
+ expect(element.cursor()).toBe(0);
+ });
+
+ it('when a selection includes part of the indent and text', () => {
+ element.value = ' foobar';
+ element.setSelectionRange(2, 8);
+ ih.unindent();
+ expect(element.value).toBe('foobar');
+ expect(element.selection()).toEqual([0, 4]);
+ });
+
+ it('when a selection includes part of the indent only', () => {
+ element.value = ' foobar';
+ element.setSelectionRange(0, 4);
+ ih.unindent();
+ expect(element.value).toBe('foobar');
+ expect(element.cursor()).toBe(0);
+
+ element.value = ' foobar';
+ element.setSelectionRange(1, 3);
+ ih.unindent();
+ expect(element.value).toBe('foobar');
+ expect(element.cursor()).toBe(0);
+ });
+ });
+
+ describe('several lines', () => {
+ it('when everything is selected', () => {
+ element.value = ' foo\n bar\n baz';
+ element.setSelectionRange(0, 27);
+ ih.unindent();
+ expect(element.value).toBe('foo\n bar\nbaz');
+ expect(element.selection()).toEqual([0, 15]);
+ });
+
+ it('when all lines are partially selected', () => {
+ element.value = ' foo\n bar\n baz';
+ element.setSelectionRange(5, 26);
+ ih.unindent();
+ expect(element.value).toBe('foo\n bar\nbaz');
+ expect(element.selection()).toEqual([1, 14]);
+ });
+
+ it('when all lines are entirely selected', () => {
+ element.value = ' foo\n bar\n baz';
+ element.setSelectionRange(8, 27);
+ ih.unindent();
+ expect(element.value).toBe(' foo\n bar\nbaz');
+ expect(element.selection()).toEqual([8, 19]);
+ });
+
+ it('when some lines are entirely selected', () => {
+ element.value = ' foo\n bar\n baz';
+ element.setSelectionRange(8, 27);
+ ih.unindent();
+ expect(element.value).toBe(' foo\n bar\nbaz');
+ expect(element.selection()).toEqual([8, 19]);
+ });
+
+ it('when some lines are partially selected', () => {
+ element.value = ' foo\n bar\n baz';
+ element.setSelectionRange(17, 26);
+ ih.unindent();
+ expect(element.value).toBe(' foo\n bar\nbaz');
+ expect(element.selection()).toEqual([13, 18]);
+ });
+
+ it('when some lines are partially selected within their indents', () => {
+ element.value = ' foo\n bar\n baz';
+ element.setSelectionRange(10, 22);
+ ih.unindent();
+ expect(element.value).toBe(' foo\n bar\nbaz');
+ expect(element.selection()).toEqual([8, 16]);
+ });
+ });
+ });
+
+ describe('newline', () => {
+ describe('on a single line', () => {
+ it('auto-indents the new line', () => {
+ element.value = 'foo\n bar\n baz\n qux';
+
+ element.setCursor(3);
+ ih.newline();
+ expect(element.value).toBe('foo\n\n bar\n baz\n qux');
+ expect(element.cursor()).toBe(4);
+
+ element.setCursor(9);
+ ih.newline();
+ expect(element.value).toBe('foo\n\n bar\n \n baz\n qux');
+ expect(element.cursor()).toBe(11);
+
+ element.setCursor(19);
+ ih.newline();
+ expect(element.value).toBe('foo\n\n bar\n \n baz\n \n qux');
+ expect(element.cursor()).toBe(24);
+
+ element.setCursor(36);
+ ih.newline();
+ expect(element.value).toBe('foo\n\n bar\n \n baz\n \n qux\n ');
+ expect(element.cursor()).toBe(45);
+ });
+
+ it('splits a line and auto-indents', () => {
+ element.value = ' foobar';
+ element.setCursor(7);
+ ih.newline();
+ expect(element.value).toBe(' foo\n bar');
+ expect(element.cursor()).toBe(12);
+ });
+
+ it('replaces selection with an indented newline', () => {
+ element.value = ' foobarbaz';
+ element.setSelectionRange(7, 10);
+ ih.newline();
+ expect(element.value).toBe(' foo\n baz');
+ expect(element.cursor()).toBe(12);
+ });
+ });
+
+ it('on several lines.replaces selection with indented newline', () => {
+ element.value = ' foo\n bar\n baz';
+ element.setSelectionRange(4, 17);
+ ih.newline();
+ expect(element.value).toBe(' fo\n az');
+ expect(element.cursor()).toBe(7);
+ });
+ });
+
+ describe('backspace', () => {
+ let event;
+
+ // This suite tests only the special indent-removing behaviour of the
+ // backspace() method, since non-special cases are handled natively as a
+ // backspace keypress.
+
+ beforeEach(() => {
+ event = { preventDefault: jest.fn() };
+ });
+
+ describe('on a single line', () => {
+ it('does nothing special if in the line text', () => {
+ element.value = ' foobar';
+ element.setCursor(7);
+ ih.backspace(event);
+ expect(event.preventDefault).not.toHaveBeenCalled();
+ });
+
+ it('does nothing special if after a non-leading indent', () => {
+ element.value = ' foo bar';
+ element.setCursor(11);
+ ih.backspace(event);
+ expect(event.preventDefault).not.toHaveBeenCalled();
+ });
+
+ it('deletes one leading indent', () => {
+ element.value = ' foo';
+ element.setCursor(8);
+ ih.backspace(event);
+ expect(event.preventDefault).toHaveBeenCalled();
+ expect(element.value).toBe(' foo');
+ expect(element.cursor()).toBe(4);
+ });
+
+ it('does nothing if cursor is inside the leading indent', () => {
+ element.value = ' foo';
+ element.setCursor(4);
+ ih.backspace(event);
+ expect(event.preventDefault).not.toHaveBeenCalled();
+ });
+
+ it('does nothing if cursor is at the start of the line', () => {
+ element.value = ' foo';
+ element.setCursor(0);
+ ih.backspace(event);
+ expect(event.preventDefault).not.toHaveBeenCalled();
+ });
+
+ it('deletes one partial indent', () => {
+ element.value = ' foo';
+ element.setCursor(6);
+ ih.backspace(event);
+ expect(event.preventDefault).toHaveBeenCalled();
+ expect(element.value).toBe(' foo');
+ expect(element.cursor()).toBe(4);
+ });
+
+ it('deletes indents sequentially', () => {
+ element.value = ' foo';
+ element.setCursor(10);
+ ih.backspace(event);
+ ih.backspace(event);
+ ih.backspace(event);
+ expect(event.preventDefault).toHaveBeenCalled();
+ expect(element.value).toBe('foo');
+ expect(element.cursor()).toBe(0);
+ });
+ });
+
+ describe('on several lines', () => {
+ it('deletes indent only on its own line', () => {
+ element.value = ' foo\n bar\n baz';
+ element.setCursor(16);
+ ih.backspace(event);
+ expect(event.preventDefault).toHaveBeenCalled();
+ expect(element.value).toBe(' foo\n bar\n baz');
+ expect(element.cursor()).toBe(12);
+ });
+
+ it('has no special behaviour with any range selection', () => {
+ const text = ' foo\n bar\n baz';
+ for (let start = 0; start < text.length; start += 1) {
+ for (let end = start + 1; end < text.length; end += 1) {
+ element.value = text;
+ element.setSelectionRange(start, end);
+ ih.backspace(event);
+ expect(event.preventDefault).not.toHaveBeenCalled();
+
+ // Ensure that the backspace() method doesn't change state
+ // In reality, these two statements won't hold because the browser
+ // will natively process the backspace event.
+ expect(element.value).toBe(text);
+ expect(element.selection()).toEqual([start, end]);
+ }
+ }
+ });
+ });
+ });
+});
diff --git a/spec/frontend/lib/utils/common_utils_spec.js b/spec/frontend/lib/utils/common_utils_spec.js
new file mode 100644
index 00000000000..e3d3b82d2f3
--- /dev/null
+++ b/spec/frontend/lib/utils/common_utils_spec.js
@@ -0,0 +1,180 @@
+import * as cu from '~/lib/utils/common_utils';
+
+const CMD_ENTITY = '&#8984;';
+
+// Redefine `navigator.platform` because it's unsettable by default in JSDOM.
+let platform;
+Object.defineProperty(navigator, 'platform', {
+ configurable: true,
+ get: () => platform,
+ set: val => {
+ platform = val;
+ },
+});
+
+describe('common_utils', () => {
+ describe('platform leader key helpers', () => {
+ const CTRL_EVENT = { ctrlKey: true };
+ const META_EVENT = { metaKey: true };
+ const BOTH_EVENT = { ctrlKey: true, metaKey: true };
+
+ it('should return "ctrl" if navigator.platform is unset', () => {
+ expect(cu.getPlatformLeaderKey()).toBe('ctrl');
+ expect(cu.getPlatformLeaderKeyHTML()).toBe('Ctrl');
+ expect(cu.isPlatformLeaderKey(CTRL_EVENT)).toBe(true);
+ expect(cu.isPlatformLeaderKey(META_EVENT)).toBe(false);
+ expect(cu.isPlatformLeaderKey(BOTH_EVENT)).toBe(true);
+ });
+
+ it('should return "meta" on MacOS', () => {
+ navigator.platform = 'MacIntel';
+ expect(cu.getPlatformLeaderKey()).toBe('meta');
+ expect(cu.getPlatformLeaderKeyHTML()).toBe(CMD_ENTITY);
+ expect(cu.isPlatformLeaderKey(CTRL_EVENT)).toBe(false);
+ expect(cu.isPlatformLeaderKey(META_EVENT)).toBe(true);
+ expect(cu.isPlatformLeaderKey(BOTH_EVENT)).toBe(true);
+ });
+
+ it('should return "ctrl" on Linux', () => {
+ navigator.platform = 'Linux is great';
+ expect(cu.getPlatformLeaderKey()).toBe('ctrl');
+ expect(cu.getPlatformLeaderKeyHTML()).toBe('Ctrl');
+ expect(cu.isPlatformLeaderKey(CTRL_EVENT)).toBe(true);
+ expect(cu.isPlatformLeaderKey(META_EVENT)).toBe(false);
+ expect(cu.isPlatformLeaderKey(BOTH_EVENT)).toBe(true);
+ });
+
+ it('should return "ctrl" on Windows', () => {
+ navigator.platform = 'Win32';
+ expect(cu.getPlatformLeaderKey()).toBe('ctrl');
+ expect(cu.getPlatformLeaderKeyHTML()).toBe('Ctrl');
+ expect(cu.isPlatformLeaderKey(CTRL_EVENT)).toBe(true);
+ expect(cu.isPlatformLeaderKey(META_EVENT)).toBe(false);
+ expect(cu.isPlatformLeaderKey(BOTH_EVENT)).toBe(true);
+ });
+ });
+
+ describe('keystroke', () => {
+ const CODE_BACKSPACE = 8;
+ const CODE_TAB = 9;
+ const CODE_ENTER = 13;
+ const CODE_SPACE = 32;
+ const CODE_4 = 52;
+ const CODE_F = 70;
+ const CODE_Z = 90;
+
+ // Helper function that quickly creates KeyboardEvents
+ const k = (code, modifiers = '') => ({
+ keyCode: code,
+ which: code,
+ altKey: modifiers.includes('a'),
+ ctrlKey: modifiers.includes('c'),
+ metaKey: modifiers.includes('m'),
+ shiftKey: modifiers.includes('s'),
+ });
+
+ const EV_F = k(CODE_F);
+ const EV_ALT_F = k(CODE_F, 'a');
+ const EV_CONTROL_F = k(CODE_F, 'c');
+ const EV_META_F = k(CODE_F, 'm');
+ const EV_SHIFT_F = k(CODE_F, 's');
+ const EV_CONTROL_SHIFT_F = k(CODE_F, 'cs');
+ const EV_ALL_F = k(CODE_F, 'scma');
+ const EV_ENTER = k(CODE_ENTER);
+ const EV_TAB = k(CODE_TAB);
+ const EV_SPACE = k(CODE_SPACE);
+ const EV_BACKSPACE = k(CODE_BACKSPACE);
+ const EV_4 = k(CODE_4);
+ const EV_$ = k(CODE_4, 's');
+
+ const { keystroke } = cu;
+
+ it('short-circuits with bad arguments', () => {
+ expect(keystroke()).toBe(false);
+ expect(keystroke({})).toBe(false);
+ });
+
+ it('handles keystrokes using key codes', () => {
+ // Test a letter key with modifiers
+ expect(keystroke(EV_F, CODE_F)).toBe(true);
+ expect(keystroke(EV_F, CODE_F, '')).toBe(true);
+ expect(keystroke(EV_ALT_F, CODE_F, 'a')).toBe(true);
+ expect(keystroke(EV_CONTROL_F, CODE_F, 'c')).toBe(true);
+ expect(keystroke(EV_META_F, CODE_F, 'm')).toBe(true);
+ expect(keystroke(EV_SHIFT_F, CODE_F, 's')).toBe(true);
+ expect(keystroke(EV_CONTROL_SHIFT_F, CODE_F, 'cs')).toBe(true);
+ expect(keystroke(EV_ALL_F, CODE_F, 'acms')).toBe(true);
+
+ // Test non-letter keys
+ expect(keystroke(EV_TAB, CODE_TAB)).toBe(true);
+ expect(keystroke(EV_ENTER, CODE_ENTER)).toBe(true);
+ expect(keystroke(EV_SPACE, CODE_SPACE)).toBe(true);
+ expect(keystroke(EV_BACKSPACE, CODE_BACKSPACE)).toBe(true);
+
+ // Test a number/symbol key
+ expect(keystroke(EV_4, CODE_4)).toBe(true);
+ expect(keystroke(EV_$, CODE_4, 's')).toBe(true);
+
+ // Test wrong input
+ expect(keystroke(EV_F, CODE_Z)).toBe(false);
+ expect(keystroke(EV_SHIFT_F, CODE_F)).toBe(false);
+ expect(keystroke(EV_SHIFT_F, CODE_F, 'c')).toBe(false);
+ });
+
+ it('is case-insensitive', () => {
+ expect(keystroke(EV_ALL_F, CODE_F, 'ACMS')).toBe(true);
+ });
+
+ it('handles bogus inputs', () => {
+ expect(keystroke(EV_F, 'not a keystroke')).toBe(false);
+ expect(keystroke(EV_F, null)).toBe(false);
+ });
+
+ it('handles exact modifier keys, in any order', () => {
+ // Test permutations of modifiers
+ expect(keystroke(EV_ALL_F, CODE_F, 'acms')).toBe(true);
+ expect(keystroke(EV_ALL_F, CODE_F, 'smca')).toBe(true);
+ expect(keystroke(EV_ALL_F, CODE_F, 'csma')).toBe(true);
+ expect(keystroke(EV_CONTROL_SHIFT_F, CODE_F, 'cs')).toBe(true);
+ expect(keystroke(EV_CONTROL_SHIFT_F, CODE_F, 'sc')).toBe(true);
+
+ // Test wrong modifiers
+ expect(keystroke(EV_ALL_F, CODE_F, 'smca')).toBe(true);
+ expect(keystroke(EV_ALL_F, CODE_F)).toBe(false);
+ expect(keystroke(EV_ALL_F, CODE_F, '')).toBe(false);
+ expect(keystroke(EV_ALL_F, CODE_F, 'c')).toBe(false);
+ expect(keystroke(EV_ALL_F, CODE_F, 'ca')).toBe(false);
+ expect(keystroke(EV_ALL_F, CODE_F, 'ms')).toBe(false);
+ expect(keystroke(EV_CONTROL_SHIFT_F, CODE_F, 'cs')).toBe(true);
+ expect(keystroke(EV_CONTROL_SHIFT_F, CODE_F, 'c')).toBe(false);
+ expect(keystroke(EV_CONTROL_SHIFT_F, CODE_F, 's')).toBe(false);
+ expect(keystroke(EV_CONTROL_SHIFT_F, CODE_F, 'csa')).toBe(false);
+ expect(keystroke(EV_CONTROL_SHIFT_F, CODE_F, 'm')).toBe(false);
+ expect(keystroke(EV_SHIFT_F, CODE_F, 's')).toBe(true);
+ expect(keystroke(EV_SHIFT_F, CODE_F, 'c')).toBe(false);
+ expect(keystroke(EV_SHIFT_F, CODE_F, 'csm')).toBe(false);
+ });
+
+ it('handles the platform-dependent leader key', () => {
+ navigator.platform = 'Win32';
+ let EV_UNDO = k(CODE_Z, 'c');
+ let EV_REDO = k(CODE_Z, 'cs');
+ expect(keystroke(EV_UNDO, CODE_Z, 'l')).toBe(true);
+ expect(keystroke(EV_UNDO, CODE_Z, 'c')).toBe(true);
+ expect(keystroke(EV_UNDO, CODE_Z, 'm')).toBe(false);
+ expect(keystroke(EV_REDO, CODE_Z, 'sl')).toBe(true);
+ expect(keystroke(EV_REDO, CODE_Z, 'sc')).toBe(true);
+ expect(keystroke(EV_REDO, CODE_Z, 'sm')).toBe(false);
+
+ navigator.platform = 'MacIntel';
+ EV_UNDO = k(CODE_Z, 'm');
+ EV_REDO = k(CODE_Z, 'ms');
+ expect(keystroke(EV_UNDO, CODE_Z, 'l')).toBe(true);
+ expect(keystroke(EV_UNDO, CODE_Z, 'c')).toBe(false);
+ expect(keystroke(EV_UNDO, CODE_Z, 'm')).toBe(true);
+ expect(keystroke(EV_REDO, CODE_Z, 'sl')).toBe(true);
+ expect(keystroke(EV_REDO, CODE_Z, 'sc')).toBe(false);
+ expect(keystroke(EV_REDO, CODE_Z, 'sm')).toBe(true);
+ });
+ });
+});
diff --git a/spec/frontend/lib/utils/undo_stack_spec.js b/spec/frontend/lib/utils/undo_stack_spec.js
new file mode 100644
index 00000000000..31ad0e77d6f
--- /dev/null
+++ b/spec/frontend/lib/utils/undo_stack_spec.js
@@ -0,0 +1,237 @@
+import UndoStack from '~/lib/utils/undo_stack';
+
+import { isEqual } from 'underscore';
+
+describe('UndoStack', () => {
+ let stack;
+
+ beforeEach(() => {
+ stack = new UndoStack();
+ });
+
+ afterEach(() => {
+ // Make sure there's not pending saves
+ const history = Array.from(stack.history);
+ jest.runAllTimers();
+ expect(stack.history).toEqual(history);
+ });
+
+ it('is blank on construction', () => {
+ expect(stack.isEmpty()).toBe(true);
+ expect(stack.history).toEqual([]);
+ expect(stack.cursor).toBe(-1);
+ expect(stack.canUndo()).toBe(false);
+ expect(stack.canRedo()).toBe(false);
+ });
+
+ it('handles simple undo/redo behaviour', () => {
+ stack.save(10);
+ stack.save(11);
+ stack.save(12);
+
+ expect(stack.history).toEqual([10, 11, 12]);
+ expect(stack.cursor).toBe(2);
+ expect(stack.current()).toBe(12);
+ expect(stack.isEmpty()).toBe(false);
+ expect(stack.canUndo()).toBe(true);
+ expect(stack.canRedo()).toBe(false);
+
+ stack.undo();
+ expect(stack.history).toEqual([10, 11, 12]);
+ expect(stack.current()).toBe(11);
+ expect(stack.canUndo()).toBe(true);
+ expect(stack.canRedo()).toBe(true);
+
+ stack.undo();
+ expect(stack.current()).toBe(10);
+ expect(stack.canUndo()).toBe(false);
+ expect(stack.canRedo()).toBe(true);
+
+ stack.redo();
+ expect(stack.current()).toBe(11);
+
+ stack.redo();
+ expect(stack.current()).toBe(12);
+ expect(stack.isEmpty()).toBe(false);
+ expect(stack.canUndo()).toBe(true);
+ expect(stack.canRedo()).toBe(false);
+
+ // Saving should clear the redo stack
+ stack.undo();
+ stack.save(13);
+ expect(stack.history).toEqual([10, 11, 13]);
+ expect(stack.current()).toBe(13);
+ });
+
+ it('clear() should clear the undo history', () => {
+ stack.save(0);
+ stack.save(1);
+ stack.save(2);
+ stack.clear();
+ expect(stack.history).toEqual([]);
+ expect(stack.current()).toBeUndefined();
+ });
+
+ it('undo and redo are no-ops if unavailable', () => {
+ stack.save(10);
+ expect(stack.canRedo()).toBe(false);
+ expect(stack.canUndo()).toBe(false);
+
+ stack.save(11);
+ expect(stack.canRedo()).toBe(false);
+ expect(stack.canUndo()).toBe(true);
+
+ expect(stack.redo()).toBeUndefined();
+ expect(stack.history).toEqual([10, 11]);
+ expect(stack.current()).toBe(11);
+ expect(stack.canRedo()).toBe(false);
+ expect(stack.canUndo()).toBe(true);
+
+ expect(stack.undo()).toBe(10);
+ expect(stack.undo()).toBeUndefined();
+ expect(stack.history).toEqual([10, 11]);
+ expect(stack.current()).toBe(10);
+ expect(stack.canRedo()).toBe(true);
+ expect(stack.canUndo()).toBe(false);
+ });
+
+ it('should not save a duplicate state', () => {
+ stack.save(10);
+ stack.save(11);
+ stack.save(11);
+ stack.save(10);
+ stack.save(10);
+
+ expect(stack.history).toEqual([10, 11, 10]);
+ });
+
+ it('uses the === operator to detect duplicates', () => {
+ stack.save(10);
+ stack.save(10);
+ expect(stack.history).toEqual([10]);
+
+ // eslint-disable-next-line eqeqeq
+ expect(2 == '2' && '2' == 2).toBe(true);
+ stack.clear();
+ stack.save(2);
+ stack.save(2);
+ stack.save('2');
+ stack.save('2');
+ stack.save(2);
+ expect(stack.history).toEqual([2, '2', 2]);
+
+ const obj = {};
+ stack.clear();
+ stack.save(obj);
+ stack.save(obj);
+ stack.save({});
+ stack.save({});
+ expect(stack.history).toEqual([{}, {}, {}]);
+ });
+
+ it('should allow custom comparators', () => {
+ stack.comparator = isEqual;
+ const obj = {};
+ stack.clear();
+ stack.save(obj);
+ stack.save(obj);
+ stack.save({});
+ stack.save({});
+ expect(stack.history).toEqual([{}]);
+ });
+
+ it('should enforce a max number of undo states', () => {
+ // Try 2000 saves. Only the last 1000 should be preserved.
+ const sequence = Array(2000)
+ .fill(0)
+ .map((el, i) => i);
+ sequence.forEach(stack.save.bind(stack));
+ expect(stack.history.length).toBe(1000);
+ expect(stack.history).toEqual(sequence.slice(1000));
+ expect(stack.current()).toBe(1999);
+ expect(stack.canUndo()).toBe(true);
+ expect(stack.canRedo()).toBe(false);
+
+ // Saving drops the oldest elements from the stack
+ stack.save('end');
+ expect(stack.history.length).toBe(1000);
+ expect(stack.current()).toBe('end');
+ expect(stack.history).toEqual([...sequence.slice(1001), 'end']);
+
+ // If states were undone but the history is full, can still add.
+ stack.undo();
+ stack.undo();
+ expect(stack.current()).toBe(1998);
+ stack.save(3000);
+ expect(stack.history.length).toBe(999);
+ // should be [1001, 1002, ..., 1998, 3000]
+ expect(stack.history).toEqual([...sequence.slice(1001, 1999), 3000]);
+
+ // Try a different max length
+ stack = new UndoStack(2);
+ stack.save(0);
+ expect(stack.history).toEqual([0]);
+ stack.save(1);
+ expect(stack.history).toEqual([0, 1]);
+ stack.save(2);
+ expect(stack.history).toEqual([1, 2]);
+ });
+
+ describe('scheduled saves', () => {
+ it('should work', () => {
+ // Schedules 1000 ms ahead by default
+ stack.save(0);
+ stack.scheduleSave(1);
+ expect(stack.history).toEqual([0]);
+ jest.advanceTimersByTime(999);
+ expect(stack.history).toEqual([0]);
+ jest.advanceTimersByTime(1);
+ expect(stack.history).toEqual([0, 1]);
+ });
+
+ it('should have an adjustable delay', () => {
+ stack.scheduleSave(2, 100);
+ jest.advanceTimersByTime(100);
+ expect(stack.history).toEqual([2]);
+ });
+
+ it('should cancel previous scheduled saves', () => {
+ stack.scheduleSave(3);
+ jest.advanceTimersByTime(100);
+ stack.scheduleSave(4);
+ jest.runAllTimers();
+ expect(stack.history).toEqual([4]);
+ });
+
+ it('should be canceled by explicit saves', () => {
+ stack.scheduleSave(5);
+ stack.save(6);
+ jest.runAllTimers();
+ expect(stack.history).toEqual([6]);
+ });
+
+ it('should be canceled by undos and redos', () => {
+ stack.save(1);
+ stack.save(2);
+ stack.scheduleSave(3);
+ stack.undo();
+ jest.runAllTimers();
+ expect(stack.history).toEqual([1, 2]);
+ expect(stack.current()).toBe(1);
+
+ stack.scheduleSave(4);
+ stack.redo();
+ jest.runAllTimers();
+ expect(stack.history).toEqual([1, 2]);
+ expect(stack.current()).toBe(2);
+ });
+
+ it('should be persisted immediately with saveNow()', () => {
+ stack.scheduleSave(7);
+ stack.scheduleSave(8);
+ stack.saveNow();
+ jest.runAllTimers();
+ expect(stack.history).toEqual([8]);
+ });
+ });
+});
diff --git a/spec/graphql/resolvers/namespace_projects_resolver_spec.rb b/spec/graphql/resolvers/namespace_projects_resolver_spec.rb
index 20e197e9f73..47591445fc0 100644
--- a/spec/graphql/resolvers/namespace_projects_resolver_spec.rb
+++ b/spec/graphql/resolvers/namespace_projects_resolver_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Resolvers::NamespaceProjectsResolver, :nested_groups do
+describe Resolvers::NamespaceProjectsResolver do
include GraphqlHelpers
let(:current_user) { create(:user) }
diff --git a/spec/helpers/auto_devops_helper_spec.rb b/spec/helpers/auto_devops_helper_spec.rb
index d2540696b17..e80388f9ea7 100644
--- a/spec/helpers/auto_devops_helper_spec.rb
+++ b/spec/helpers/auto_devops_helper_spec.rb
@@ -118,7 +118,7 @@ describe AutoDevopsHelper do
it { is_expected.to eq('instance enabled') }
end
- context 'with groups', :nested_groups do
+ context 'with groups' do
before do
receiver.update(parent: parent)
end
@@ -170,7 +170,7 @@ describe AutoDevopsHelper do
it { is_expected.to eq('instance enabled') }
end
- context 'with groups', :nested_groups do
+ context 'with groups' do
let(:receiver) { create(:project, :repository, namespace: group) }
before do
@@ -203,7 +203,7 @@ describe AutoDevopsHelper do
it { is_expected.to be_nil }
end
- context 'with groups', :nested_groups do
+ context 'with groups' do
let(:receiver) { create(:project, :repository, namespace: group) }
context 'when auto devops is disabled on group level' do
diff --git a/spec/helpers/groups_helper_spec.rb b/spec/helpers/groups_helper_spec.rb
index 1763c46389a..037b16c90ed 100644
--- a/spec/helpers/groups_helper_spec.rb
+++ b/spec/helpers/groups_helper_spec.rb
@@ -86,7 +86,7 @@ describe GroupsHelper do
end
end
- describe 'group_title', :nested_groups do
+ describe 'group_title' do
let(:group) { create(:group) }
let(:nested_group) { create(:group, parent: group) }
let(:deep_nested_group) { create(:group, parent: nested_group) }
@@ -99,7 +99,7 @@ describe GroupsHelper do
end
# rubocop:disable Layout/SpaceBeforeComma
- describe '#share_with_group_lock_help_text', :nested_groups do
+ describe '#share_with_group_lock_help_text' do
let!(:root_group) { create(:group) }
let!(:subgroup) { create(:group, parent: root_group) }
let!(:sub_subgroup) { create(:group, parent: subgroup) }
@@ -230,7 +230,7 @@ describe GroupsHelper do
end
end
- describe 'parent_group_options', :nested_groups do
+ describe 'parent_group_options' do
let(:current_user) { create(:user) }
let(:group) { create(:group, name: 'group') }
let(:group2) { create(:group, name: 'group2') }
diff --git a/spec/helpers/namespaces_helper_spec.rb b/spec/helpers/namespaces_helper_spec.rb
index 601f864ef36..e38513f6d94 100644
--- a/spec/helpers/namespaces_helper_spec.rb
+++ b/spec/helpers/namespaces_helper_spec.rb
@@ -1,6 +1,6 @@
require 'spec_helper'
-describe NamespacesHelper, :postgresql do
+describe NamespacesHelper do
let!(:admin) { create(:admin) }
let!(:admin_project_creation_level) { nil }
let!(:admin_group) do
@@ -109,7 +109,7 @@ describe NamespacesHelper, :postgresql do
expect(options).to include(user_group.name)
end
- context 'when nested groups are available', :nested_groups do
+ context 'when nested groups are available' do
it 'includes groups nested in groups the user can administer' do
allow(helper).to receive(:current_user).and_return(user)
child_group = create(:group, :private, parent: user_group)
diff --git a/spec/helpers/submodule_helper_spec.rb b/spec/helpers/submodule_helper_spec.rb
index b922b910c89..ab4ef899119 100644
--- a/spec/helpers/submodule_helper_spec.rb
+++ b/spec/helpers/submodule_helper_spec.rb
@@ -229,6 +229,19 @@ describe SubmoduleHelper do
end
end
end
+
+ context 'unknown submodule' do
+ before do
+ # When there is no `.gitmodules` file, or if `.gitmodules` does not
+ # know the submodule at the specified path,
+ # `Repository#submodule_url_for` returns `nil`
+ stub_url(nil)
+ end
+
+ it 'returns no links' do
+ expect(subject).to eq([nil, nil])
+ end
+ end
end
context 'as view helpers in view context' do
diff --git a/spec/javascripts/badges/components/badge_list_spec.js b/spec/javascripts/badges/components/badge_list_spec.js
index 2f72c9ed89d..2fa807657de 100644
--- a/spec/javascripts/badges/components/badge_list_spec.js
+++ b/spec/javascripts/badges/components/badge_list_spec.js
@@ -60,7 +60,7 @@ describe('BadgeList component', () => {
Vue.nextTick()
.then(() => {
- const loadingIcon = vm.$el.querySelector('.spinner');
+ const loadingIcon = vm.$el.querySelector('.gl-spinner');
expect(loadingIcon).toBeVisible();
})
diff --git a/spec/javascripts/badges/components/badge_spec.js b/spec/javascripts/badges/components/badge_spec.js
index 4e4d1ae2e99..c82a03a628a 100644
--- a/spec/javascripts/badges/components/badge_spec.js
+++ b/spec/javascripts/badges/components/badge_spec.js
@@ -15,7 +15,7 @@ describe('Badge component', () => {
const buttons = vm.$el.querySelectorAll('button');
return {
badgeImage: vm.$el.querySelector('img.project-badge'),
- loadingIcon: vm.$el.querySelector('.spinner'),
+ loadingIcon: vm.$el.querySelector('.gl-spinner'),
reloadButton: buttons[buttons.length - 1],
};
};
diff --git a/spec/javascripts/boards/board_list_spec.js b/spec/javascripts/boards/board_list_spec.js
index 9c9b435d7fd..6774a46ed58 100644
--- a/spec/javascripts/boards/board_list_spec.js
+++ b/spec/javascripts/boards/board_list_spec.js
@@ -148,7 +148,7 @@ describe('Board list component', () => {
component.list.loadingMore = true;
Vue.nextTick(() => {
- expect(component.$el.querySelector('.board-list-count .spinner')).not.toBeNull();
+ expect(component.$el.querySelector('.board-list-count .gl-spinner')).not.toBeNull();
done();
});
diff --git a/spec/javascripts/registry/components/app_spec.js b/spec/javascripts/registry/components/app_spec.js
index 7b9b8d2b039..e7675669f7a 100644
--- a/spec/javascripts/registry/components/app_spec.js
+++ b/spec/javascripts/registry/components/app_spec.js
@@ -106,7 +106,7 @@ describe('Registry List', () => {
it('should render a loading spinner', done => {
Vue.nextTick(() => {
- expect(vm.$el.querySelector('.spinner')).not.toBe(null);
+ expect(vm.$el.querySelector('.gl-spinner')).not.toBe(null);
done();
});
});
diff --git a/spec/javascripts/reports/components/grouped_test_reports_app_spec.js b/spec/javascripts/reports/components/grouped_test_reports_app_spec.js
index a17494966a3..1f1e626ed33 100644
--- a/spec/javascripts/reports/components/grouped_test_reports_app_spec.js
+++ b/spec/javascripts/reports/components/grouped_test_reports_app_spec.js
@@ -34,7 +34,7 @@ describe('Grouped Test Reports App', () => {
it('renders success summary text', done => {
setTimeout(() => {
- expect(vm.$el.querySelector('.fa-spinner')).toBeNull();
+ expect(vm.$el.querySelector('.gl-spinner')).toBeNull();
expect(vm.$el.querySelector('.js-code-text').textContent.trim()).toEqual(
'Test summary contained no changed test results out of 11 total tests',
);
@@ -61,7 +61,7 @@ describe('Grouped Test Reports App', () => {
it('renders success summary text', done => {
setTimeout(() => {
- expect(vm.$el.querySelector('.spinner')).not.toBeNull();
+ expect(vm.$el.querySelector('.gl-spinner')).not.toBeNull();
expect(vm.$el.querySelector('.js-code-text').textContent.trim()).toEqual(
'Test summary results are being parsed',
);
@@ -81,7 +81,7 @@ describe('Grouped Test Reports App', () => {
it('renders failed summary text + new badge', done => {
setTimeout(() => {
- expect(vm.$el.querySelector('.spinner')).toBeNull();
+ expect(vm.$el.querySelector('.gl-spinner')).toBeNull();
expect(vm.$el.querySelector('.js-code-text').textContent.trim()).toEqual(
'Test summary contained 2 failed test results out of 11 total tests',
);
@@ -109,7 +109,7 @@ describe('Grouped Test Reports App', () => {
it('renders summary text', done => {
setTimeout(() => {
- expect(vm.$el.querySelector('.spinner')).toBeNull();
+ expect(vm.$el.querySelector('.gl-spinner')).toBeNull();
expect(vm.$el.querySelector('.js-code-text').textContent.trim()).toEqual(
'Test summary contained 2 failed test results and 2 fixed test results out of 11 total tests',
);
@@ -137,7 +137,7 @@ describe('Grouped Test Reports App', () => {
it('renders summary text', done => {
setTimeout(() => {
- expect(vm.$el.querySelector('.spinner')).toBeNull();
+ expect(vm.$el.querySelector('.gl-spinner')).toBeNull();
expect(vm.$el.querySelector('.js-code-text').textContent.trim()).toEqual(
'Test summary contained 2 fixed test results out of 11 total tests',
);
@@ -190,7 +190,7 @@ describe('Grouped Test Reports App', () => {
});
it('renders loading summary text with loading icon', done => {
- expect(vm.$el.querySelector('.spinner')).not.toBeNull();
+ expect(vm.$el.querySelector('.gl-spinner')).not.toBeNull();
expect(vm.$el.querySelector('.js-code-text').textContent.trim()).toEqual(
'Test summary results are being parsed',
);
diff --git a/spec/javascripts/vue_mr_widget/components/mr_widget_status_icon_spec.js b/spec/javascripts/vue_mr_widget/components/mr_widget_status_icon_spec.js
index f622f52a7b9..5aac37d28df 100644
--- a/spec/javascripts/vue_mr_widget/components/mr_widget_status_icon_spec.js
+++ b/spec/javascripts/vue_mr_widget/components/mr_widget_status_icon_spec.js
@@ -18,7 +18,7 @@ describe('MR widget status icon component', () => {
it('renders loading icon', () => {
vm = mountComponent(Component, { status: 'loading' });
- expect(vm.$el.querySelector('.mr-widget-icon span').classList).toContain('spinner');
+ expect(vm.$el.querySelector('.mr-widget-icon span').classList).toContain('gl-spinner');
});
});
diff --git a/spec/javascripts/vue_mr_widget/components/states/mr_widget_auto_merge_failed_spec.js b/spec/javascripts/vue_mr_widget/components/states/mr_widget_auto_merge_failed_spec.js
index d93badf8cd3..55a11a72551 100644
--- a/spec/javascripts/vue_mr_widget/components/states/mr_widget_auto_merge_failed_spec.js
+++ b/spec/javascripts/vue_mr_widget/components/states/mr_widget_auto_merge_failed_spec.js
@@ -38,7 +38,9 @@ describe('MRWidgetAutoMergeFailed', () => {
Vue.nextTick(() => {
expect(vm.$el.querySelector('button').getAttribute('disabled')).toEqual('disabled');
- expect(vm.$el.querySelector('button .loading-container span').classList).toContain('spinner');
+ expect(vm.$el.querySelector('button .loading-container span').classList).toContain(
+ 'gl-spinner',
+ );
done();
});
});
diff --git a/spec/javascripts/vue_mr_widget/components/states/mr_widget_checking_spec.js b/spec/javascripts/vue_mr_widget/components/states/mr_widget_checking_spec.js
index 96e512d222a..70c70eca746 100644
--- a/spec/javascripts/vue_mr_widget/components/states/mr_widget_checking_spec.js
+++ b/spec/javascripts/vue_mr_widget/components/states/mr_widget_checking_spec.js
@@ -20,7 +20,7 @@ describe('MRWidgetChecking', () => {
});
it('renders loading icon', () => {
- expect(vm.$el.querySelector('.mr-widget-icon span').classList).toContain('spinner');
+ expect(vm.$el.querySelector('.mr-widget-icon span').classList).toContain('gl-spinner');
});
it('renders information about merging', () => {
diff --git a/spec/javascripts/vue_shared/components/file_icon_spec.js b/spec/javascripts/vue_shared/components/file_icon_spec.js
index 5bea8c43da3..1f61e19fa84 100644
--- a/spec/javascripts/vue_shared/components/file_icon_spec.js
+++ b/spec/javascripts/vue_shared/components/file_icon_spec.js
@@ -72,7 +72,7 @@ describe('File Icon component', () => {
const { classList } = vm.$el.querySelector('.loading-container span');
- expect(classList.contains('spinner')).toEqual(true);
+ expect(classList.contains('gl-spinner')).toEqual(true);
});
it('should add a special class and a size class', () => {
diff --git a/spec/javascripts/vue_shared/components/header_ci_component_spec.js b/spec/javascripts/vue_shared/components/header_ci_component_spec.js
index a9c1a67b39b..2b059e5e9f4 100644
--- a/spec/javascripts/vue_shared/components/header_ci_component_spec.js
+++ b/spec/javascripts/vue_shared/components/header_ci_component_spec.js
@@ -88,7 +88,7 @@ describe('Header CI Component', () => {
vm.actions[0].isLoading = true;
Vue.nextTick(() => {
- expect(vm.$el.querySelector('.btn .spinner').getAttribute('style')).toBeFalsy();
+ expect(vm.$el.querySelector('.btn .gl-spinner').getAttribute('style')).toBeFalsy();
done();
});
});
diff --git a/spec/lib/after_commit_queue_spec.rb b/spec/lib/after_commit_queue_spec.rb
index 6e7c2ec2363..8e9dfd90338 100644
--- a/spec/lib/after_commit_queue_spec.rb
+++ b/spec/lib/after_commit_queue_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe AfterCommitQueue do
diff --git a/spec/lib/api/api_spec.rb b/spec/lib/api/api_spec.rb
index ceef0b41e59..c83d068ca50 100644
--- a/spec/lib/api/api_spec.rb
+++ b/spec/lib/api/api_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe API::API do
diff --git a/spec/lib/api/helpers/custom_validators_spec.rb b/spec/lib/api/helpers/custom_validators_spec.rb
index aed86b21cb7..1ebce2ab5c4 100644
--- a/spec/lib/api/helpers/custom_validators_spec.rb
+++ b/spec/lib/api/helpers/custom_validators_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe API::Helpers::CustomValidators do
diff --git a/spec/lib/api/helpers/pagination_spec.rb b/spec/lib/api/helpers/pagination_spec.rb
index b0a00392957..b57adb46385 100644
--- a/spec/lib/api/helpers/pagination_spec.rb
+++ b/spec/lib/api/helpers/pagination_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe API::Helpers::Pagination do
diff --git a/spec/lib/api/helpers/related_resources_helpers_spec.rb b/spec/lib/api/helpers/related_resources_helpers_spec.rb
index 99fe8795d91..fb26cc417e8 100644
--- a/spec/lib/api/helpers/related_resources_helpers_spec.rb
+++ b/spec/lib/api/helpers/related_resources_helpers_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe API::Helpers::RelatedResourcesHelpers do
diff --git a/spec/lib/api/helpers/version_spec.rb b/spec/lib/api/helpers/version_spec.rb
index 34006e0930b..a9f33962537 100644
--- a/spec/lib/api/helpers/version_spec.rb
+++ b/spec/lib/api/helpers/version_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe API::Helpers::Version do
diff --git a/spec/lib/api/helpers_spec.rb b/spec/lib/api/helpers_spec.rb
index 00916f80784..0624c25e734 100644
--- a/spec/lib/api/helpers_spec.rb
+++ b/spec/lib/api/helpers_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe API::Helpers do
diff --git a/spec/lib/backup/files_spec.rb b/spec/lib/backup/files_spec.rb
index 63f2298357f..e903eada62d 100644
--- a/spec/lib/backup/files_spec.rb
+++ b/spec/lib/backup/files_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Backup::Files do
diff --git a/spec/lib/backup/manager_spec.rb b/spec/lib/backup/manager_spec.rb
index ae1c881e1f6..fee7ffc60ee 100644
--- a/spec/lib/backup/manager_spec.rb
+++ b/spec/lib/backup/manager_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Backup::Manager do
diff --git a/spec/lib/backup/repository_spec.rb b/spec/lib/backup/repository_spec.rb
index 5ace5c5b1a2..e1d46c25338 100644
--- a/spec/lib/backup/repository_spec.rb
+++ b/spec/lib/backup/repository_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Backup::Repository do
diff --git a/spec/lib/backup/uploads_spec.rb b/spec/lib/backup/uploads_spec.rb
index 544d3754c0f..55b69f29812 100644
--- a/spec/lib/backup/uploads_spec.rb
+++ b/spec/lib/backup/uploads_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Backup::Uploads do
diff --git a/spec/lib/banzai/color_parser_spec.rb b/spec/lib/banzai/color_parser_spec.rb
index af2a8f215c1..d9202ce77db 100644
--- a/spec/lib/banzai/color_parser_spec.rb
+++ b/spec/lib/banzai/color_parser_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Banzai::ColorParser do
diff --git a/spec/lib/banzai/commit_renderer_spec.rb b/spec/lib/banzai/commit_renderer_spec.rb
index 316dbf052c3..e5a16b167be 100644
--- a/spec/lib/banzai/commit_renderer_spec.rb
+++ b/spec/lib/banzai/commit_renderer_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Banzai::CommitRenderer do
diff --git a/spec/lib/banzai/cross_project_reference_spec.rb b/spec/lib/banzai/cross_project_reference_spec.rb
index ba995e16be7..cf41af7e7a1 100644
--- a/spec/lib/banzai/cross_project_reference_spec.rb
+++ b/spec/lib/banzai/cross_project_reference_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Banzai::CrossProjectReference do
diff --git a/spec/lib/banzai/filter/absolute_link_filter_spec.rb b/spec/lib/banzai/filter/absolute_link_filter_spec.rb
index 50be551cd90..b61bd496dba 100644
--- a/spec/lib/banzai/filter/absolute_link_filter_spec.rb
+++ b/spec/lib/banzai/filter/absolute_link_filter_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Banzai::Filter::AbsoluteLinkFilter do
diff --git a/spec/lib/banzai/filter/abstract_reference_filter_spec.rb b/spec/lib/banzai/filter/abstract_reference_filter_spec.rb
index 1e82d18d056..3e8b0ea113f 100644
--- a/spec/lib/banzai/filter/abstract_reference_filter_spec.rb
+++ b/spec/lib/banzai/filter/abstract_reference_filter_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Banzai::Filter::AbstractReferenceFilter do
diff --git a/spec/lib/banzai/filter/ascii_doc_post_processing_filter_spec.rb b/spec/lib/banzai/filter/ascii_doc_post_processing_filter_spec.rb
index 34f1657b6d3..bd06dae26ba 100644
--- a/spec/lib/banzai/filter/ascii_doc_post_processing_filter_spec.rb
+++ b/spec/lib/banzai/filter/ascii_doc_post_processing_filter_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Banzai::Filter::AsciiDocPostProcessingFilter do
diff --git a/spec/lib/banzai/filter/autolink_filter_spec.rb b/spec/lib/banzai/filter/autolink_filter_spec.rb
index 4972c4b4bd2..8fba72a23f6 100644
--- a/spec/lib/banzai/filter/autolink_filter_spec.rb
+++ b/spec/lib/banzai/filter/autolink_filter_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Banzai::Filter::AutolinkFilter do
diff --git a/spec/lib/banzai/filter/blockquote_fence_filter_spec.rb b/spec/lib/banzai/filter/blockquote_fence_filter_spec.rb
index 5b3f679084e..807f1b8bbd3 100644
--- a/spec/lib/banzai/filter/blockquote_fence_filter_spec.rb
+++ b/spec/lib/banzai/filter/blockquote_fence_filter_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'rails_helper'
describe Banzai::Filter::BlockquoteFenceFilter do
diff --git a/spec/lib/banzai/filter/color_filter_spec.rb b/spec/lib/banzai/filter/color_filter_spec.rb
index a098b037510..f8931d37b99 100644
--- a/spec/lib/banzai/filter/color_filter_spec.rb
+++ b/spec/lib/banzai/filter/color_filter_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Banzai::Filter::ColorFilter, lib: true do
diff --git a/spec/lib/banzai/filter/commit_range_reference_filter_spec.rb b/spec/lib/banzai/filter/commit_range_reference_filter_spec.rb
index 4daf6be1bb7..a82b890be42 100644
--- a/spec/lib/banzai/filter/commit_range_reference_filter_spec.rb
+++ b/spec/lib/banzai/filter/commit_range_reference_filter_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Banzai::Filter::CommitRangeReferenceFilter do
diff --git a/spec/lib/banzai/filter/commit_reference_filter_spec.rb b/spec/lib/banzai/filter/commit_reference_filter_spec.rb
index d6c9e9e4b19..1bc0335cfc0 100644
--- a/spec/lib/banzai/filter/commit_reference_filter_spec.rb
+++ b/spec/lib/banzai/filter/commit_reference_filter_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Banzai::Filter::CommitReferenceFilter do
diff --git a/spec/lib/banzai/filter/commit_trailers_filter_spec.rb b/spec/lib/banzai/filter/commit_trailers_filter_spec.rb
index 068cdc85a07..bcb74be1034 100644
--- a/spec/lib/banzai/filter/commit_trailers_filter_spec.rb
+++ b/spec/lib/banzai/filter/commit_trailers_filter_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
require 'ffaker'
diff --git a/spec/lib/banzai/filter/emoji_filter_spec.rb b/spec/lib/banzai/filter/emoji_filter_spec.rb
index 85a4619e33d..4e163668a28 100644
--- a/spec/lib/banzai/filter/emoji_filter_spec.rb
+++ b/spec/lib/banzai/filter/emoji_filter_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Banzai::Filter::EmojiFilter do
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 7c94cf37e32..78795a157f8 100644
--- a/spec/lib/banzai/filter/external_issue_reference_filter_spec.rb
+++ b/spec/lib/banzai/filter/external_issue_reference_filter_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Banzai::Filter::ExternalIssueReferenceFilter do
diff --git a/spec/lib/banzai/filter/external_link_filter_spec.rb b/spec/lib/banzai/filter/external_link_filter_spec.rb
index 2acbe05f082..59fea5766ee 100644
--- a/spec/lib/banzai/filter/external_link_filter_spec.rb
+++ b/spec/lib/banzai/filter/external_link_filter_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
shared_examples 'an external link with rel attribute' do
diff --git a/spec/lib/banzai/filter/front_matter_filter_spec.rb b/spec/lib/banzai/filter/front_matter_filter_spec.rb
index 3071dc7cf21..90b383dbcff 100644
--- a/spec/lib/banzai/filter/front_matter_filter_spec.rb
+++ b/spec/lib/banzai/filter/front_matter_filter_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'rails_helper'
describe Banzai::Filter::FrontMatterFilter do
diff --git a/spec/lib/banzai/filter/gollum_tags_filter_spec.rb b/spec/lib/banzai/filter/gollum_tags_filter_spec.rb
index 0e178b859c4..9d179ef2a49 100644
--- a/spec/lib/banzai/filter/gollum_tags_filter_spec.rb
+++ b/spec/lib/banzai/filter/gollum_tags_filter_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Banzai::Filter::GollumTagsFilter do
diff --git a/spec/lib/banzai/filter/html_entity_filter_spec.rb b/spec/lib/banzai/filter/html_entity_filter_spec.rb
index 1d98fc0d5db..6017380725d 100644
--- a/spec/lib/banzai/filter/html_entity_filter_spec.rb
+++ b/spec/lib/banzai/filter/html_entity_filter_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Banzai::Filter::HtmlEntityFilter do
diff --git a/spec/lib/banzai/filter/image_lazy_load_filter_spec.rb b/spec/lib/banzai/filter/image_lazy_load_filter_spec.rb
index d06c5535309..6475fd14ce4 100644
--- a/spec/lib/banzai/filter/image_lazy_load_filter_spec.rb
+++ b/spec/lib/banzai/filter/image_lazy_load_filter_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Banzai::Filter::ImageLazyLoadFilter do
diff --git a/spec/lib/banzai/filter/image_link_filter_spec.rb b/spec/lib/banzai/filter/image_link_filter_spec.rb
index c84b98eb225..7b0cb675551 100644
--- a/spec/lib/banzai/filter/image_link_filter_spec.rb
+++ b/spec/lib/banzai/filter/image_link_filter_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Banzai::Filter::ImageLinkFilter do
diff --git a/spec/lib/banzai/filter/inline_diff_filter_spec.rb b/spec/lib/banzai/filter/inline_diff_filter_spec.rb
index 63c4ab61b86..c09065fb746 100644
--- a/spec/lib/banzai/filter/inline_diff_filter_spec.rb
+++ b/spec/lib/banzai/filter/inline_diff_filter_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Banzai::Filter::InlineDiffFilter do
diff --git a/spec/lib/banzai/filter/issuable_state_filter_spec.rb b/spec/lib/banzai/filter/issuable_state_filter_spec.rb
index a5373517ac8..9f6dcded56f 100644
--- a/spec/lib/banzai/filter/issuable_state_filter_spec.rb
+++ b/spec/lib/banzai/filter/issuable_state_filter_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Banzai::Filter::IssuableStateFilter do
diff --git a/spec/lib/banzai/filter/issue_reference_filter_spec.rb b/spec/lib/banzai/filter/issue_reference_filter_spec.rb
index 914c4e2d823..4a412da27a7 100644
--- a/spec/lib/banzai/filter/issue_reference_filter_spec.rb
+++ b/spec/lib/banzai/filter/issue_reference_filter_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Banzai::Filter::IssueReferenceFilter do
diff --git a/spec/lib/banzai/filter/label_reference_filter_spec.rb b/spec/lib/banzai/filter/label_reference_filter_spec.rb
index 108d7b43a26..213a5459118 100644
--- a/spec/lib/banzai/filter/label_reference_filter_spec.rb
+++ b/spec/lib/banzai/filter/label_reference_filter_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
require 'html/pipeline'
diff --git a/spec/lib/banzai/filter/markdown_filter_spec.rb b/spec/lib/banzai/filter/markdown_filter_spec.rb
index 83fcda29680..06df67facf9 100644
--- a/spec/lib/banzai/filter/markdown_filter_spec.rb
+++ b/spec/lib/banzai/filter/markdown_filter_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Banzai::Filter::MarkdownFilter do
diff --git a/spec/lib/banzai/filter/math_filter_spec.rb b/spec/lib/banzai/filter/math_filter_spec.rb
index cade8cb409e..c8fd92edcdf 100644
--- a/spec/lib/banzai/filter/math_filter_spec.rb
+++ b/spec/lib/banzai/filter/math_filter_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Banzai::Filter::MathFilter do
diff --git a/spec/lib/banzai/filter/merge_request_reference_filter_spec.rb b/spec/lib/banzai/filter/merge_request_reference_filter_spec.rb
index 72dfd6ff9ea..12ee952b10e 100644
--- a/spec/lib/banzai/filter/merge_request_reference_filter_spec.rb
+++ b/spec/lib/banzai/filter/merge_request_reference_filter_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Banzai::Filter::MergeRequestReferenceFilter do
diff --git a/spec/lib/banzai/filter/mermaid_filter_spec.rb b/spec/lib/banzai/filter/mermaid_filter_spec.rb
index f6474c8936d..ae6725cc14c 100644
--- a/spec/lib/banzai/filter/mermaid_filter_spec.rb
+++ b/spec/lib/banzai/filter/mermaid_filter_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Banzai::Filter::MermaidFilter do
diff --git a/spec/lib/banzai/filter/milestone_reference_filter_spec.rb b/spec/lib/banzai/filter/milestone_reference_filter_spec.rb
index f0a5dc8d0d7..3f021adc756 100644
--- a/spec/lib/banzai/filter/milestone_reference_filter_spec.rb
+++ b/spec/lib/banzai/filter/milestone_reference_filter_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Banzai::Filter::MilestoneReferenceFilter do
@@ -363,7 +365,7 @@ describe Banzai::Filter::MilestoneReferenceFilter do
expect(doc.css('a')).to be_empty
end
- it 'supports parent group references', :nested_groups do
+ it 'supports parent group references' do
milestone.update!(group: parent_group)
doc = reference_filter("See #{reference}")
@@ -396,7 +398,7 @@ describe Banzai::Filter::MilestoneReferenceFilter do
context 'when group milestone' do
let(:group_milestone) { create(:milestone, title: 'group_milestone', group: group) }
- context 'for subgroups', :nested_groups do
+ context 'for subgroups' do
let(:sub_group) { create(:group, parent: group) }
let(:sub_group_milestone) { create(:milestone, title: 'sub_group_milestone', group: sub_group) }
diff --git a/spec/lib/banzai/filter/plantuml_filter_spec.rb b/spec/lib/banzai/filter/plantuml_filter_spec.rb
index 6f7acfe7072..713bab4527b 100644
--- a/spec/lib/banzai/filter/plantuml_filter_spec.rb
+++ b/spec/lib/banzai/filter/plantuml_filter_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Banzai::Filter::PlantumlFilter do
diff --git a/spec/lib/banzai/filter/reference_filter_spec.rb b/spec/lib/banzai/filter/reference_filter_spec.rb
index f96b6c83b0a..d889b0b832d 100644
--- a/spec/lib/banzai/filter/reference_filter_spec.rb
+++ b/spec/lib/banzai/filter/reference_filter_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Banzai::Filter::ReferenceFilter do
diff --git a/spec/lib/banzai/filter/reference_redactor_filter_spec.rb b/spec/lib/banzai/filter/reference_redactor_filter_spec.rb
index e87440895e0..dc888a47988 100644
--- a/spec/lib/banzai/filter/reference_redactor_filter_spec.rb
+++ b/spec/lib/banzai/filter/reference_redactor_filter_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Banzai::Filter::ReferenceRedactorFilter do
diff --git a/spec/lib/banzai/filter/relative_link_filter_spec.rb b/spec/lib/banzai/filter/relative_link_filter_spec.rb
index a714fa50f5f..ecb83b6cb66 100644
--- a/spec/lib/banzai/filter/relative_link_filter_spec.rb
+++ b/spec/lib/banzai/filter/relative_link_filter_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Banzai::Filter::RelativeLinkFilter do
diff --git a/spec/lib/banzai/filter/sanitization_filter_spec.rb b/spec/lib/banzai/filter/sanitization_filter_spec.rb
index f2a5d7b2c9f..8a4b819e4d6 100644
--- a/spec/lib/banzai/filter/sanitization_filter_spec.rb
+++ b/spec/lib/banzai/filter/sanitization_filter_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Banzai::Filter::SanitizationFilter do
diff --git a/spec/lib/banzai/filter/snippet_reference_filter_spec.rb b/spec/lib/banzai/filter/snippet_reference_filter_spec.rb
index 21cf092428d..62ce12406a2 100644
--- a/spec/lib/banzai/filter/snippet_reference_filter_spec.rb
+++ b/spec/lib/banzai/filter/snippet_reference_filter_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Banzai::Filter::SnippetReferenceFilter do
diff --git a/spec/lib/banzai/filter/spaced_link_filter_spec.rb b/spec/lib/banzai/filter/spaced_link_filter_spec.rb
index 76d7644d76c..98c38813144 100644
--- a/spec/lib/banzai/filter/spaced_link_filter_spec.rb
+++ b/spec/lib/banzai/filter/spaced_link_filter_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Banzai::Filter::SpacedLinkFilter do
diff --git a/spec/lib/banzai/filter/syntax_highlight_filter_spec.rb b/spec/lib/banzai/filter/syntax_highlight_filter_spec.rb
index 80ca7a63435..f220ccecee1 100644
--- a/spec/lib/banzai/filter/syntax_highlight_filter_spec.rb
+++ b/spec/lib/banzai/filter/syntax_highlight_filter_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Banzai::Filter::SyntaxHighlightFilter do
diff --git a/spec/lib/banzai/filter/table_of_contents_filter_spec.rb b/spec/lib/banzai/filter/table_of_contents_filter_spec.rb
index 4a9880ac85a..5ca3c722e3e 100644
--- a/spec/lib/banzai/filter/table_of_contents_filter_spec.rb
+++ b/spec/lib/banzai/filter/table_of_contents_filter_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Banzai::Filter::TableOfContentsFilter do
@@ -112,11 +114,11 @@ describe Banzai::Filter::TableOfContentsFilter do
context 'table of contents nesting' do
let(:results) do
result(
- header(1, 'Header 1') <<
- header(2, 'Header 1-1') <<
- header(3, 'Header 1-1-1') <<
- header(2, 'Header 1-2') <<
- header(1, 'Header 2') <<
+ header(1, 'Header 1') +
+ header(2, 'Header 1-1') +
+ header(3, 'Header 1-1-1') +
+ header(2, 'Header 1-2') +
+ header(1, 'Header 2') +
header(2, 'Header 2-1')
)
end
diff --git a/spec/lib/banzai/filter/user_reference_filter_spec.rb b/spec/lib/banzai/filter/user_reference_filter_spec.rb
index 1e8a44b4549..6bc87d245f5 100644
--- a/spec/lib/banzai/filter/user_reference_filter_spec.rb
+++ b/spec/lib/banzai/filter/user_reference_filter_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Banzai::Filter::UserReferenceFilter do
diff --git a/spec/lib/banzai/filter/video_link_filter_spec.rb b/spec/lib/banzai/filter/video_link_filter_spec.rb
index 81dda0687f3..483e806624c 100644
--- a/spec/lib/banzai/filter/video_link_filter_spec.rb
+++ b/spec/lib/banzai/filter/video_link_filter_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Banzai::Filter::VideoLinkFilter do
diff --git a/spec/lib/banzai/filter/wiki_link_filter_spec.rb b/spec/lib/banzai/filter/wiki_link_filter_spec.rb
index cce1cd0b284..9694c44c17a 100644
--- a/spec/lib/banzai/filter/wiki_link_filter_spec.rb
+++ b/spec/lib/banzai/filter/wiki_link_filter_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Banzai::Filter::WikiLinkFilter do
diff --git a/spec/lib/banzai/filter_array_spec.rb b/spec/lib/banzai/filter_array_spec.rb
index ea84005e7f8..bed41a80d29 100644
--- a/spec/lib/banzai/filter_array_spec.rb
+++ b/spec/lib/banzai/filter_array_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Banzai::FilterArray do
diff --git a/spec/lib/banzai/issuable_extractor_spec.rb b/spec/lib/banzai/issuable_extractor_spec.rb
index f42951d9781..7fa6048c1c6 100644
--- a/spec/lib/banzai/issuable_extractor_spec.rb
+++ b/spec/lib/banzai/issuable_extractor_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Banzai::IssuableExtractor do
diff --git a/spec/lib/banzai/object_renderer_spec.rb b/spec/lib/banzai/object_renderer_spec.rb
index e3e6e22568c..a523608fa50 100644
--- a/spec/lib/banzai/object_renderer_spec.rb
+++ b/spec/lib/banzai/object_renderer_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Banzai::ObjectRenderer do
diff --git a/spec/lib/banzai/pipeline/description_pipeline_spec.rb b/spec/lib/banzai/pipeline/description_pipeline_spec.rb
index 77cb1954ea3..d032ec71e45 100644
--- a/spec/lib/banzai/pipeline/description_pipeline_spec.rb
+++ b/spec/lib/banzai/pipeline/description_pipeline_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'rails_helper'
describe Banzai::Pipeline::DescriptionPipeline do
diff --git a/spec/lib/banzai/pipeline/email_pipeline_spec.rb b/spec/lib/banzai/pipeline/email_pipeline_spec.rb
index b99161109eb..eea25320f3d 100644
--- a/spec/lib/banzai/pipeline/email_pipeline_spec.rb
+++ b/spec/lib/banzai/pipeline/email_pipeline_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'rails_helper'
describe Banzai::Pipeline::EmailPipeline do
diff --git a/spec/lib/banzai/pipeline/full_pipeline_spec.rb b/spec/lib/banzai/pipeline/full_pipeline_spec.rb
index 3d3aa64d630..2b4d1b58676 100644
--- a/spec/lib/banzai/pipeline/full_pipeline_spec.rb
+++ b/spec/lib/banzai/pipeline/full_pipeline_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'rails_helper'
describe Banzai::Pipeline::FullPipeline do
diff --git a/spec/lib/banzai/pipeline/gfm_pipeline_spec.rb b/spec/lib/banzai/pipeline/gfm_pipeline_spec.rb
index 469692f7b5a..0a3e0962452 100644
--- a/spec/lib/banzai/pipeline/gfm_pipeline_spec.rb
+++ b/spec/lib/banzai/pipeline/gfm_pipeline_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'rails_helper'
describe Banzai::Pipeline::GfmPipeline do
diff --git a/spec/lib/banzai/pipeline/wiki_pipeline_spec.rb b/spec/lib/banzai/pipeline/wiki_pipeline_spec.rb
index 64ca3ec345d..cb94944fdfb 100644
--- a/spec/lib/banzai/pipeline/wiki_pipeline_spec.rb
+++ b/spec/lib/banzai/pipeline/wiki_pipeline_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'rails_helper'
describe Banzai::Pipeline::WikiPipeline do
diff --git a/spec/lib/banzai/querying_spec.rb b/spec/lib/banzai/querying_spec.rb
index 27da2a7439c..b7a235b0558 100644
--- a/spec/lib/banzai/querying_spec.rb
+++ b/spec/lib/banzai/querying_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Banzai::Querying do
diff --git a/spec/lib/banzai/reference_parser/base_parser_spec.rb b/spec/lib/banzai/reference_parser/base_parser_spec.rb
index c6e9fc414a1..7897164d985 100644
--- a/spec/lib/banzai/reference_parser/base_parser_spec.rb
+++ b/spec/lib/banzai/reference_parser/base_parser_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Banzai::ReferenceParser::BaseParser do
diff --git a/spec/lib/banzai/reference_parser/commit_parser_spec.rb b/spec/lib/banzai/reference_parser/commit_parser_spec.rb
index f558dea209f..b44ae67e430 100644
--- a/spec/lib/banzai/reference_parser/commit_parser_spec.rb
+++ b/spec/lib/banzai/reference_parser/commit_parser_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Banzai::ReferenceParser::CommitParser do
diff --git a/spec/lib/banzai/reference_parser/commit_range_parser_spec.rb b/spec/lib/banzai/reference_parser/commit_range_parser_spec.rb
index ff3b82cc482..da853233018 100644
--- a/spec/lib/banzai/reference_parser/commit_range_parser_spec.rb
+++ b/spec/lib/banzai/reference_parser/commit_range_parser_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Banzai::ReferenceParser::CommitRangeParser do
diff --git a/spec/lib/banzai/reference_parser/external_issue_parser_spec.rb b/spec/lib/banzai/reference_parser/external_issue_parser_spec.rb
index 1cb31e57114..0f29a95bdcc 100644
--- a/spec/lib/banzai/reference_parser/external_issue_parser_spec.rb
+++ b/spec/lib/banzai/reference_parser/external_issue_parser_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Banzai::ReferenceParser::ExternalIssueParser do
diff --git a/spec/lib/banzai/reference_parser/issue_parser_spec.rb b/spec/lib/banzai/reference_parser/issue_parser_spec.rb
index 77c2064caba..a925d294b1b 100644
--- a/spec/lib/banzai/reference_parser/issue_parser_spec.rb
+++ b/spec/lib/banzai/reference_parser/issue_parser_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Banzai::ReferenceParser::IssueParser do
diff --git a/spec/lib/banzai/reference_parser/label_parser_spec.rb b/spec/lib/banzai/reference_parser/label_parser_spec.rb
index e4df2533821..cf8adb57ffc 100644
--- a/spec/lib/banzai/reference_parser/label_parser_spec.rb
+++ b/spec/lib/banzai/reference_parser/label_parser_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Banzai::ReferenceParser::LabelParser do
diff --git a/spec/lib/banzai/reference_parser/merge_request_parser_spec.rb b/spec/lib/banzai/reference_parser/merge_request_parser_spec.rb
index 5417b1f00be..1561dabcdbf 100644
--- a/spec/lib/banzai/reference_parser/merge_request_parser_spec.rb
+++ b/spec/lib/banzai/reference_parser/merge_request_parser_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Banzai::ReferenceParser::MergeRequestParser do
diff --git a/spec/lib/banzai/reference_parser/milestone_parser_spec.rb b/spec/lib/banzai/reference_parser/milestone_parser_spec.rb
index 751d042ffde..006f8e37690 100644
--- a/spec/lib/banzai/reference_parser/milestone_parser_spec.rb
+++ b/spec/lib/banzai/reference_parser/milestone_parser_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Banzai::ReferenceParser::MilestoneParser do
diff --git a/spec/lib/banzai/reference_parser/snippet_parser_spec.rb b/spec/lib/banzai/reference_parser/snippet_parser_spec.rb
index d410bd4c164..528f79ed020 100644
--- a/spec/lib/banzai/reference_parser/snippet_parser_spec.rb
+++ b/spec/lib/banzai/reference_parser/snippet_parser_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Banzai::ReferenceParser::SnippetParser do
diff --git a/spec/lib/banzai/reference_parser/user_parser_spec.rb b/spec/lib/banzai/reference_parser/user_parser_spec.rb
index 112447f098e..a5b4e59a3a1 100644
--- a/spec/lib/banzai/reference_parser/user_parser_spec.rb
+++ b/spec/lib/banzai/reference_parser/user_parser_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Banzai::ReferenceParser::UserParser do
diff --git a/spec/lib/banzai/reference_redactor_spec.rb b/spec/lib/banzai/reference_redactor_spec.rb
index a3b47c4d826..c30a194a0b3 100644
--- a/spec/lib/banzai/reference_redactor_spec.rb
+++ b/spec/lib/banzai/reference_redactor_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Banzai::ReferenceRedactor do
diff --git a/spec/lib/banzai/renderer_spec.rb b/spec/lib/banzai/renderer_spec.rb
index a099f7482c1..0d329b47aa3 100644
--- a/spec/lib/banzai/renderer_spec.rb
+++ b/spec/lib/banzai/renderer_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Banzai::Renderer do
diff --git a/spec/lib/bitbucket/collection_spec.rb b/spec/lib/bitbucket/collection_spec.rb
index 9008cb3e870..5946be71565 100644
--- a/spec/lib/bitbucket/collection_spec.rb
+++ b/spec/lib/bitbucket/collection_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
# Emulates paginator. It returns 2 pages with results
diff --git a/spec/lib/bitbucket/connection_spec.rb b/spec/lib/bitbucket/connection_spec.rb
index 14faeb231a9..ec8eac232cd 100644
--- a/spec/lib/bitbucket/connection_spec.rb
+++ b/spec/lib/bitbucket/connection_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Bitbucket::Connection do
diff --git a/spec/lib/bitbucket/page_spec.rb b/spec/lib/bitbucket/page_spec.rb
index 04d5a0470b1..6301dd56faf 100644
--- a/spec/lib/bitbucket/page_spec.rb
+++ b/spec/lib/bitbucket/page_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Bitbucket::Page do
diff --git a/spec/lib/bitbucket/paginator_spec.rb b/spec/lib/bitbucket/paginator_spec.rb
index bdf10a5e2a2..a1effa14000 100644
--- a/spec/lib/bitbucket/paginator_spec.rb
+++ b/spec/lib/bitbucket/paginator_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Bitbucket::Paginator do
diff --git a/spec/lib/bitbucket/representation/comment_spec.rb b/spec/lib/bitbucket/representation/comment_spec.rb
index fec243a9f96..2dcc933ee61 100644
--- a/spec/lib/bitbucket/representation/comment_spec.rb
+++ b/spec/lib/bitbucket/representation/comment_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Bitbucket::Representation::Comment do
diff --git a/spec/lib/bitbucket/representation/issue_spec.rb b/spec/lib/bitbucket/representation/issue_spec.rb
index 20f47224aa8..c7d1ebdd597 100644
--- a/spec/lib/bitbucket/representation/issue_spec.rb
+++ b/spec/lib/bitbucket/representation/issue_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Bitbucket::Representation::Issue do
diff --git a/spec/lib/bitbucket/representation/pull_request_comment_spec.rb b/spec/lib/bitbucket/representation/pull_request_comment_spec.rb
index 673dcf22ce8..151055f510f 100644
--- a/spec/lib/bitbucket/representation/pull_request_comment_spec.rb
+++ b/spec/lib/bitbucket/representation/pull_request_comment_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Bitbucket::Representation::PullRequestComment do
diff --git a/spec/lib/bitbucket/representation/pull_request_spec.rb b/spec/lib/bitbucket/representation/pull_request_spec.rb
index 30453528be4..7cf43b2b6fd 100644
--- a/spec/lib/bitbucket/representation/pull_request_spec.rb
+++ b/spec/lib/bitbucket/representation/pull_request_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Bitbucket::Representation::PullRequest do
diff --git a/spec/lib/bitbucket/representation/repo_spec.rb b/spec/lib/bitbucket/representation/repo_spec.rb
index 405265cc669..a272695e681 100644
--- a/spec/lib/bitbucket/representation/repo_spec.rb
+++ b/spec/lib/bitbucket/representation/repo_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Bitbucket::Representation::Repo do
diff --git a/spec/lib/bitbucket/representation/user_spec.rb b/spec/lib/bitbucket/representation/user_spec.rb
index f79ff4edb7b..0169887a24c 100644
--- a/spec/lib/bitbucket/representation/user_spec.rb
+++ b/spec/lib/bitbucket/representation/user_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Bitbucket::Representation::User do
diff --git a/spec/lib/bitbucket_server/client_spec.rb b/spec/lib/bitbucket_server/client_spec.rb
index 4f0d57ca8a6..988710b7c4d 100644
--- a/spec/lib/bitbucket_server/client_spec.rb
+++ b/spec/lib/bitbucket_server/client_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe BitbucketServer::Client do
diff --git a/spec/lib/bitbucket_server/connection_spec.rb b/spec/lib/bitbucket_server/connection_spec.rb
index ab8a5b89608..3a7fe4e7321 100644
--- a/spec/lib/bitbucket_server/connection_spec.rb
+++ b/spec/lib/bitbucket_server/connection_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe BitbucketServer::Connection do
diff --git a/spec/lib/bitbucket_server/page_spec.rb b/spec/lib/bitbucket_server/page_spec.rb
index cf419a9045b..2da1d0995ca 100644
--- a/spec/lib/bitbucket_server/page_spec.rb
+++ b/spec/lib/bitbucket_server/page_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe BitbucketServer::Page do
diff --git a/spec/lib/bitbucket_server/paginator_spec.rb b/spec/lib/bitbucket_server/paginator_spec.rb
index eadd7f68bfb..e01cbeb4270 100644
--- a/spec/lib/bitbucket_server/paginator_spec.rb
+++ b/spec/lib/bitbucket_server/paginator_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe BitbucketServer::Paginator do
diff --git a/spec/lib/bitbucket_server/representation/activity_spec.rb b/spec/lib/bitbucket_server/representation/activity_spec.rb
index 15c50e40472..b548dedadfb 100644
--- a/spec/lib/bitbucket_server/representation/activity_spec.rb
+++ b/spec/lib/bitbucket_server/representation/activity_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe BitbucketServer::Representation::Activity do
diff --git a/spec/lib/bitbucket_server/representation/comment_spec.rb b/spec/lib/bitbucket_server/representation/comment_spec.rb
index 53a20a1d80a..f8c73c3da35 100644
--- a/spec/lib/bitbucket_server/representation/comment_spec.rb
+++ b/spec/lib/bitbucket_server/representation/comment_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe BitbucketServer::Representation::Comment do
diff --git a/spec/lib/bitbucket_server/representation/pull_request_comment_spec.rb b/spec/lib/bitbucket_server/representation/pull_request_comment_spec.rb
index bd7e3597486..db43e990812 100644
--- a/spec/lib/bitbucket_server/representation/pull_request_comment_spec.rb
+++ b/spec/lib/bitbucket_server/representation/pull_request_comment_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe BitbucketServer::Representation::PullRequestComment do
diff --git a/spec/lib/bitbucket_server/representation/pull_request_spec.rb b/spec/lib/bitbucket_server/representation/pull_request_spec.rb
index 4b8afdb006b..e091890041e 100644
--- a/spec/lib/bitbucket_server/representation/pull_request_spec.rb
+++ b/spec/lib/bitbucket_server/representation/pull_request_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe BitbucketServer::Representation::PullRequest do
diff --git a/spec/lib/bitbucket_server/representation/repo_spec.rb b/spec/lib/bitbucket_server/representation/repo_spec.rb
index 3ac1030fbb0..801de247d73 100644
--- a/spec/lib/bitbucket_server/representation/repo_spec.rb
+++ b/spec/lib/bitbucket_server/representation/repo_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe BitbucketServer::Representation::Repo do
diff --git a/spec/lib/constraints/feature_constrainer_spec.rb b/spec/lib/constraints/feature_constrainer_spec.rb
index 42efc164f81..0739da801a7 100644
--- a/spec/lib/constraints/feature_constrainer_spec.rb
+++ b/spec/lib/constraints/feature_constrainer_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Constraints::FeatureConstrainer do
diff --git a/spec/lib/constraints/group_url_constrainer_spec.rb b/spec/lib/constraints/group_url_constrainer_spec.rb
index ff295068ba9..573de331898 100644
--- a/spec/lib/constraints/group_url_constrainer_spec.rb
+++ b/spec/lib/constraints/group_url_constrainer_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Constraints::GroupUrlConstrainer do
diff --git a/spec/lib/constraints/project_url_constrainer_spec.rb b/spec/lib/constraints/project_url_constrainer_spec.rb
index 3496b01ebcc..ac3221ecab7 100644
--- a/spec/lib/constraints/project_url_constrainer_spec.rb
+++ b/spec/lib/constraints/project_url_constrainer_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Constraints::ProjectUrlConstrainer do
diff --git a/spec/lib/constraints/user_url_constrainer_spec.rb b/spec/lib/constraints/user_url_constrainer_spec.rb
index e2c85bb27bb..15ef930420c 100644
--- a/spec/lib/constraints/user_url_constrainer_spec.rb
+++ b/spec/lib/constraints/user_url_constrainer_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Constraints::UserUrlConstrainer do
diff --git a/spec/lib/container_registry/blob_spec.rb b/spec/lib/container_registry/blob_spec.rb
index d3fff5bad42..ba7f76cfa3b 100644
--- a/spec/lib/container_registry/blob_spec.rb
+++ b/spec/lib/container_registry/blob_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe ContainerRegistry::Blob do
diff --git a/spec/lib/container_registry/client_spec.rb b/spec/lib/container_registry/client_spec.rb
index ce06377bbbf..bc5fddd12ba 100644
--- a/spec/lib/container_registry/client_spec.rb
+++ b/spec/lib/container_registry/client_spec.rb
@@ -1,4 +1,6 @@
# coding: utf-8
+# frozen_string_literal: true
+
require 'spec_helper'
describe ContainerRegistry::Client do
diff --git a/spec/lib/container_registry/path_spec.rb b/spec/lib/container_registry/path_spec.rb
index 010deae822c..8c671b4d56d 100644
--- a/spec/lib/container_registry/path_spec.rb
+++ b/spec/lib/container_registry/path_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe ContainerRegistry::Path do
diff --git a/spec/lib/container_registry/registry_spec.rb b/spec/lib/container_registry/registry_spec.rb
index 4d6eea94bf0..7cf70a1f562 100644
--- a/spec/lib/container_registry/registry_spec.rb
+++ b/spec/lib/container_registry/registry_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe ContainerRegistry::Registry do
diff --git a/spec/lib/container_registry/tag_spec.rb b/spec/lib/container_registry/tag_spec.rb
index 65090f32f66..110f006536b 100644
--- a/spec/lib/container_registry/tag_spec.rb
+++ b/spec/lib/container_registry/tag_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe ContainerRegistry::Tag do
diff --git a/spec/lib/event_filter_spec.rb b/spec/lib/event_filter_spec.rb
index 6648e141b7a..d6eca8d85ff 100644
--- a/spec/lib/event_filter_spec.rb
+++ b/spec/lib/event_filter_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe EventFilter do
diff --git a/spec/lib/expand_variables_spec.rb b/spec/lib/expand_variables_spec.rb
index 7faa0f31b68..099d7b6b67c 100644
--- a/spec/lib/expand_variables_spec.rb
+++ b/spec/lib/expand_variables_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe ExpandVariables do
diff --git a/spec/lib/extracts_path_spec.rb b/spec/lib/extracts_path_spec.rb
index 21ba72953fb..ffe7584a019 100644
--- a/spec/lib/extracts_path_spec.rb
+++ b/spec/lib/extracts_path_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe ExtractsPath do
diff --git a/spec/lib/feature/gitaly_spec.rb b/spec/lib/feature/gitaly_spec.rb
index 0e24a927d4c..4e07acf9c1a 100644
--- a/spec/lib/feature/gitaly_spec.rb
+++ b/spec/lib/feature/gitaly_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Feature::Gitaly do
diff --git a/spec/lib/feature_spec.rb b/spec/lib/feature_spec.rb
index 127463a57e8..185abacf8e7 100644
--- a/spec/lib/feature_spec.rb
+++ b/spec/lib/feature_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Feature do
diff --git a/spec/lib/file_size_validator_spec.rb b/spec/lib/file_size_validator_spec.rb
index ebd907ecb7f..87376a98c60 100644
--- a/spec/lib/file_size_validator_spec.rb
+++ b/spec/lib/file_size_validator_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe FileSizeValidator do
diff --git a/spec/lib/forever_spec.rb b/spec/lib/forever_spec.rb
index 800fa5a6ad6..9f17308241b 100644
--- a/spec/lib/forever_spec.rb
+++ b/spec/lib/forever_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Forever do
diff --git a/spec/lib/gitaly/server_spec.rb b/spec/lib/gitaly/server_spec.rb
index 34bd43cb3ab..12dfad6698d 100644
--- a/spec/lib/gitaly/server_spec.rb
+++ b/spec/lib/gitaly/server_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitaly::Server do
diff --git a/spec/lib/gitlab/action_rate_limiter_spec.rb b/spec/lib/gitlab/action_rate_limiter_spec.rb
index cf266a25819..8dbad32dfb4 100644
--- a/spec/lib/gitlab/action_rate_limiter_spec.rb
+++ b/spec/lib/gitlab/action_rate_limiter_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::ActionRateLimiter, :clean_gitlab_redis_cache do
diff --git a/spec/lib/gitlab/allowable_spec.rb b/spec/lib/gitlab/allowable_spec.rb
index 9d80d480b52..4905cc4c3db 100644
--- a/spec/lib/gitlab/allowable_spec.rb
+++ b/spec/lib/gitlab/allowable_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Allowable do
diff --git a/spec/lib/gitlab/app_logger_spec.rb b/spec/lib/gitlab/app_logger_spec.rb
index c86d30ce6df..3b21104b15d 100644
--- a/spec/lib/gitlab/app_logger_spec.rb
+++ b/spec/lib/gitlab/app_logger_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::AppLogger, :request_store do
diff --git a/spec/lib/gitlab/asciidoc_spec.rb b/spec/lib/gitlab/asciidoc_spec.rb
index cbd4a509a55..7c65525b8dc 100644
--- a/spec/lib/gitlab/asciidoc_spec.rb
+++ b/spec/lib/gitlab/asciidoc_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
require 'nokogiri'
diff --git a/spec/lib/gitlab/auth/activity_spec.rb b/spec/lib/gitlab/auth/activity_spec.rb
index 07854cb1eba..e03fafe3826 100644
--- a/spec/lib/gitlab/auth/activity_spec.rb
+++ b/spec/lib/gitlab/auth/activity_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'fast_spec_helper'
describe Gitlab::Auth::Activity do
diff --git a/spec/lib/gitlab/auth/blocked_user_tracker_spec.rb b/spec/lib/gitlab/auth/blocked_user_tracker_spec.rb
index f39863fdda1..52849f8c172 100644
--- a/spec/lib/gitlab/auth/blocked_user_tracker_spec.rb
+++ b/spec/lib/gitlab/auth/blocked_user_tracker_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Auth::BlockedUserTracker do
diff --git a/spec/lib/gitlab/auth/ldap/access_spec.rb b/spec/lib/gitlab/auth/ldap/access_spec.rb
index 662f899180b..ecdd5b29986 100644
--- a/spec/lib/gitlab/auth/ldap/access_spec.rb
+++ b/spec/lib/gitlab/auth/ldap/access_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Auth::LDAP::Access do
diff --git a/spec/lib/gitlab/auth/ldap/adapter_spec.rb b/spec/lib/gitlab/auth/ldap/adapter_spec.rb
index 3eeaf3862f6..54486913b72 100644
--- a/spec/lib/gitlab/auth/ldap/adapter_spec.rb
+++ b/spec/lib/gitlab/auth/ldap/adapter_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Auth::LDAP::Adapter do
diff --git a/spec/lib/gitlab/auth/ldap/authentication_spec.rb b/spec/lib/gitlab/auth/ldap/authentication_spec.rb
index 111572d043b..e68e83e4617 100644
--- a/spec/lib/gitlab/auth/ldap/authentication_spec.rb
+++ b/spec/lib/gitlab/auth/ldap/authentication_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Auth::LDAP::Authentication do
diff --git a/spec/lib/gitlab/auth/ldap/config_spec.rb b/spec/lib/gitlab/auth/ldap/config_spec.rb
index b91a09e3137..577dfe51949 100644
--- a/spec/lib/gitlab/auth/ldap/config_spec.rb
+++ b/spec/lib/gitlab/auth/ldap/config_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Auth::LDAP::Config do
diff --git a/spec/lib/gitlab/auth/ldap/dn_spec.rb b/spec/lib/gitlab/auth/ldap/dn_spec.rb
index f2983a02602..63656efba29 100644
--- a/spec/lib/gitlab/auth/ldap/dn_spec.rb
+++ b/spec/lib/gitlab/auth/ldap/dn_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Auth::LDAP::DN do
diff --git a/spec/lib/gitlab/auth/ldap/user_spec.rb b/spec/lib/gitlab/auth/ldap/user_spec.rb
index 44bb9d20e47..bc09de7b525 100644
--- a/spec/lib/gitlab/auth/ldap/user_spec.rb
+++ b/spec/lib/gitlab/auth/ldap/user_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Auth::LDAP::User do
diff --git a/spec/lib/gitlab/auth/o_auth/auth_hash_spec.rb b/spec/lib/gitlab/auth/o_auth/auth_hash_spec.rb
index a5436149818..a2d9e27ea5b 100644
--- a/spec/lib/gitlab/auth/o_auth/auth_hash_spec.rb
+++ b/spec/lib/gitlab/auth/o_auth/auth_hash_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Auth::OAuth::AuthHash do
@@ -13,13 +15,13 @@ describe Gitlab::Auth::OAuth::AuthHash do
end
let(:uid_raw) do
- "CN=Onur K\xC3\xBC\xC3\xA7\xC3\xBCk,OU=Test,DC=example,DC=net"
+ +"CN=Onur K\xC3\xBC\xC3\xA7\xC3\xBCk,OU=Test,DC=example,DC=net"
end
- let(:email_raw) { "onur.k\xC3\xBC\xC3\xA7\xC3\xBCk_ABC-123@example.net" }
- let(:nickname_raw) { "ok\xC3\xBC\xC3\xA7\xC3\xBCk" }
- let(:first_name_raw) { 'Onur' }
- let(:last_name_raw) { "K\xC3\xBC\xC3\xA7\xC3\xBCk" }
- let(:name_raw) { "Onur K\xC3\xBC\xC3\xA7\xC3\xBCk" }
+ let(:email_raw) { +"onur.k\xC3\xBC\xC3\xA7\xC3\xBCk_ABC-123@example.net" }
+ let(:nickname_raw) { +"ok\xC3\xBC\xC3\xA7\xC3\xBCk" }
+ let(:first_name_raw) { +'Onur' }
+ let(:last_name_raw) { +"K\xC3\xBC\xC3\xA7\xC3\xBCk" }
+ let(:name_raw) { +"Onur K\xC3\xBC\xC3\xA7\xC3\xBCk" }
let(:uid_ascii) { uid_raw.force_encoding(Encoding::ASCII_8BIT) }
let(:email_ascii) { email_raw.force_encoding(Encoding::ASCII_8BIT) }
diff --git a/spec/lib/gitlab/auth/o_auth/identity_linker_spec.rb b/spec/lib/gitlab/auth/o_auth/identity_linker_spec.rb
index bf810d72f0e..45c1baa4089 100644
--- a/spec/lib/gitlab/auth/o_auth/identity_linker_spec.rb
+++ b/spec/lib/gitlab/auth/o_auth/identity_linker_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Auth::OAuth::IdentityLinker do
diff --git a/spec/lib/gitlab/auth/o_auth/provider_spec.rb b/spec/lib/gitlab/auth/o_auth/provider_spec.rb
index 80d702cf9dc..f46f9d76a1e 100644
--- a/spec/lib/gitlab/auth/o_auth/provider_spec.rb
+++ b/spec/lib/gitlab/auth/o_auth/provider_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Auth::OAuth::Provider do
diff --git a/spec/lib/gitlab/auth/o_auth/user_spec.rb b/spec/lib/gitlab/auth/o_auth/user_spec.rb
index b765c265e69..a9b15c411dc 100644
--- a/spec/lib/gitlab/auth/o_auth/user_spec.rb
+++ b/spec/lib/gitlab/auth/o_auth/user_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Auth::OAuth::User do
diff --git a/spec/lib/gitlab/auth/request_authenticator_spec.rb b/spec/lib/gitlab/auth/request_authenticator_spec.rb
index 3d979132880..f7fff389d88 100644
--- a/spec/lib/gitlab/auth/request_authenticator_spec.rb
+++ b/spec/lib/gitlab/auth/request_authenticator_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Auth::RequestAuthenticator do
diff --git a/spec/lib/gitlab/auth/saml/auth_hash_spec.rb b/spec/lib/gitlab/auth/saml/auth_hash_spec.rb
index 3620e1afe25..13636a495d1 100644
--- a/spec/lib/gitlab/auth/saml/auth_hash_spec.rb
+++ b/spec/lib/gitlab/auth/saml/auth_hash_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Auth::Saml::AuthHash do
diff --git a/spec/lib/gitlab/auth/saml/identity_linker_spec.rb b/spec/lib/gitlab/auth/saml/identity_linker_spec.rb
index f3305d574cc..89118ff05ba 100644
--- a/spec/lib/gitlab/auth/saml/identity_linker_spec.rb
+++ b/spec/lib/gitlab/auth/saml/identity_linker_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Auth::Saml::IdentityLinker do
diff --git a/spec/lib/gitlab/auth/saml/user_spec.rb b/spec/lib/gitlab/auth/saml/user_spec.rb
index c523f5e177f..5546438b7ee 100644
--- a/spec/lib/gitlab/auth/saml/user_spec.rb
+++ b/spec/lib/gitlab/auth/saml/user_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Auth::Saml::User do
diff --git a/spec/lib/gitlab/auth/unique_ips_limiter_spec.rb b/spec/lib/gitlab/auth/unique_ips_limiter_spec.rb
index 22708687a56..ebf7de9c701 100644
--- a/spec/lib/gitlab/auth/unique_ips_limiter_spec.rb
+++ b/spec/lib/gitlab/auth/unique_ips_limiter_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Auth::UniqueIpsLimiter, :clean_gitlab_redis_shared_state do
diff --git a/spec/lib/gitlab/auth/user_access_denied_reason_spec.rb b/spec/lib/gitlab/auth/user_access_denied_reason_spec.rb
index 002ce776be9..8ec19c454d8 100644
--- a/spec/lib/gitlab/auth/user_access_denied_reason_spec.rb
+++ b/spec/lib/gitlab/auth/user_access_denied_reason_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Auth::UserAccessDeniedReason do
diff --git a/spec/lib/gitlab/auth/user_auth_finders_spec.rb b/spec/lib/gitlab/auth/user_auth_finders_spec.rb
index 4751f880cee..41265da97a4 100644
--- a/spec/lib/gitlab/auth/user_auth_finders_spec.rb
+++ b/spec/lib/gitlab/auth/user_auth_finders_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Auth::UserAuthFinders do
diff --git a/spec/lib/gitlab/auth_spec.rb b/spec/lib/gitlab/auth_spec.rb
index 0403830f700..edff38f05ec 100644
--- a/spec/lib/gitlab/auth_spec.rb
+++ b/spec/lib/gitlab/auth_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Auth do
diff --git a/spec/lib/gitlab/background_migration/add_merge_request_diff_commits_count_spec.rb b/spec/lib/gitlab/background_migration/add_merge_request_diff_commits_count_spec.rb
index c43ed72038e..e299e2a366f 100644
--- a/spec/lib/gitlab/background_migration/add_merge_request_diff_commits_count_spec.rb
+++ b/spec/lib/gitlab/background_migration/add_merge_request_diff_commits_count_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::BackgroundMigration::AddMergeRequestDiffCommitsCount, :migration, schema: 20180105212544 do
diff --git a/spec/lib/gitlab/background_migration/archive_legacy_traces_spec.rb b/spec/lib/gitlab/background_migration/archive_legacy_traces_spec.rb
index 877c061d11b..2a7cffb2f3e 100644
--- a/spec/lib/gitlab/background_migration/archive_legacy_traces_spec.rb
+++ b/spec/lib/gitlab/background_migration/archive_legacy_traces_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::BackgroundMigration::ArchiveLegacyTraces, :migration, schema: 20180529152628 do
diff --git a/spec/lib/gitlab/background_migration/encrypt_columns_spec.rb b/spec/lib/gitlab/background_migration/encrypt_columns_spec.rb
index 1d9bac79dcd..3c2ed6d3a6d 100644
--- a/spec/lib/gitlab/background_migration/encrypt_columns_spec.rb
+++ b/spec/lib/gitlab/background_migration/encrypt_columns_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::BackgroundMigration::EncryptColumns, :migration, schema: 20180910115836 do
diff --git a/spec/lib/gitlab/background_migration/encrypt_runners_tokens_spec.rb b/spec/lib/gitlab/background_migration/encrypt_runners_tokens_spec.rb
index 9d4921968b3..54af9807e7b 100644
--- a/spec/lib/gitlab/background_migration/encrypt_runners_tokens_spec.rb
+++ b/spec/lib/gitlab/background_migration/encrypt_runners_tokens_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::BackgroundMigration::EncryptRunnersTokens, :migration, schema: 20181121111200 do
diff --git a/spec/lib/gitlab/background_migration/fix_cross_project_label_links_spec.rb b/spec/lib/gitlab/background_migration/fix_cross_project_label_links_spec.rb
index 20af63bc6c8..f3127cbf5df 100644
--- a/spec/lib/gitlab/background_migration/fix_cross_project_label_links_spec.rb
+++ b/spec/lib/gitlab/background_migration/fix_cross_project_label_links_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::BackgroundMigration::FixCrossProjectLabelLinks, :migration, schema: 20180702120647 do
@@ -75,7 +77,7 @@ describe Gitlab::BackgroundMigration::FixCrossProjectLabelLinks, :migration, sch
create_resource(target_type, 1, 2)
end
- it 'ignores label links referencing ancestor group labels', :nested_groups do
+ it 'ignores label links referencing ancestor group labels' do
labels_table.create(id: 4, title: 'bug', color: 'red', project_id: 2, type: 'ProjectLabel')
label_links_table.create(label_id: 4, target_type: target_type, target_id: 1)
link = label_links_table.create(label_id: 1, target_type: target_type, target_id: 1)
@@ -85,7 +87,7 @@ describe Gitlab::BackgroundMigration::FixCrossProjectLabelLinks, :migration, sch
expect(link.reload.label_id).to eq(1)
end
- it 'checks also issues and MRs in subgroups', :nested_groups do
+ it 'checks also issues and MRs in subgroups' do
link = label_links_table.create(label_id: 2, target_type: target_type, target_id: 1)
subject.perform(1, 100)
diff --git a/spec/lib/gitlab/background_migration/migrate_build_stage_spec.rb b/spec/lib/gitlab/background_migration/migrate_build_stage_spec.rb
index 582396275ed..a496f8416bf 100644
--- a/spec/lib/gitlab/background_migration/migrate_build_stage_spec.rb
+++ b/spec/lib/gitlab/background_migration/migrate_build_stage_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::BackgroundMigration::MigrateBuildStage, :migration, schema: 20180212101928 do
diff --git a/spec/lib/gitlab/background_migration/migrate_legacy_artifacts_spec.rb b/spec/lib/gitlab/background_migration/migrate_legacy_artifacts_spec.rb
index 2d1505dacfe..268626d58fd 100644
--- a/spec/lib/gitlab/background_migration/migrate_legacy_artifacts_spec.rb
+++ b/spec/lib/gitlab/background_migration/migrate_legacy_artifacts_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::BackgroundMigration::MigrateLegacyArtifacts, :migration, schema: 20180816161409 do
diff --git a/spec/lib/gitlab/background_migration/migrate_stage_index_spec.rb b/spec/lib/gitlab/background_migration/migrate_stage_index_spec.rb
index 4db829b1e7b..1a8b0355fd9 100644
--- a/spec/lib/gitlab/background_migration/migrate_stage_index_spec.rb
+++ b/spec/lib/gitlab/background_migration/migrate_stage_index_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::BackgroundMigration::MigrateStageIndex, :migration, schema: 20180420080616 do
diff --git a/spec/lib/gitlab/background_migration/populate_untracked_uploads_dependencies/untracked_file_spec.rb b/spec/lib/gitlab/background_migration/populate_untracked_uploads_dependencies/untracked_file_spec.rb
index c76adcbe2f5..ea1eaa6417d 100644
--- a/spec/lib/gitlab/background_migration/populate_untracked_uploads_dependencies/untracked_file_spec.rb
+++ b/spec/lib/gitlab/background_migration/populate_untracked_uploads_dependencies/untracked_file_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
# Rollback DB to 10.5 (later than this was originally written for) because it still needs to work.
diff --git a/spec/lib/gitlab/background_migration/populate_untracked_uploads_spec.rb b/spec/lib/gitlab/background_migration/populate_untracked_uploads_spec.rb
index 0d2074eed22..44f537ca8dd 100644
--- a/spec/lib/gitlab/background_migration/populate_untracked_uploads_spec.rb
+++ b/spec/lib/gitlab/background_migration/populate_untracked_uploads_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
# Rollback DB to 10.5 (later than this was originally written for) because it still needs to work.
diff --git a/spec/lib/gitlab/background_migration/prepare_untracked_uploads_spec.rb b/spec/lib/gitlab/background_migration/prepare_untracked_uploads_spec.rb
index 35750d89c35..591368ee98e 100644
--- a/spec/lib/gitlab/background_migration/prepare_untracked_uploads_spec.rb
+++ b/spec/lib/gitlab/background_migration/prepare_untracked_uploads_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
# Rollback DB to 10.5 (later than this was originally written for) because it still needs to work.
diff --git a/spec/lib/gitlab/background_migration/schedule_calculate_wiki_sizes_spec.rb b/spec/lib/gitlab/background_migration/schedule_calculate_wiki_sizes_spec.rb
index d494ce68c5b..f877e8cc1b8 100644
--- a/spec/lib/gitlab/background_migration/schedule_calculate_wiki_sizes_spec.rb
+++ b/spec/lib/gitlab/background_migration/schedule_calculate_wiki_sizes_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
require Rails.root.join('db', 'post_migrate', '20190527194900_schedule_calculate_wiki_sizes.rb')
diff --git a/spec/lib/gitlab/background_migration/set_confidential_note_events_on_services_spec.rb b/spec/lib/gitlab/background_migration/set_confidential_note_events_on_services_spec.rb
index 6f3fb994f17..3600755ada7 100644
--- a/spec/lib/gitlab/background_migration/set_confidential_note_events_on_services_spec.rb
+++ b/spec/lib/gitlab/background_migration/set_confidential_note_events_on_services_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::BackgroundMigration::SetConfidentialNoteEventsOnServices, :migration, schema: 20180122154930 do
diff --git a/spec/lib/gitlab/background_migration/set_confidential_note_events_on_webhooks_spec.rb b/spec/lib/gitlab/background_migration/set_confidential_note_events_on_webhooks_spec.rb
index 82b484b7d5b..5cd9c02fd3f 100644
--- a/spec/lib/gitlab/background_migration/set_confidential_note_events_on_webhooks_spec.rb
+++ b/spec/lib/gitlab/background_migration/set_confidential_note_events_on_webhooks_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::BackgroundMigration::SetConfidentialNoteEventsOnWebhooks, :migration, schema: 20180104131052 do
diff --git a/spec/lib/gitlab/background_migration_spec.rb b/spec/lib/gitlab/background_migration_spec.rb
index 1d0ffb5e9df..8960ac706e6 100644
--- a/spec/lib/gitlab/background_migration_spec.rb
+++ b/spec/lib/gitlab/background_migration_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::BackgroundMigration do
diff --git a/spec/lib/gitlab/badge/coverage/metadata_spec.rb b/spec/lib/gitlab/badge/coverage/metadata_spec.rb
index 74eaf7eaf8b..2b87508bdef 100644
--- a/spec/lib/gitlab/badge/coverage/metadata_spec.rb
+++ b/spec/lib/gitlab/badge/coverage/metadata_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
require 'lib/gitlab/badge/shared/metadata'
diff --git a/spec/lib/gitlab/badge/coverage/report_spec.rb b/spec/lib/gitlab/badge/coverage/report_spec.rb
index da789bf3705..eee3f96ab85 100644
--- a/spec/lib/gitlab/badge/coverage/report_spec.rb
+++ b/spec/lib/gitlab/badge/coverage/report_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Badge::Coverage::Report do
diff --git a/spec/lib/gitlab/badge/coverage/template_spec.rb b/spec/lib/gitlab/badge/coverage/template_spec.rb
index d9c21a22590..b51d707a61d 100644
--- a/spec/lib/gitlab/badge/coverage/template_spec.rb
+++ b/spec/lib/gitlab/badge/coverage/template_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Badge::Coverage::Template do
diff --git a/spec/lib/gitlab/badge/pipeline/metadata_spec.rb b/spec/lib/gitlab/badge/pipeline/metadata_spec.rb
index 9032a8e9016..b096803f921 100644
--- a/spec/lib/gitlab/badge/pipeline/metadata_spec.rb
+++ b/spec/lib/gitlab/badge/pipeline/metadata_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
require 'lib/gitlab/badge/shared/metadata'
diff --git a/spec/lib/gitlab/badge/pipeline/status_spec.rb b/spec/lib/gitlab/badge/pipeline/status_spec.rb
index dc835375c66..684c6829879 100644
--- a/spec/lib/gitlab/badge/pipeline/status_spec.rb
+++ b/spec/lib/gitlab/badge/pipeline/status_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Badge::Pipeline::Status do
diff --git a/spec/lib/gitlab/badge/pipeline/template_spec.rb b/spec/lib/gitlab/badge/pipeline/template_spec.rb
index bcef0b7e120..c0aaa3d73e1 100644
--- a/spec/lib/gitlab/badge/pipeline/template_spec.rb
+++ b/spec/lib/gitlab/badge/pipeline/template_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Badge::Pipeline::Template do
diff --git a/spec/lib/gitlab/badge/shared/metadata.rb b/spec/lib/gitlab/badge/shared/metadata.rb
index 63c7ca5a915..809fa54db02 100644
--- a/spec/lib/gitlab/badge/shared/metadata.rb
+++ b/spec/lib/gitlab/badge/shared/metadata.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
shared_examples 'badge metadata' do
describe '#to_html' do
let(:html) { Nokogiri::HTML.parse(metadata.to_html) }
diff --git a/spec/lib/gitlab/bare_repository_import/importer_spec.rb b/spec/lib/gitlab/bare_repository_import/importer_spec.rb
index f4759b69538..0c1eedad7f4 100644
--- a/spec/lib/gitlab/bare_repository_import/importer_spec.rb
+++ b/spec/lib/gitlab/bare_repository_import/importer_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::BareRepositoryImport::Importer, :seed_helper do
@@ -103,7 +105,7 @@ describe Gitlab::BareRepositoryImport::Importer, :seed_helper do
end
end
- context 'with subgroups', :nested_groups do
+ context 'with subgroups' do
let(:project_path) { 'a-group/a-sub-group/a-project' }
let(:existing_group) do
@@ -188,20 +190,6 @@ describe Gitlab::BareRepositoryImport::Importer, :seed_helper do
end
end
- context 'when subgroups are not available' do
- let(:project_path) { 'a-group/a-sub-group/a-project' }
-
- before do
- expect(Group).to receive(:supports_nested_objects?) { false }
- end
-
- describe '#create_project_if_needed' do
- it 'raises an error' do
- expect { importer.create_project_if_needed }.to raise_error('Nested groups are not supported on MySQL')
- end
- end
- end
-
def prepare_repository(project_path, source_project)
repo_path = File.join(base_dir, project_path)
diff --git a/spec/lib/gitlab/bare_repository_import/repository_spec.rb b/spec/lib/gitlab/bare_repository_import/repository_spec.rb
index a07c5371134..0607e2232a1 100644
--- a/spec/lib/gitlab/bare_repository_import/repository_spec.rb
+++ b/spec/lib/gitlab/bare_repository_import/repository_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe ::Gitlab::BareRepositoryImport::Repository do
diff --git a/spec/lib/gitlab/bitbucket_import/importer_spec.rb b/spec/lib/gitlab/bitbucket_import/importer_spec.rb
index 35700e0b588..62b688d4d3e 100644
--- a/spec/lib/gitlab/bitbucket_import/importer_spec.rb
+++ b/spec/lib/gitlab/bitbucket_import/importer_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::BitbucketImport::Importer do
diff --git a/spec/lib/gitlab/bitbucket_import/project_creator_spec.rb b/spec/lib/gitlab/bitbucket_import/project_creator_spec.rb
index e2bee22cf1f..0dd8547a925 100644
--- a/spec/lib/gitlab/bitbucket_import/project_creator_spec.rb
+++ b/spec/lib/gitlab/bitbucket_import/project_creator_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::BitbucketImport::ProjectCreator do
diff --git a/spec/lib/gitlab/bitbucket_import/wiki_formatter_spec.rb b/spec/lib/gitlab/bitbucket_import/wiki_formatter_spec.rb
index 795fd069ab2..7b5c7847f2d 100644
--- a/spec/lib/gitlab/bitbucket_import/wiki_formatter_spec.rb
+++ b/spec/lib/gitlab/bitbucket_import/wiki_formatter_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::BitbucketImport::WikiFormatter do
diff --git a/spec/lib/gitlab/bitbucket_server_import/importer_spec.rb b/spec/lib/gitlab/bitbucket_server_import/importer_spec.rb
index cc09804fd53..8ab7b2c5fa7 100644
--- a/spec/lib/gitlab/bitbucket_server_import/importer_spec.rb
+++ b/spec/lib/gitlab/bitbucket_server_import/importer_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::BitbucketServerImport::Importer do
diff --git a/spec/lib/gitlab/blame_spec.rb b/spec/lib/gitlab/blame_spec.rb
index 7cab04e9fc9..e1afd5b25bb 100644
--- a/spec/lib/gitlab/blame_spec.rb
+++ b/spec/lib/gitlab/blame_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Blame do
diff --git a/spec/lib/gitlab/build_access_spec.rb b/spec/lib/gitlab/build_access_spec.rb
index 08f50bf4fac..b7af8ace5b5 100644
--- a/spec/lib/gitlab/build_access_spec.rb
+++ b/spec/lib/gitlab/build_access_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::BuildAccess do
diff --git a/spec/lib/gitlab/cache/ci/project_pipeline_status_spec.rb b/spec/lib/gitlab/cache/ci/project_pipeline_status_spec.rb
index 483c5ea9cff..91e7edaf704 100644
--- a/spec/lib/gitlab/cache/ci/project_pipeline_status_spec.rb
+++ b/spec/lib/gitlab/cache/ci/project_pipeline_status_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Cache::Ci::ProjectPipelineStatus, :clean_gitlab_redis_cache do
diff --git a/spec/lib/gitlab/cache/request_cache_spec.rb b/spec/lib/gitlab/cache/request_cache_spec.rb
index 5b82c216a13..70a7f090d0a 100644
--- a/spec/lib/gitlab/cache/request_cache_spec.rb
+++ b/spec/lib/gitlab/cache/request_cache_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Cache::RequestCache do
diff --git a/spec/lib/gitlab/changes_list_spec.rb b/spec/lib/gitlab/changes_list_spec.rb
index 464508fcd73..911450f3a8b 100644
--- a/spec/lib/gitlab/changes_list_spec.rb
+++ b/spec/lib/gitlab/changes_list_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require "spec_helper"
describe Gitlab::ChangesList do
diff --git a/spec/lib/gitlab/chat_name_token_spec.rb b/spec/lib/gitlab/chat_name_token_spec.rb
index 1e9fb9077fc..b2d4a466021 100644
--- a/spec/lib/gitlab/chat_name_token_spec.rb
+++ b/spec/lib/gitlab/chat_name_token_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::ChatNameToken do
diff --git a/spec/lib/gitlab/chat_spec.rb b/spec/lib/gitlab/chat_spec.rb
index d61c4b36668..08cc16314c5 100644
--- a/spec/lib/gitlab/chat_spec.rb
+++ b/spec/lib/gitlab/chat_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Chat, :use_clean_rails_memory_store_caching do
diff --git a/spec/lib/gitlab/checks/change_access_spec.rb b/spec/lib/gitlab/checks/change_access_spec.rb
index 45fb33e9e4a..3a8e8f67e16 100644
--- a/spec/lib/gitlab/checks/change_access_spec.rb
+++ b/spec/lib/gitlab/checks/change_access_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Checks::ChangeAccess do
diff --git a/spec/lib/gitlab/checks/force_push_spec.rb b/spec/lib/gitlab/checks/force_push_spec.rb
index 0e0788ce974..9432be083d3 100644
--- a/spec/lib/gitlab/checks/force_push_spec.rb
+++ b/spec/lib/gitlab/checks/force_push_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Checks::ForcePush do
diff --git a/spec/lib/gitlab/checks/lfs_integrity_spec.rb b/spec/lib/gitlab/checks/lfs_integrity_spec.rb
index 887ea8fc1e0..88e8f5d74d1 100644
--- a/spec/lib/gitlab/checks/lfs_integrity_spec.rb
+++ b/spec/lib/gitlab/checks/lfs_integrity_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Checks::LfsIntegrity do
diff --git a/spec/lib/gitlab/checks/project_created_spec.rb b/spec/lib/gitlab/checks/project_created_spec.rb
index ac02007e111..14cb5e6ec66 100644
--- a/spec/lib/gitlab/checks/project_created_spec.rb
+++ b/spec/lib/gitlab/checks/project_created_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'rails_helper'
describe Gitlab::Checks::ProjectCreated, :clean_gitlab_redis_shared_state do
diff --git a/spec/lib/gitlab/checks/project_moved_spec.rb b/spec/lib/gitlab/checks/project_moved_spec.rb
index 8e9386b1ba1..3ca977aa48d 100644
--- a/spec/lib/gitlab/checks/project_moved_spec.rb
+++ b/spec/lib/gitlab/checks/project_moved_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'rails_helper'
describe Gitlab::Checks::ProjectMoved, :clean_gitlab_redis_shared_state do
diff --git a/spec/lib/gitlab/ci/ansi2html_spec.rb b/spec/lib/gitlab/ci/ansi2html_spec.rb
index 3d57ce431ab..651fdaaabca 100644
--- a/spec/lib/gitlab/ci/ansi2html_spec.rb
+++ b/spec/lib/gitlab/ci/ansi2html_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Ansi2html do
diff --git a/spec/lib/gitlab/ci/build/artifacts/adapters/gzip_stream_spec.rb b/spec/lib/gitlab/ci/build/artifacts/adapters/gzip_stream_spec.rb
index 987c6b37aaa..cec3e70bb9f 100644
--- a/spec/lib/gitlab/ci/build/artifacts/adapters/gzip_stream_spec.rb
+++ b/spec/lib/gitlab/ci/build/artifacts/adapters/gzip_stream_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Build::Artifacts::Adapters::GzipStream do
diff --git a/spec/lib/gitlab/ci/build/artifacts/adapters/raw_stream_spec.rb b/spec/lib/gitlab/ci/build/artifacts/adapters/raw_stream_spec.rb
index ec2dd724b45..66a234232e1 100644
--- a/spec/lib/gitlab/ci/build/artifacts/adapters/raw_stream_spec.rb
+++ b/spec/lib/gitlab/ci/build/artifacts/adapters/raw_stream_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Build::Artifacts::Adapters::RawStream do
diff --git a/spec/lib/gitlab/ci/build/artifacts/metadata/entry_spec.rb b/spec/lib/gitlab/ci/build/artifacts/metadata/entry_spec.rb
index 3b905611467..24d17eb0fb3 100644
--- a/spec/lib/gitlab/ci/build/artifacts/metadata/entry_spec.rb
+++ b/spec/lib/gitlab/ci/build/artifacts/metadata/entry_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Build::Artifacts::Metadata::Entry do
diff --git a/spec/lib/gitlab/ci/build/artifacts/metadata_spec.rb b/spec/lib/gitlab/ci/build/artifacts/metadata_spec.rb
index a9a4af1f455..ff189c4701e 100644
--- a/spec/lib/gitlab/ci/build/artifacts/metadata_spec.rb
+++ b/spec/lib/gitlab/ci/build/artifacts/metadata_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Build::Artifacts::Metadata do
diff --git a/spec/lib/gitlab/ci/build/artifacts/path_spec.rb b/spec/lib/gitlab/ci/build/artifacts/path_spec.rb
index 7bd6a2ead25..7bbef0f5197 100644
--- a/spec/lib/gitlab/ci/build/artifacts/path_spec.rb
+++ b/spec/lib/gitlab/ci/build/artifacts/path_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Build::Artifacts::Path do
diff --git a/spec/lib/gitlab/ci/build/credentials/factory_spec.rb b/spec/lib/gitlab/ci/build/credentials/factory_spec.rb
index d53db05e5e6..9148c0d579e 100644
--- a/spec/lib/gitlab/ci/build/credentials/factory_spec.rb
+++ b/spec/lib/gitlab/ci/build/credentials/factory_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Build::Credentials::Factory do
diff --git a/spec/lib/gitlab/ci/build/credentials/registry_spec.rb b/spec/lib/gitlab/ci/build/credentials/registry_spec.rb
index c6054138cde..552580dcbbe 100644
--- a/spec/lib/gitlab/ci/build/credentials/registry_spec.rb
+++ b/spec/lib/gitlab/ci/build/credentials/registry_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Build::Credentials::Registry do
diff --git a/spec/lib/gitlab/ci/build/image_spec.rb b/spec/lib/gitlab/ci/build/image_spec.rb
index 6e20e0ef5c3..04bab9c58b8 100644
--- a/spec/lib/gitlab/ci/build/image_spec.rb
+++ b/spec/lib/gitlab/ci/build/image_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Build::Image do
diff --git a/spec/lib/gitlab/ci/build/policy/changes_spec.rb b/spec/lib/gitlab/ci/build/policy/changes_spec.rb
index 92cf0376c02..48ac2e4e657 100644
--- a/spec/lib/gitlab/ci/build/policy/changes_spec.rb
+++ b/spec/lib/gitlab/ci/build/policy/changes_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Build::Policy::Changes do
diff --git a/spec/lib/gitlab/ci/build/policy/kubernetes_spec.rb b/spec/lib/gitlab/ci/build/policy/kubernetes_spec.rb
index 4510b82ca9d..bc2e6fe6b8d 100644
--- a/spec/lib/gitlab/ci/build/policy/kubernetes_spec.rb
+++ b/spec/lib/gitlab/ci/build/policy/kubernetes_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Build::Policy::Kubernetes do
diff --git a/spec/lib/gitlab/ci/build/policy/refs_spec.rb b/spec/lib/gitlab/ci/build/policy/refs_spec.rb
index 22ca681cfd3..43c5d3ec980 100644
--- a/spec/lib/gitlab/ci/build/policy/refs_spec.rb
+++ b/spec/lib/gitlab/ci/build/policy/refs_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Build::Policy::Refs do
diff --git a/spec/lib/gitlab/ci/build/policy/variables_spec.rb b/spec/lib/gitlab/ci/build/policy/variables_spec.rb
index 9b016901a20..42a2a9fda2e 100644
--- a/spec/lib/gitlab/ci/build/policy/variables_spec.rb
+++ b/spec/lib/gitlab/ci/build/policy/variables_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Build::Policy::Variables do
diff --git a/spec/lib/gitlab/ci/build/policy_spec.rb b/spec/lib/gitlab/ci/build/policy_spec.rb
index 20ee3dd3e89..80d7b2e9dc8 100644
--- a/spec/lib/gitlab/ci/build/policy_spec.rb
+++ b/spec/lib/gitlab/ci/build/policy_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Build::Policy do
diff --git a/spec/lib/gitlab/ci/build/step_spec.rb b/spec/lib/gitlab/ci/build/step_spec.rb
index e3136fc925e..84e6e0e177f 100644
--- a/spec/lib/gitlab/ci/build/step_spec.rb
+++ b/spec/lib/gitlab/ci/build/step_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Build::Step do
diff --git a/spec/lib/gitlab/ci/charts_spec.rb b/spec/lib/gitlab/ci/charts_spec.rb
index 1668d3bbaac..cfb7a3f72fa 100644
--- a/spec/lib/gitlab/ci/charts_spec.rb
+++ b/spec/lib/gitlab/ci/charts_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Charts do
diff --git a/spec/lib/gitlab/ci/config/entry/artifacts_spec.rb b/spec/lib/gitlab/ci/config/entry/artifacts_spec.rb
index bd1f2c92844..a7f457e0f5e 100644
--- a/spec/lib/gitlab/ci/config/entry/artifacts_spec.rb
+++ b/spec/lib/gitlab/ci/config/entry/artifacts_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Config::Entry::Artifacts do
diff --git a/spec/lib/gitlab/ci/config/entry/cache_spec.rb b/spec/lib/gitlab/ci/config/entry/cache_spec.rb
index 8f711e02f9b..4cb63168ec7 100644
--- a/spec/lib/gitlab/ci/config/entry/cache_spec.rb
+++ b/spec/lib/gitlab/ci/config/entry/cache_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Config::Entry::Cache do
diff --git a/spec/lib/gitlab/ci/config/entry/commands_spec.rb b/spec/lib/gitlab/ci/config/entry/commands_spec.rb
index 8934aeb83db..269a3406913 100644
--- a/spec/lib/gitlab/ci/config/entry/commands_spec.rb
+++ b/spec/lib/gitlab/ci/config/entry/commands_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Config::Entry::Commands do
diff --git a/spec/lib/gitlab/ci/config/entry/coverage_spec.rb b/spec/lib/gitlab/ci/config/entry/coverage_spec.rb
index 4c6bd859552..48d0864cfca 100644
--- a/spec/lib/gitlab/ci/config/entry/coverage_spec.rb
+++ b/spec/lib/gitlab/ci/config/entry/coverage_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Config::Entry::Coverage do
diff --git a/spec/lib/gitlab/ci/config/entry/default_spec.rb b/spec/lib/gitlab/ci/config/entry/default_spec.rb
index a901dd80c2c..27d63dbd407 100644
--- a/spec/lib/gitlab/ci/config/entry/default_spec.rb
+++ b/spec/lib/gitlab/ci/config/entry/default_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Config::Entry::Default do
diff --git a/spec/lib/gitlab/ci/config/entry/environment_spec.rb b/spec/lib/gitlab/ci/config/entry/environment_spec.rb
index 0bc9e8bd3cd..7b72b45fd8d 100644
--- a/spec/lib/gitlab/ci/config/entry/environment_spec.rb
+++ b/spec/lib/gitlab/ci/config/entry/environment_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Config::Entry::Environment do
diff --git a/spec/lib/gitlab/ci/config/entry/hidden_spec.rb b/spec/lib/gitlab/ci/config/entry/hidden_spec.rb
index c88ee10550c..40b73352676 100644
--- a/spec/lib/gitlab/ci/config/entry/hidden_spec.rb
+++ b/spec/lib/gitlab/ci/config/entry/hidden_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Config::Entry::Hidden do
diff --git a/spec/lib/gitlab/ci/config/entry/image_spec.rb b/spec/lib/gitlab/ci/config/entry/image_spec.rb
index 1ebdda398b9..8de2e5de724 100644
--- a/spec/lib/gitlab/ci/config/entry/image_spec.rb
+++ b/spec/lib/gitlab/ci/config/entry/image_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Config::Entry::Image do
diff --git a/spec/lib/gitlab/ci/config/entry/job_spec.rb b/spec/lib/gitlab/ci/config/entry/job_spec.rb
index 25766d34c65..d5861d5dd07 100644
--- a/spec/lib/gitlab/ci/config/entry/job_spec.rb
+++ b/spec/lib/gitlab/ci/config/entry/job_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Config::Entry::Job do
diff --git a/spec/lib/gitlab/ci/config/entry/jobs_spec.rb b/spec/lib/gitlab/ci/config/entry/jobs_spec.rb
index 3e4137930dc..61c8956d41f 100644
--- a/spec/lib/gitlab/ci/config/entry/jobs_spec.rb
+++ b/spec/lib/gitlab/ci/config/entry/jobs_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Config::Entry::Jobs do
diff --git a/spec/lib/gitlab/ci/config/entry/key_spec.rb b/spec/lib/gitlab/ci/config/entry/key_spec.rb
index 3cbf19bea8b..a7874447725 100644
--- a/spec/lib/gitlab/ci/config/entry/key_spec.rb
+++ b/spec/lib/gitlab/ci/config/entry/key_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Config::Entry::Key do
diff --git a/spec/lib/gitlab/ci/config/entry/paths_spec.rb b/spec/lib/gitlab/ci/config/entry/paths_spec.rb
index 1d9c5ddee9b..221d5ae5863 100644
--- a/spec/lib/gitlab/ci/config/entry/paths_spec.rb
+++ b/spec/lib/gitlab/ci/config/entry/paths_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Config::Entry::Paths do
diff --git a/spec/lib/gitlab/ci/config/entry/policy_spec.rb b/spec/lib/gitlab/ci/config/entry/policy_spec.rb
index fba5671594d..266a27c1e47 100644
--- a/spec/lib/gitlab/ci/config/entry/policy_spec.rb
+++ b/spec/lib/gitlab/ci/config/entry/policy_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'fast_spec_helper'
require 'support/helpers/stub_feature_flags'
require_dependency 'active_model'
diff --git a/spec/lib/gitlab/ci/config/entry/reports_spec.rb b/spec/lib/gitlab/ci/config/entry/reports_spec.rb
index 38943138cbf..3c352c30e55 100644
--- a/spec/lib/gitlab/ci/config/entry/reports_spec.rb
+++ b/spec/lib/gitlab/ci/config/entry/reports_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Config::Entry::Reports do
diff --git a/spec/lib/gitlab/ci/config/entry/retry_spec.rb b/spec/lib/gitlab/ci/config/entry/retry_spec.rb
index 164a9ed4c3d..f9efd2e014d 100644
--- a/spec/lib/gitlab/ci/config/entry/retry_spec.rb
+++ b/spec/lib/gitlab/ci/config/entry/retry_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Config::Entry::Retry do
diff --git a/spec/lib/gitlab/ci/config/entry/root_spec.rb b/spec/lib/gitlab/ci/config/entry/root_spec.rb
index 7a252ed675a..968dbb9c7f2 100644
--- a/spec/lib/gitlab/ci/config/entry/root_spec.rb
+++ b/spec/lib/gitlab/ci/config/entry/root_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Config::Entry::Root do
diff --git a/spec/lib/gitlab/ci/config/entry/script_spec.rb b/spec/lib/gitlab/ci/config/entry/script_spec.rb
index 069eaa26422..d523243d3b6 100644
--- a/spec/lib/gitlab/ci/config/entry/script_spec.rb
+++ b/spec/lib/gitlab/ci/config/entry/script_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Config::Entry::Script do
diff --git a/spec/lib/gitlab/ci/config/entry/service_spec.rb b/spec/lib/gitlab/ci/config/entry/service_spec.rb
index d31866a1987..66cca100688 100644
--- a/spec/lib/gitlab/ci/config/entry/service_spec.rb
+++ b/spec/lib/gitlab/ci/config/entry/service_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Config::Entry::Service do
diff --git a/spec/lib/gitlab/ci/config/entry/services_spec.rb b/spec/lib/gitlab/ci/config/entry/services_spec.rb
index d5a1316f665..764f783b083 100644
--- a/spec/lib/gitlab/ci/config/entry/services_spec.rb
+++ b/spec/lib/gitlab/ci/config/entry/services_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Config::Entry::Services do
diff --git a/spec/lib/gitlab/ci/config/entry/stage_spec.rb b/spec/lib/gitlab/ci/config/entry/stage_spec.rb
index 70c8a0a355a..574fa00575a 100644
--- a/spec/lib/gitlab/ci/config/entry/stage_spec.rb
+++ b/spec/lib/gitlab/ci/config/entry/stage_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Config::Entry::Stage do
diff --git a/spec/lib/gitlab/ci/config/entry/stages_spec.rb b/spec/lib/gitlab/ci/config/entry/stages_spec.rb
index 182c8d867c7..97970522104 100644
--- a/spec/lib/gitlab/ci/config/entry/stages_spec.rb
+++ b/spec/lib/gitlab/ci/config/entry/stages_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Config::Entry::Stages do
diff --git a/spec/lib/gitlab/ci/config/entry/variables_spec.rb b/spec/lib/gitlab/ci/config/entry/variables_spec.rb
index 84bfef9e8ad..1320b366367 100644
--- a/spec/lib/gitlab/ci/config/entry/variables_spec.rb
+++ b/spec/lib/gitlab/ci/config/entry/variables_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Config::Entry::Variables do
diff --git a/spec/lib/gitlab/ci/config/extendable/entry_spec.rb b/spec/lib/gitlab/ci/config/extendable/entry_spec.rb
index d63612053b6..e00104e3c68 100644
--- a/spec/lib/gitlab/ci/config/extendable/entry_spec.rb
+++ b/spec/lib/gitlab/ci/config/extendable/entry_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'fast_spec_helper'
describe Gitlab::Ci::Config::Extendable::Entry do
diff --git a/spec/lib/gitlab/ci/config/extendable_spec.rb b/spec/lib/gitlab/ci/config/extendable_spec.rb
index 90213f6603d..874b224067b 100644
--- a/spec/lib/gitlab/ci/config/extendable_spec.rb
+++ b/spec/lib/gitlab/ci/config/extendable_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'fast_spec_helper'
describe Gitlab::Ci::Config::Extendable do
diff --git a/spec/lib/gitlab/ci/config_spec.rb b/spec/lib/gitlab/ci/config_spec.rb
index 4e8bff3d738..986cde3540a 100644
--- a/spec/lib/gitlab/ci/config_spec.rb
+++ b/spec/lib/gitlab/ci/config_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Config do
diff --git a/spec/lib/gitlab/ci/cron_parser_spec.rb b/spec/lib/gitlab/ci/cron_parser_spec.rb
index 491e3fba9d9..af4e9d687c4 100644
--- a/spec/lib/gitlab/ci/cron_parser_spec.rb
+++ b/spec/lib/gitlab/ci/cron_parser_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::CronParser do
diff --git a/spec/lib/gitlab/ci/mask_secret_spec.rb b/spec/lib/gitlab/ci/mask_secret_spec.rb
index 3789a142248..6607aaae399 100644
--- a/spec/lib/gitlab/ci/mask_secret_spec.rb
+++ b/spec/lib/gitlab/ci/mask_secret_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::MaskSecret do
diff --git a/spec/lib/gitlab/ci/parsers/test/junit_spec.rb b/spec/lib/gitlab/ci/parsers/test/junit_spec.rb
index a49402c7398..8ff60710f67 100644
--- a/spec/lib/gitlab/ci/parsers/test/junit_spec.rb
+++ b/spec/lib/gitlab/ci/parsers/test/junit_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'fast_spec_helper'
describe Gitlab::Ci::Parsers::Test::Junit do
diff --git a/spec/lib/gitlab/ci/pipeline/chain/build_spec.rb b/spec/lib/gitlab/ci/pipeline/chain/build_spec.rb
index 50cb45c39d1..bf9ff922c05 100644
--- a/spec/lib/gitlab/ci/pipeline/chain/build_spec.rb
+++ b/spec/lib/gitlab/ci/pipeline/chain/build_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Pipeline::Chain::Build do
diff --git a/spec/lib/gitlab/ci/pipeline/chain/command_spec.rb b/spec/lib/gitlab/ci/pipeline/chain/command_spec.rb
index 5181e9c1583..5775e934cfd 100644
--- a/spec/lib/gitlab/ci/pipeline/chain/command_spec.rb
+++ b/spec/lib/gitlab/ci/pipeline/chain/command_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Pipeline::Chain::Command do
diff --git a/spec/lib/gitlab/ci/pipeline/chain/create_spec.rb b/spec/lib/gitlab/ci/pipeline/chain/create_spec.rb
index 0edc3f315bb..650ab193997 100644
--- a/spec/lib/gitlab/ci/pipeline/chain/create_spec.rb
+++ b/spec/lib/gitlab/ci/pipeline/chain/create_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Pipeline::Chain::Create do
diff --git a/spec/lib/gitlab/ci/pipeline/chain/populate_spec.rb b/spec/lib/gitlab/ci/pipeline/chain/populate_spec.rb
index 0302e4090cf..417a2d119ff 100644
--- a/spec/lib/gitlab/ci/pipeline/chain/populate_spec.rb
+++ b/spec/lib/gitlab/ci/pipeline/chain/populate_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Pipeline::Chain::Populate do
diff --git a/spec/lib/gitlab/ci/pipeline/chain/sequence_spec.rb b/spec/lib/gitlab/ci/pipeline/chain/sequence_spec.rb
index eca23694a2b..9cb59442dfd 100644
--- a/spec/lib/gitlab/ci/pipeline/chain/sequence_spec.rb
+++ b/spec/lib/gitlab/ci/pipeline/chain/sequence_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Pipeline::Chain::Sequence do
diff --git a/spec/lib/gitlab/ci/pipeline/chain/skip_spec.rb b/spec/lib/gitlab/ci/pipeline/chain/skip_spec.rb
index c7f4fc98ca3..fe46633ed1b 100644
--- a/spec/lib/gitlab/ci/pipeline/chain/skip_spec.rb
+++ b/spec/lib/gitlab/ci/pipeline/chain/skip_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Pipeline::Chain::Skip do
diff --git a/spec/lib/gitlab/ci/pipeline/chain/validate/abilities_spec.rb b/spec/lib/gitlab/ci/pipeline/chain/validate/abilities_spec.rb
index b3e58c3dfdb..ac370433955 100644
--- a/spec/lib/gitlab/ci/pipeline/chain/validate/abilities_spec.rb
+++ b/spec/lib/gitlab/ci/pipeline/chain/validate/abilities_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Pipeline::Chain::Validate::Abilities do
diff --git a/spec/lib/gitlab/ci/pipeline/chain/validate/config_spec.rb b/spec/lib/gitlab/ci/pipeline/chain/validate/config_spec.rb
index 00bbc4c817a..79acd3e4f54 100644
--- a/spec/lib/gitlab/ci/pipeline/chain/validate/config_spec.rb
+++ b/spec/lib/gitlab/ci/pipeline/chain/validate/config_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Pipeline::Chain::Validate::Config do
diff --git a/spec/lib/gitlab/ci/pipeline/chain/validate/repository_spec.rb b/spec/lib/gitlab/ci/pipeline/chain/validate/repository_spec.rb
index 2e8c9d70098..b866355906e 100644
--- a/spec/lib/gitlab/ci/pipeline/chain/validate/repository_spec.rb
+++ b/spec/lib/gitlab/ci/pipeline/chain/validate/repository_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Pipeline::Chain::Validate::Repository do
diff --git a/spec/lib/gitlab/ci/pipeline/duration_spec.rb b/spec/lib/gitlab/ci/pipeline/duration_spec.rb
index 7c9836e2da6..a4984092f35 100644
--- a/spec/lib/gitlab/ci/pipeline/duration_spec.rb
+++ b/spec/lib/gitlab/ci/pipeline/duration_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Pipeline::Duration do
diff --git a/spec/lib/gitlab/ci/pipeline/expression/lexeme/and_spec.rb b/spec/lib/gitlab/ci/pipeline/expression/lexeme/and_spec.rb
index 006ce4d8078..847d613dba3 100644
--- a/spec/lib/gitlab/ci/pipeline/expression/lexeme/and_spec.rb
+++ b/spec/lib/gitlab/ci/pipeline/expression/lexeme/and_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'fast_spec_helper'
require 'rspec-parameterized'
diff --git a/spec/lib/gitlab/ci/pipeline/expression/lexeme/equals_spec.rb b/spec/lib/gitlab/ci/pipeline/expression/lexeme/equals_spec.rb
index fcbd2863289..0e13681a4cf 100644
--- a/spec/lib/gitlab/ci/pipeline/expression/lexeme/equals_spec.rb
+++ b/spec/lib/gitlab/ci/pipeline/expression/lexeme/equals_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Pipeline::Expression::Lexeme::Equals do
diff --git a/spec/lib/gitlab/ci/pipeline/expression/lexeme/matches_spec.rb b/spec/lib/gitlab/ci/pipeline/expression/lexeme/matches_spec.rb
index a6fdec832a3..4e4f1bf6ad3 100644
--- a/spec/lib/gitlab/ci/pipeline/expression/lexeme/matches_spec.rb
+++ b/spec/lib/gitlab/ci/pipeline/expression/lexeme/matches_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'fast_spec_helper'
require_dependency 're2'
diff --git a/spec/lib/gitlab/ci/pipeline/expression/lexeme/not_equals_spec.rb b/spec/lib/gitlab/ci/pipeline/expression/lexeme/not_equals_spec.rb
index 38d30c9035a..a3a48f83b27 100644
--- a/spec/lib/gitlab/ci/pipeline/expression/lexeme/not_equals_spec.rb
+++ b/spec/lib/gitlab/ci/pipeline/expression/lexeme/not_equals_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Pipeline::Expression::Lexeme::NotEquals do
diff --git a/spec/lib/gitlab/ci/pipeline/expression/lexeme/not_matches_spec.rb b/spec/lib/gitlab/ci/pipeline/expression/lexeme/not_matches_spec.rb
index 99110ff8d88..6b81008ffb1 100644
--- a/spec/lib/gitlab/ci/pipeline/expression/lexeme/not_matches_spec.rb
+++ b/spec/lib/gitlab/ci/pipeline/expression/lexeme/not_matches_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'fast_spec_helper'
require_dependency 're2'
diff --git a/spec/lib/gitlab/ci/pipeline/expression/lexeme/null_spec.rb b/spec/lib/gitlab/ci/pipeline/expression/lexeme/null_spec.rb
index b5a59929e11..7013c6bacbb 100644
--- a/spec/lib/gitlab/ci/pipeline/expression/lexeme/null_spec.rb
+++ b/spec/lib/gitlab/ci/pipeline/expression/lexeme/null_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Pipeline::Expression::Lexeme::Null do
diff --git a/spec/lib/gitlab/ci/pipeline/expression/lexeme/or_spec.rb b/spec/lib/gitlab/ci/pipeline/expression/lexeme/or_spec.rb
index d542eebc613..15505ebc82b 100644
--- a/spec/lib/gitlab/ci/pipeline/expression/lexeme/or_spec.rb
+++ b/spec/lib/gitlab/ci/pipeline/expression/lexeme/or_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'fast_spec_helper'
require 'rspec-parameterized'
diff --git a/spec/lib/gitlab/ci/pipeline/expression/lexeme/pattern_spec.rb b/spec/lib/gitlab/ci/pipeline/expression/lexeme/pattern_spec.rb
index 6ce4b321397..2cc25a07417 100644
--- a/spec/lib/gitlab/ci/pipeline/expression/lexeme/pattern_spec.rb
+++ b/spec/lib/gitlab/ci/pipeline/expression/lexeme/pattern_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Pipeline::Expression::Lexeme::Pattern do
diff --git a/spec/lib/gitlab/ci/pipeline/expression/lexeme/string_spec.rb b/spec/lib/gitlab/ci/pipeline/expression/lexeme/string_spec.rb
index f54ef492e6d..2a6b90d127f 100644
--- a/spec/lib/gitlab/ci/pipeline/expression/lexeme/string_spec.rb
+++ b/spec/lib/gitlab/ci/pipeline/expression/lexeme/string_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Pipeline::Expression::Lexeme::String do
diff --git a/spec/lib/gitlab/ci/pipeline/expression/lexeme/variable_spec.rb b/spec/lib/gitlab/ci/pipeline/expression/lexeme/variable_spec.rb
index 599a5411881..29e26930249 100644
--- a/spec/lib/gitlab/ci/pipeline/expression/lexeme/variable_spec.rb
+++ b/spec/lib/gitlab/ci/pipeline/expression/lexeme/variable_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Pipeline::Expression::Lexeme::Variable do
diff --git a/spec/lib/gitlab/ci/pipeline/expression/lexer_spec.rb b/spec/lib/gitlab/ci/pipeline/expression/lexer_spec.rb
index 7c98e729b0b..2b0cee2d6f2 100644
--- a/spec/lib/gitlab/ci/pipeline/expression/lexer_spec.rb
+++ b/spec/lib/gitlab/ci/pipeline/expression/lexer_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Pipeline::Expression::Lexer do
diff --git a/spec/lib/gitlab/ci/pipeline/expression/parser_spec.rb b/spec/lib/gitlab/ci/pipeline/expression/parser_spec.rb
index e88ec5561b6..10adfa18af6 100644
--- a/spec/lib/gitlab/ci/pipeline/expression/parser_spec.rb
+++ b/spec/lib/gitlab/ci/pipeline/expression/parser_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'fast_spec_helper'
describe Gitlab::Ci::Pipeline::Expression::Parser do
diff --git a/spec/lib/gitlab/ci/pipeline/expression/statement_spec.rb b/spec/lib/gitlab/ci/pipeline/expression/statement_spec.rb
index b259ef711aa..79ee4d07e3a 100644
--- a/spec/lib/gitlab/ci/pipeline/expression/statement_spec.rb
+++ b/spec/lib/gitlab/ci/pipeline/expression/statement_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'fast_spec_helper'
require 'rspec-parameterized'
diff --git a/spec/lib/gitlab/ci/pipeline/expression/token_spec.rb b/spec/lib/gitlab/ci/pipeline/expression/token_spec.rb
index cedfe270f9d..aa807cecb72 100644
--- a/spec/lib/gitlab/ci/pipeline/expression/token_spec.rb
+++ b/spec/lib/gitlab/ci/pipeline/expression/token_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'fast_spec_helper'
describe Gitlab::Ci::Pipeline::Expression::Token do
diff --git a/spec/lib/gitlab/ci/pipeline/seed/stage_spec.rb b/spec/lib/gitlab/ci/pipeline/seed/stage_spec.rb
index 493ca3cd7b5..ad864d0d56e 100644
--- a/spec/lib/gitlab/ci/pipeline/seed/stage_spec.rb
+++ b/spec/lib/gitlab/ci/pipeline/seed/stage_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Pipeline::Seed::Stage do
diff --git a/spec/lib/gitlab/ci/reports/test_case_spec.rb b/spec/lib/gitlab/ci/reports/test_case_spec.rb
index 6932f79f0ce..20c489ee94c 100644
--- a/spec/lib/gitlab/ci/reports/test_case_spec.rb
+++ b/spec/lib/gitlab/ci/reports/test_case_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Reports::TestCase do
diff --git a/spec/lib/gitlab/ci/reports/test_reports_comparer_spec.rb b/spec/lib/gitlab/ci/reports/test_reports_comparer_spec.rb
index 36582204cc1..48eef0643b2 100644
--- a/spec/lib/gitlab/ci/reports/test_reports_comparer_spec.rb
+++ b/spec/lib/gitlab/ci/reports/test_reports_comparer_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Reports::TestReportsComparer do
diff --git a/spec/lib/gitlab/ci/reports/test_reports_spec.rb b/spec/lib/gitlab/ci/reports/test_reports_spec.rb
index 74ff134b239..0b5d05bada3 100644
--- a/spec/lib/gitlab/ci/reports/test_reports_spec.rb
+++ b/spec/lib/gitlab/ci/reports/test_reports_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Reports::TestReports do
diff --git a/spec/lib/gitlab/ci/reports/test_suite_comparer_spec.rb b/spec/lib/gitlab/ci/reports/test_suite_comparer_spec.rb
index 579b3e6fd24..cf4690bb334 100644
--- a/spec/lib/gitlab/ci/reports/test_suite_comparer_spec.rb
+++ b/spec/lib/gitlab/ci/reports/test_suite_comparer_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Reports::TestSuiteComparer do
diff --git a/spec/lib/gitlab/ci/reports/test_suite_spec.rb b/spec/lib/gitlab/ci/reports/test_suite_spec.rb
index cd34dbaf62f..8646db43bc8 100644
--- a/spec/lib/gitlab/ci/reports/test_suite_spec.rb
+++ b/spec/lib/gitlab/ci/reports/test_suite_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Reports::TestSuite do
diff --git a/spec/lib/gitlab/ci/status/build/action_spec.rb b/spec/lib/gitlab/ci/status/build/action_spec.rb
index bdec582b57b..3aae7e18d6d 100644
--- a/spec/lib/gitlab/ci/status/build/action_spec.rb
+++ b/spec/lib/gitlab/ci/status/build/action_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Status::Build::Action do
diff --git a/spec/lib/gitlab/ci/status/build/cancelable_spec.rb b/spec/lib/gitlab/ci/status/build/cancelable_spec.rb
index 78d6fa65b5a..3841dae91c7 100644
--- a/spec/lib/gitlab/ci/status/build/cancelable_spec.rb
+++ b/spec/lib/gitlab/ci/status/build/cancelable_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Status::Build::Cancelable do
diff --git a/spec/lib/gitlab/ci/status/build/canceled_spec.rb b/spec/lib/gitlab/ci/status/build/canceled_spec.rb
index c6b5cc68770..4b43c78f1a7 100644
--- a/spec/lib/gitlab/ci/status/build/canceled_spec.rb
+++ b/spec/lib/gitlab/ci/status/build/canceled_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Status::Build::Canceled do
diff --git a/spec/lib/gitlab/ci/status/build/common_spec.rb b/spec/lib/gitlab/ci/status/build/common_spec.rb
index ca3c66f0152..5114540708f 100644
--- a/spec/lib/gitlab/ci/status/build/common_spec.rb
+++ b/spec/lib/gitlab/ci/status/build/common_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Status::Build::Common do
diff --git a/spec/lib/gitlab/ci/status/build/created_spec.rb b/spec/lib/gitlab/ci/status/build/created_spec.rb
index 8bdfe6ef7a2..6e3aa442810 100644
--- a/spec/lib/gitlab/ci/status/build/created_spec.rb
+++ b/spec/lib/gitlab/ci/status/build/created_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Status::Build::Created do
diff --git a/spec/lib/gitlab/ci/status/build/erased_spec.rb b/spec/lib/gitlab/ci/status/build/erased_spec.rb
index 0acd271e375..af9c296da0c 100644
--- a/spec/lib/gitlab/ci/status/build/erased_spec.rb
+++ b/spec/lib/gitlab/ci/status/build/erased_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Status::Build::Erased do
diff --git a/spec/lib/gitlab/ci/status/build/factory_spec.rb b/spec/lib/gitlab/ci/status/build/factory_spec.rb
index b6231510b91..de489fa4664 100644
--- a/spec/lib/gitlab/ci/status/build/factory_spec.rb
+++ b/spec/lib/gitlab/ci/status/build/factory_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Status::Build::Factory do
diff --git a/spec/lib/gitlab/ci/status/build/failed_allowed_spec.rb b/spec/lib/gitlab/ci/status/build/failed_allowed_spec.rb
index 2a5915d75d0..01500689619 100644
--- a/spec/lib/gitlab/ci/status/build/failed_allowed_spec.rb
+++ b/spec/lib/gitlab/ci/status/build/failed_allowed_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Status::Build::FailedAllowed do
diff --git a/spec/lib/gitlab/ci/status/build/failed_spec.rb b/spec/lib/gitlab/ci/status/build/failed_spec.rb
index e424270f7c5..78f5214ca81 100644
--- a/spec/lib/gitlab/ci/status/build/failed_spec.rb
+++ b/spec/lib/gitlab/ci/status/build/failed_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Status::Build::Failed do
diff --git a/spec/lib/gitlab/ci/status/build/failed_unmet_prerequisites_spec.rb b/spec/lib/gitlab/ci/status/build/failed_unmet_prerequisites_spec.rb
index a4854bdc6b9..19a3c82eac7 100644
--- a/spec/lib/gitlab/ci/status/build/failed_unmet_prerequisites_spec.rb
+++ b/spec/lib/gitlab/ci/status/build/failed_unmet_prerequisites_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
RSpec.describe Gitlab::Ci::Status::Build::FailedUnmetPrerequisites do
diff --git a/spec/lib/gitlab/ci/status/build/manual_spec.rb b/spec/lib/gitlab/ci/status/build/manual_spec.rb
index 6386296f992..bffe2c10d12 100644
--- a/spec/lib/gitlab/ci/status/build/manual_spec.rb
+++ b/spec/lib/gitlab/ci/status/build/manual_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Status::Build::Manual do
diff --git a/spec/lib/gitlab/ci/status/build/pending_spec.rb b/spec/lib/gitlab/ci/status/build/pending_spec.rb
index 4cf70828e53..64d57954c15 100644
--- a/spec/lib/gitlab/ci/status/build/pending_spec.rb
+++ b/spec/lib/gitlab/ci/status/build/pending_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Status::Build::Pending do
diff --git a/spec/lib/gitlab/ci/status/build/play_spec.rb b/spec/lib/gitlab/ci/status/build/play_spec.rb
index 02f8c4c114b..bb12a900b55 100644
--- a/spec/lib/gitlab/ci/status/build/play_spec.rb
+++ b/spec/lib/gitlab/ci/status/build/play_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Status::Build::Play do
diff --git a/spec/lib/gitlab/ci/status/build/retried_spec.rb b/spec/lib/gitlab/ci/status/build/retried_spec.rb
index 76c2fb01e3f..fce497d40a1 100644
--- a/spec/lib/gitlab/ci/status/build/retried_spec.rb
+++ b/spec/lib/gitlab/ci/status/build/retried_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Status::Build::Retried do
diff --git a/spec/lib/gitlab/ci/status/build/retryable_spec.rb b/spec/lib/gitlab/ci/status/build/retryable_spec.rb
index 84d98588f2d..5b0ae315927 100644
--- a/spec/lib/gitlab/ci/status/build/retryable_spec.rb
+++ b/spec/lib/gitlab/ci/status/build/retryable_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Status::Build::Retryable do
diff --git a/spec/lib/gitlab/ci/status/build/scheduled_spec.rb b/spec/lib/gitlab/ci/status/build/scheduled_spec.rb
index 68b87fea75d..8f87da10815 100644
--- a/spec/lib/gitlab/ci/status/build/scheduled_spec.rb
+++ b/spec/lib/gitlab/ci/status/build/scheduled_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Status::Build::Scheduled do
diff --git a/spec/lib/gitlab/ci/status/build/skipped_spec.rb b/spec/lib/gitlab/ci/status/build/skipped_spec.rb
index 46f6933025a..7ce5142da78 100644
--- a/spec/lib/gitlab/ci/status/build/skipped_spec.rb
+++ b/spec/lib/gitlab/ci/status/build/skipped_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Status::Build::Skipped do
diff --git a/spec/lib/gitlab/ci/status/build/stop_spec.rb b/spec/lib/gitlab/ci/status/build/stop_spec.rb
index 5b7534c96c1..d3e98400a53 100644
--- a/spec/lib/gitlab/ci/status/build/stop_spec.rb
+++ b/spec/lib/gitlab/ci/status/build/stop_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Status::Build::Stop do
diff --git a/spec/lib/gitlab/ci/status/build/unschedule_spec.rb b/spec/lib/gitlab/ci/status/build/unschedule_spec.rb
index ed046d66ca5..c18fc3252b4 100644
--- a/spec/lib/gitlab/ci/status/build/unschedule_spec.rb
+++ b/spec/lib/gitlab/ci/status/build/unschedule_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Status::Build::Unschedule do
diff --git a/spec/lib/gitlab/ci/status/canceled_spec.rb b/spec/lib/gitlab/ci/status/canceled_spec.rb
index dc74d7e28c5..6cfcea4fdde 100644
--- a/spec/lib/gitlab/ci/status/canceled_spec.rb
+++ b/spec/lib/gitlab/ci/status/canceled_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Status::Canceled do
diff --git a/spec/lib/gitlab/ci/status/created_spec.rb b/spec/lib/gitlab/ci/status/created_spec.rb
index ce4333f2aca..aeb41e9cfc3 100644
--- a/spec/lib/gitlab/ci/status/created_spec.rb
+++ b/spec/lib/gitlab/ci/status/created_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Status::Created do
diff --git a/spec/lib/gitlab/ci/status/extended_spec.rb b/spec/lib/gitlab/ci/status/extended_spec.rb
index 6eacb07078b..8accfc4a2f9 100644
--- a/spec/lib/gitlab/ci/status/extended_spec.rb
+++ b/spec/lib/gitlab/ci/status/extended_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Status::Extended do
diff --git a/spec/lib/gitlab/ci/status/external/common_spec.rb b/spec/lib/gitlab/ci/status/external/common_spec.rb
index 0d02c371a92..983522fa2d6 100644
--- a/spec/lib/gitlab/ci/status/external/common_spec.rb
+++ b/spec/lib/gitlab/ci/status/external/common_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Status::External::Common do
diff --git a/spec/lib/gitlab/ci/status/external/factory_spec.rb b/spec/lib/gitlab/ci/status/external/factory_spec.rb
index 529d02a3e39..3b90fb60cca 100644
--- a/spec/lib/gitlab/ci/status/external/factory_spec.rb
+++ b/spec/lib/gitlab/ci/status/external/factory_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Status::External::Factory do
diff --git a/spec/lib/gitlab/ci/status/factory_spec.rb b/spec/lib/gitlab/ci/status/factory_spec.rb
index bbf9c7c83a3..b51c0bec47e 100644
--- a/spec/lib/gitlab/ci/status/factory_spec.rb
+++ b/spec/lib/gitlab/ci/status/factory_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Status::Factory do
diff --git a/spec/lib/gitlab/ci/status/failed_spec.rb b/spec/lib/gitlab/ci/status/failed_spec.rb
index a4a92117c7f..5c7393fc8cf 100644
--- a/spec/lib/gitlab/ci/status/failed_spec.rb
+++ b/spec/lib/gitlab/ci/status/failed_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Status::Failed do
diff --git a/spec/lib/gitlab/ci/status/group/common_spec.rb b/spec/lib/gitlab/ci/status/group/common_spec.rb
index c0ca05881f5..35fff30ea9d 100644
--- a/spec/lib/gitlab/ci/status/group/common_spec.rb
+++ b/spec/lib/gitlab/ci/status/group/common_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Status::Group::Common do
diff --git a/spec/lib/gitlab/ci/status/group/factory_spec.rb b/spec/lib/gitlab/ci/status/group/factory_spec.rb
index 0cd83123938..be76a1d5a65 100644
--- a/spec/lib/gitlab/ci/status/group/factory_spec.rb
+++ b/spec/lib/gitlab/ci/status/group/factory_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Status::Group::Factory do
diff --git a/spec/lib/gitlab/ci/status/manual_spec.rb b/spec/lib/gitlab/ci/status/manual_spec.rb
index 0463f2e1aff..0839452ec22 100644
--- a/spec/lib/gitlab/ci/status/manual_spec.rb
+++ b/spec/lib/gitlab/ci/status/manual_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Status::Manual do
diff --git a/spec/lib/gitlab/ci/status/pending_spec.rb b/spec/lib/gitlab/ci/status/pending_spec.rb
index 0e25358dd8a..5f830e5bb56 100644
--- a/spec/lib/gitlab/ci/status/pending_spec.rb
+++ b/spec/lib/gitlab/ci/status/pending_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Status::Pending do
diff --git a/spec/lib/gitlab/ci/status/pipeline/blocked_spec.rb b/spec/lib/gitlab/ci/status/pipeline/blocked_spec.rb
index 1a2b952d374..876ba712d05 100644
--- a/spec/lib/gitlab/ci/status/pipeline/blocked_spec.rb
+++ b/spec/lib/gitlab/ci/status/pipeline/blocked_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Status::Pipeline::Blocked do
diff --git a/spec/lib/gitlab/ci/status/pipeline/common_spec.rb b/spec/lib/gitlab/ci/status/pipeline/common_spec.rb
index 57df8325635..d3251d138b8 100644
--- a/spec/lib/gitlab/ci/status/pipeline/common_spec.rb
+++ b/spec/lib/gitlab/ci/status/pipeline/common_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Status::Pipeline::Common do
diff --git a/spec/lib/gitlab/ci/status/pipeline/delayed_spec.rb b/spec/lib/gitlab/ci/status/pipeline/delayed_spec.rb
index f89712d2b03..90b797965b3 100644
--- a/spec/lib/gitlab/ci/status/pipeline/delayed_spec.rb
+++ b/spec/lib/gitlab/ci/status/pipeline/delayed_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Status::Pipeline::Delayed do
diff --git a/spec/lib/gitlab/ci/status/pipeline/factory_spec.rb b/spec/lib/gitlab/ci/status/pipeline/factory_spec.rb
index 466087a0e31..8a36cd1b658 100644
--- a/spec/lib/gitlab/ci/status/pipeline/factory_spec.rb
+++ b/spec/lib/gitlab/ci/status/pipeline/factory_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Status::Pipeline::Factory do
diff --git a/spec/lib/gitlab/ci/status/running_spec.rb b/spec/lib/gitlab/ci/status/running_spec.rb
index 9c9d431bb5d..75ff58c5c98 100644
--- a/spec/lib/gitlab/ci/status/running_spec.rb
+++ b/spec/lib/gitlab/ci/status/running_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Status::Running do
diff --git a/spec/lib/gitlab/ci/status/scheduled_spec.rb b/spec/lib/gitlab/ci/status/scheduled_spec.rb
index b8ca3caa1f7..a0374e1a87b 100644
--- a/spec/lib/gitlab/ci/status/scheduled_spec.rb
+++ b/spec/lib/gitlab/ci/status/scheduled_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Status::Scheduled do
diff --git a/spec/lib/gitlab/ci/status/skipped_spec.rb b/spec/lib/gitlab/ci/status/skipped_spec.rb
index 63694ca0ea6..7f68d4a2fa9 100644
--- a/spec/lib/gitlab/ci/status/skipped_spec.rb
+++ b/spec/lib/gitlab/ci/status/skipped_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Status::Skipped do
diff --git a/spec/lib/gitlab/ci/status/stage/common_spec.rb b/spec/lib/gitlab/ci/status/stage/common_spec.rb
index bb2d0a2c75c..26ff0e901fd 100644
--- a/spec/lib/gitlab/ci/status/stage/common_spec.rb
+++ b/spec/lib/gitlab/ci/status/stage/common_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Status::Stage::Common do
diff --git a/spec/lib/gitlab/ci/status/stage/factory_spec.rb b/spec/lib/gitlab/ci/status/stage/factory_spec.rb
index 4b299170c87..8f5b1ff62a5 100644
--- a/spec/lib/gitlab/ci/status/stage/factory_spec.rb
+++ b/spec/lib/gitlab/ci/status/stage/factory_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Status::Stage::Factory do
diff --git a/spec/lib/gitlab/ci/status/success_spec.rb b/spec/lib/gitlab/ci/status/success_spec.rb
index 2f67df71c4f..d4b3a9f12cc 100644
--- a/spec/lib/gitlab/ci/status/success_spec.rb
+++ b/spec/lib/gitlab/ci/status/success_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Status::Success do
diff --git a/spec/lib/gitlab/ci/status/success_warning_spec.rb b/spec/lib/gitlab/ci/status/success_warning_spec.rb
index 9493b1d89f2..af952011e21 100644
--- a/spec/lib/gitlab/ci/status/success_warning_spec.rb
+++ b/spec/lib/gitlab/ci/status/success_warning_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Status::SuccessWarning do
diff --git a/spec/lib/gitlab/ci/trace/chunked_io_spec.rb b/spec/lib/gitlab/ci/trace/chunked_io_spec.rb
index 3e5cd81f929..e0077a5280a 100644
--- a/spec/lib/gitlab/ci/trace/chunked_io_spec.rb
+++ b/spec/lib/gitlab/ci/trace/chunked_io_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Trace::ChunkedIO, :clean_gitlab_redis_cache do
@@ -312,7 +314,7 @@ describe Gitlab::Ci::Trace::ChunkedIO, :clean_gitlab_redis_cache do
end
context 'when utf-8 is being used' do
- let(:sample_trace_raw) { sample_trace_raw_utf8.force_encoding(Encoding::BINARY) }
+ let(:sample_trace_raw) { sample_trace_raw_utf8.dup.force_encoding(Encoding::BINARY) }
let(:sample_trace_raw_utf8) { "😺\n😺\n😺\n😺" }
before do
diff --git a/spec/lib/gitlab/ci/trace/section_parser_spec.rb b/spec/lib/gitlab/ci/trace/section_parser_spec.rb
index ca53ff87c6f..5e2efe083be 100644
--- a/spec/lib/gitlab/ci/trace/section_parser_spec.rb
+++ b/spec/lib/gitlab/ci/trace/section_parser_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Trace::SectionParser do
diff --git a/spec/lib/gitlab/ci/trace_spec.rb b/spec/lib/gitlab/ci/trace_spec.rb
index d6510649dba..f7bc5686b68 100644
--- a/spec/lib/gitlab/ci/trace_spec.rb
+++ b/spec/lib/gitlab/ci/trace_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Trace, :clean_gitlab_redis_shared_state do
diff --git a/spec/lib/gitlab/ci/variables/collection/item_spec.rb b/spec/lib/gitlab/ci/variables/collection/item_spec.rb
index 613814df23f..1bdca753cd3 100644
--- a/spec/lib/gitlab/ci/variables/collection/item_spec.rb
+++ b/spec/lib/gitlab/ci/variables/collection/item_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Variables::Collection::Item do
diff --git a/spec/lib/gitlab/ci/variables/collection_spec.rb b/spec/lib/gitlab/ci/variables/collection_spec.rb
index 8e732d44d5d..59b9f7d4fb9 100644
--- a/spec/lib/gitlab/ci/variables/collection_spec.rb
+++ b/spec/lib/gitlab/ci/variables/collection_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Ci::Variables::Collection do
diff --git a/spec/lib/gitlab/ci/yaml_processor_spec.rb b/spec/lib/gitlab/ci/yaml_processor_spec.rb
index 789d6813d5b..fc9d4f97bda 100644
--- a/spec/lib/gitlab/ci/yaml_processor_spec.rb
+++ b/spec/lib/gitlab/ci/yaml_processor_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
module Gitlab
diff --git a/spec/lib/gitlab/ci_access_spec.rb b/spec/lib/gitlab/ci_access_spec.rb
index 75b90e76083..3c68d209eb6 100644
--- a/spec/lib/gitlab/ci_access_spec.rb
+++ b/spec/lib/gitlab/ci_access_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::CiAccess do
diff --git a/spec/lib/gitlab/closing_issue_extractor_spec.rb b/spec/lib/gitlab/closing_issue_extractor_spec.rb
index 44568f2a653..fdd01f58c9d 100644
--- a/spec/lib/gitlab/closing_issue_extractor_spec.rb
+++ b/spec/lib/gitlab/closing_issue_extractor_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::ClosingIssueExtractor do
diff --git a/spec/lib/gitlab/color_schemes_spec.rb b/spec/lib/gitlab/color_schemes_spec.rb
index c7be45dbcd3..ba5573f6901 100644
--- a/spec/lib/gitlab/color_schemes_spec.rb
+++ b/spec/lib/gitlab/color_schemes_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::ColorSchemes do
diff --git a/spec/lib/gitlab/config/entry/attributable_spec.rb b/spec/lib/gitlab/config/entry/attributable_spec.rb
index abb4fff3ad7..82614bb8238 100644
--- a/spec/lib/gitlab/config/entry/attributable_spec.rb
+++ b/spec/lib/gitlab/config/entry/attributable_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Config::Entry::Attributable do
diff --git a/spec/lib/gitlab/config/entry/boolean_spec.rb b/spec/lib/gitlab/config/entry/boolean_spec.rb
index 1b7a3f850ec..0b8b720dd80 100644
--- a/spec/lib/gitlab/config/entry/boolean_spec.rb
+++ b/spec/lib/gitlab/config/entry/boolean_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Config::Entry::Boolean do
diff --git a/spec/lib/gitlab/config/entry/configurable_spec.rb b/spec/lib/gitlab/config/entry/configurable_spec.rb
index 62dbf20ddf8..8c3a4490d08 100644
--- a/spec/lib/gitlab/config/entry/configurable_spec.rb
+++ b/spec/lib/gitlab/config/entry/configurable_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Config::Entry::Configurable do
diff --git a/spec/lib/gitlab/config/entry/factory_spec.rb b/spec/lib/gitlab/config/entry/factory_spec.rb
index 42f8be8e141..a614ef56a78 100644
--- a/spec/lib/gitlab/config/entry/factory_spec.rb
+++ b/spec/lib/gitlab/config/entry/factory_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Config::Entry::Factory do
diff --git a/spec/lib/gitlab/config/entry/simplifiable_spec.rb b/spec/lib/gitlab/config/entry/simplifiable_spec.rb
index bc8387ada67..65e18fe3f10 100644
--- a/spec/lib/gitlab/config/entry/simplifiable_spec.rb
+++ b/spec/lib/gitlab/config/entry/simplifiable_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Config::Entry::Simplifiable do
diff --git a/spec/lib/gitlab/config/entry/undefined_spec.rb b/spec/lib/gitlab/config/entry/undefined_spec.rb
index 48f9d276c95..83c3a6aec72 100644
--- a/spec/lib/gitlab/config/entry/undefined_spec.rb
+++ b/spec/lib/gitlab/config/entry/undefined_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Config::Entry::Undefined do
diff --git a/spec/lib/gitlab/config/entry/unspecified_spec.rb b/spec/lib/gitlab/config/entry/unspecified_spec.rb
index 64421824a12..32c52594ecf 100644
--- a/spec/lib/gitlab/config/entry/unspecified_spec.rb
+++ b/spec/lib/gitlab/config/entry/unspecified_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Config::Entry::Unspecified do
diff --git a/spec/lib/gitlab/config/entry/validatable_spec.rb b/spec/lib/gitlab/config/entry/validatable_spec.rb
index 5a8f9766d23..925db3594ba 100644
--- a/spec/lib/gitlab/config/entry/validatable_spec.rb
+++ b/spec/lib/gitlab/config/entry/validatable_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Config::Entry::Validatable do
diff --git a/spec/lib/gitlab/config/entry/validator_spec.rb b/spec/lib/gitlab/config/entry/validator_spec.rb
index efa16c4265c..7bf350912df 100644
--- a/spec/lib/gitlab/config/entry/validator_spec.rb
+++ b/spec/lib/gitlab/config/entry/validator_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Config::Entry::Validator do
diff --git a/spec/lib/gitlab/config/loader/yaml_spec.rb b/spec/lib/gitlab/config/loader/yaml_spec.rb
index 0affeb01f6a..ccddf340c3d 100644
--- a/spec/lib/gitlab/config/loader/yaml_spec.rb
+++ b/spec/lib/gitlab/config/loader/yaml_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Config::Loader::Yaml do
diff --git a/spec/lib/gitlab/conflict/file_collection_spec.rb b/spec/lib/gitlab/conflict/file_collection_spec.rb
index c93912db411..f3cdb1a9e59 100644
--- a/spec/lib/gitlab/conflict/file_collection_spec.rb
+++ b/spec/lib/gitlab/conflict/file_collection_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Conflict::FileCollection do
diff --git a/spec/lib/gitlab/conflict/file_spec.rb b/spec/lib/gitlab/conflict/file_spec.rb
index a955ce54e85..adf5a232a75 100644
--- a/spec/lib/gitlab/conflict/file_spec.rb
+++ b/spec/lib/gitlab/conflict/file_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Conflict::File do
diff --git a/spec/lib/gitlab/contributions_calendar_spec.rb b/spec/lib/gitlab/contributions_calendar_spec.rb
index 51e5bdc6307..1154f029a8d 100644
--- a/spec/lib/gitlab/contributions_calendar_spec.rb
+++ b/spec/lib/gitlab/contributions_calendar_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::ContributionsCalendar do
diff --git a/spec/lib/gitlab/cross_project_access/check_collection_spec.rb b/spec/lib/gitlab/cross_project_access/check_collection_spec.rb
index a9e7575240e..1aa5480b670 100644
--- a/spec/lib/gitlab/cross_project_access/check_collection_spec.rb
+++ b/spec/lib/gitlab/cross_project_access/check_collection_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::CrossProjectAccess::CheckCollection do
diff --git a/spec/lib/gitlab/cross_project_access/check_info_spec.rb b/spec/lib/gitlab/cross_project_access/check_info_spec.rb
index ea7393a7006..7d2471b6327 100644
--- a/spec/lib/gitlab/cross_project_access/check_info_spec.rb
+++ b/spec/lib/gitlab/cross_project_access/check_info_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::CrossProjectAccess::CheckInfo do
diff --git a/spec/lib/gitlab/cross_project_access/class_methods_spec.rb b/spec/lib/gitlab/cross_project_access/class_methods_spec.rb
index 5349685e633..17d265542dd 100644
--- a/spec/lib/gitlab/cross_project_access/class_methods_spec.rb
+++ b/spec/lib/gitlab/cross_project_access/class_methods_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::CrossProjectAccess::ClassMethods do
diff --git a/spec/lib/gitlab/cross_project_access_spec.rb b/spec/lib/gitlab/cross_project_access_spec.rb
index 614b0473c7e..ce18d207413 100644
--- a/spec/lib/gitlab/cross_project_access_spec.rb
+++ b/spec/lib/gitlab/cross_project_access_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::CrossProjectAccess do
diff --git a/spec/lib/gitlab/crypto_helper_spec.rb b/spec/lib/gitlab/crypto_helper_spec.rb
index 05cc6cf15de..71bbeccb17b 100644
--- a/spec/lib/gitlab/crypto_helper_spec.rb
+++ b/spec/lib/gitlab/crypto_helper_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::CryptoHelper do
diff --git a/spec/lib/gitlab/current_settings_spec.rb b/spec/lib/gitlab/current_settings_spec.rb
index db31e5280a3..2759412add8 100644
--- a/spec/lib/gitlab/current_settings_spec.rb
+++ b/spec/lib/gitlab/current_settings_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::CurrentSettings do
diff --git a/spec/lib/gitlab/cycle_analytics/base_event_fetcher_spec.rb b/spec/lib/gitlab/cycle_analytics/base_event_fetcher_spec.rb
index b7a64adc2ff..3eea791d61a 100644
--- a/spec/lib/gitlab/cycle_analytics/base_event_fetcher_spec.rb
+++ b/spec/lib/gitlab/cycle_analytics/base_event_fetcher_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::CycleAnalytics::BaseEventFetcher do
diff --git a/spec/lib/gitlab/cycle_analytics/code_event_fetcher_spec.rb b/spec/lib/gitlab/cycle_analytics/code_event_fetcher_spec.rb
index 0267e8c2f69..b521ad0c6ea 100644
--- a/spec/lib/gitlab/cycle_analytics/code_event_fetcher_spec.rb
+++ b/spec/lib/gitlab/cycle_analytics/code_event_fetcher_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
require 'lib/gitlab/cycle_analytics/shared_event_spec'
diff --git a/spec/lib/gitlab/cycle_analytics/code_stage_spec.rb b/spec/lib/gitlab/cycle_analytics/code_stage_spec.rb
index 933f3c7896e..dd1d9ac0f16 100644
--- a/spec/lib/gitlab/cycle_analytics/code_stage_spec.rb
+++ b/spec/lib/gitlab/cycle_analytics/code_stage_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
require 'lib/gitlab/cycle_analytics/shared_stage_spec'
diff --git a/spec/lib/gitlab/cycle_analytics/events_spec.rb b/spec/lib/gitlab/cycle_analytics/events_spec.rb
index 5ee02650e49..a163de07967 100644
--- a/spec/lib/gitlab/cycle_analytics/events_spec.rb
+++ b/spec/lib/gitlab/cycle_analytics/events_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe 'cycle analytics events' do
diff --git a/spec/lib/gitlab/cycle_analytics/issue_event_fetcher_spec.rb b/spec/lib/gitlab/cycle_analytics/issue_event_fetcher_spec.rb
index fd9fa2fee49..afb7b6a13b0 100644
--- a/spec/lib/gitlab/cycle_analytics/issue_event_fetcher_spec.rb
+++ b/spec/lib/gitlab/cycle_analytics/issue_event_fetcher_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
require 'lib/gitlab/cycle_analytics/shared_event_spec'
diff --git a/spec/lib/gitlab/cycle_analytics/issue_stage_spec.rb b/spec/lib/gitlab/cycle_analytics/issue_stage_spec.rb
index dea17e4f3dc..4dd21239cde 100644
--- a/spec/lib/gitlab/cycle_analytics/issue_stage_spec.rb
+++ b/spec/lib/gitlab/cycle_analytics/issue_stage_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
require 'lib/gitlab/cycle_analytics/shared_stage_spec'
diff --git a/spec/lib/gitlab/cycle_analytics/permissions_spec.rb b/spec/lib/gitlab/cycle_analytics/permissions_spec.rb
index f670c7f6c75..2896e973a43 100644
--- a/spec/lib/gitlab/cycle_analytics/permissions_spec.rb
+++ b/spec/lib/gitlab/cycle_analytics/permissions_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::CycleAnalytics::Permissions do
diff --git a/spec/lib/gitlab/cycle_analytics/plan_event_fetcher_spec.rb b/spec/lib/gitlab/cycle_analytics/plan_event_fetcher_spec.rb
index 2e5dc5b5547..17786cd02c6 100644
--- a/spec/lib/gitlab/cycle_analytics/plan_event_fetcher_spec.rb
+++ b/spec/lib/gitlab/cycle_analytics/plan_event_fetcher_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
require 'lib/gitlab/cycle_analytics/shared_event_spec'
diff --git a/spec/lib/gitlab/cycle_analytics/plan_stage_spec.rb b/spec/lib/gitlab/cycle_analytics/plan_stage_spec.rb
index 3cd1320ca9c..98d2593de66 100644
--- a/spec/lib/gitlab/cycle_analytics/plan_stage_spec.rb
+++ b/spec/lib/gitlab/cycle_analytics/plan_stage_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
require 'lib/gitlab/cycle_analytics/shared_stage_spec'
diff --git a/spec/lib/gitlab/cycle_analytics/production_event_fetcher_spec.rb b/spec/lib/gitlab/cycle_analytics/production_event_fetcher_spec.rb
index 74001181305..3ecfad49acd 100644
--- a/spec/lib/gitlab/cycle_analytics/production_event_fetcher_spec.rb
+++ b/spec/lib/gitlab/cycle_analytics/production_event_fetcher_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
require 'lib/gitlab/cycle_analytics/shared_event_spec'
diff --git a/spec/lib/gitlab/cycle_analytics/production_stage_spec.rb b/spec/lib/gitlab/cycle_analytics/production_stage_spec.rb
index 916684b81eb..4d0cc91a318 100644
--- a/spec/lib/gitlab/cycle_analytics/production_stage_spec.rb
+++ b/spec/lib/gitlab/cycle_analytics/production_stage_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
require 'lib/gitlab/cycle_analytics/shared_stage_spec'
diff --git a/spec/lib/gitlab/cycle_analytics/review_event_fetcher_spec.rb b/spec/lib/gitlab/cycle_analytics/review_event_fetcher_spec.rb
index 4f67c95ed4c..2c2169be58c 100644
--- a/spec/lib/gitlab/cycle_analytics/review_event_fetcher_spec.rb
+++ b/spec/lib/gitlab/cycle_analytics/review_event_fetcher_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
require 'lib/gitlab/cycle_analytics/shared_event_spec'
diff --git a/spec/lib/gitlab/cycle_analytics/review_stage_spec.rb b/spec/lib/gitlab/cycle_analytics/review_stage_spec.rb
index 6d14973c711..0f36a8c5c36 100644
--- a/spec/lib/gitlab/cycle_analytics/review_stage_spec.rb
+++ b/spec/lib/gitlab/cycle_analytics/review_stage_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
require 'lib/gitlab/cycle_analytics/shared_stage_spec'
diff --git a/spec/lib/gitlab/cycle_analytics/shared_event_spec.rb b/spec/lib/gitlab/cycle_analytics/shared_event_spec.rb
index b001a46001e..c053af010b3 100644
--- a/spec/lib/gitlab/cycle_analytics/shared_event_spec.rb
+++ b/spec/lib/gitlab/cycle_analytics/shared_event_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
shared_examples 'default query config' do
diff --git a/spec/lib/gitlab/cycle_analytics/shared_stage_spec.rb b/spec/lib/gitlab/cycle_analytics/shared_stage_spec.rb
index c146146723f..cf95741908f 100644
--- a/spec/lib/gitlab/cycle_analytics/shared_stage_spec.rb
+++ b/spec/lib/gitlab/cycle_analytics/shared_stage_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
shared_examples 'base stage' do
diff --git a/spec/lib/gitlab/cycle_analytics/stage_summary_spec.rb b/spec/lib/gitlab/cycle_analytics/stage_summary_spec.rb
index f8009709ce2..778c2f479b5 100644
--- a/spec/lib/gitlab/cycle_analytics/stage_summary_spec.rb
+++ b/spec/lib/gitlab/cycle_analytics/stage_summary_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::CycleAnalytics::StageSummary do
diff --git a/spec/lib/gitlab/cycle_analytics/staging_event_fetcher_spec.rb b/spec/lib/gitlab/cycle_analytics/staging_event_fetcher_spec.rb
index bbc82496340..016d2e8da5b 100644
--- a/spec/lib/gitlab/cycle_analytics/staging_event_fetcher_spec.rb
+++ b/spec/lib/gitlab/cycle_analytics/staging_event_fetcher_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
require 'lib/gitlab/cycle_analytics/shared_event_spec'
diff --git a/spec/lib/gitlab/cycle_analytics/staging_stage_spec.rb b/spec/lib/gitlab/cycle_analytics/staging_stage_spec.rb
index 9ca12cc448c..bd64c4aca42 100644
--- a/spec/lib/gitlab/cycle_analytics/staging_stage_spec.rb
+++ b/spec/lib/gitlab/cycle_analytics/staging_stage_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
require 'lib/gitlab/cycle_analytics/shared_stage_spec'
diff --git a/spec/lib/gitlab/cycle_analytics/test_event_fetcher_spec.rb b/spec/lib/gitlab/cycle_analytics/test_event_fetcher_spec.rb
index 6639fa54e0e..be7c0e9dd59 100644
--- a/spec/lib/gitlab/cycle_analytics/test_event_fetcher_spec.rb
+++ b/spec/lib/gitlab/cycle_analytics/test_event_fetcher_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
require 'lib/gitlab/cycle_analytics/shared_event_spec'
diff --git a/spec/lib/gitlab/cycle_analytics/test_stage_spec.rb b/spec/lib/gitlab/cycle_analytics/test_stage_spec.rb
index 41028c44a00..9162686d17d 100644
--- a/spec/lib/gitlab/cycle_analytics/test_stage_spec.rb
+++ b/spec/lib/gitlab/cycle_analytics/test_stage_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
require 'lib/gitlab/cycle_analytics/shared_stage_spec'
diff --git a/spec/lib/gitlab/cycle_analytics/updater_spec.rb b/spec/lib/gitlab/cycle_analytics/updater_spec.rb
index eff54cd3692..67f386f9144 100644
--- a/spec/lib/gitlab/cycle_analytics/updater_spec.rb
+++ b/spec/lib/gitlab/cycle_analytics/updater_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::CycleAnalytics::Updater do
diff --git a/spec/lib/gitlab/cycle_analytics/usage_data_spec.rb b/spec/lib/gitlab/cycle_analytics/usage_data_spec.rb
index 258ab049c0b..e568ea633db 100644
--- a/spec/lib/gitlab/cycle_analytics/usage_data_spec.rb
+++ b/spec/lib/gitlab/cycle_analytics/usage_data_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::CycleAnalytics::UsageData do
diff --git a/spec/lib/gitlab/daemon_spec.rb b/spec/lib/gitlab/daemon_spec.rb
index 2bdb0dfc736..d3e73314b87 100644
--- a/spec/lib/gitlab/daemon_spec.rb
+++ b/spec/lib/gitlab/daemon_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Daemon do
diff --git a/spec/lib/gitlab/data_builder/build_spec.rb b/spec/lib/gitlab/data_builder/build_spec.rb
index 14fe196a986..b170ef788d9 100644
--- a/spec/lib/gitlab/data_builder/build_spec.rb
+++ b/spec/lib/gitlab/data_builder/build_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::DataBuilder::Build do
diff --git a/spec/lib/gitlab/data_builder/note_spec.rb b/spec/lib/gitlab/data_builder/note_spec.rb
index 1b5dd2538e0..3c26daba5a5 100644
--- a/spec/lib/gitlab/data_builder/note_spec.rb
+++ b/spec/lib/gitlab/data_builder/note_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::DataBuilder::Note do
diff --git a/spec/lib/gitlab/data_builder/pipeline_spec.rb b/spec/lib/gitlab/data_builder/pipeline_spec.rb
index 1f36fd5c6ef..4afb7195b7b 100644
--- a/spec/lib/gitlab/data_builder/pipeline_spec.rb
+++ b/spec/lib/gitlab/data_builder/pipeline_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::DataBuilder::Pipeline do
diff --git a/spec/lib/gitlab/data_builder/push_spec.rb b/spec/lib/gitlab/data_builder/push_spec.rb
index 46ad674a1eb..cc31f88d365 100644
--- a/spec/lib/gitlab/data_builder/push_spec.rb
+++ b/spec/lib/gitlab/data_builder/push_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::DataBuilder::Push do
diff --git a/spec/lib/gitlab/data_builder/wiki_page_spec.rb b/spec/lib/gitlab/data_builder/wiki_page_spec.rb
index 9c8bdf4b032..404d54bf2da 100644
--- a/spec/lib/gitlab/data_builder/wiki_page_spec.rb
+++ b/spec/lib/gitlab/data_builder/wiki_page_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::DataBuilder::WikiPage do
diff --git a/spec/lib/gitlab/database/count/exact_count_strategy_spec.rb b/spec/lib/gitlab/database/count/exact_count_strategy_spec.rb
index 0c1be4b4610..111833a506a 100644
--- a/spec/lib/gitlab/database/count/exact_count_strategy_spec.rb
+++ b/spec/lib/gitlab/database/count/exact_count_strategy_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Database::Count::ExactCountStrategy do
diff --git a/spec/lib/gitlab/database/count/reltuples_count_strategy_spec.rb b/spec/lib/gitlab/database/count/reltuples_count_strategy_spec.rb
index a528707c9dc..08032d19d14 100644
--- a/spec/lib/gitlab/database/count/reltuples_count_strategy_spec.rb
+++ b/spec/lib/gitlab/database/count/reltuples_count_strategy_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Database::Count::ReltuplesCountStrategy do
@@ -8,7 +10,7 @@ describe Gitlab::Database::Count::ReltuplesCountStrategy do
subject { described_class.new(models).count }
- describe '#count', :postgresql do
+ describe '#count' do
let(:models) { [Project, Identity] }
context 'when reltuples is up to date' do
diff --git a/spec/lib/gitlab/database/count/tablesample_count_strategy_spec.rb b/spec/lib/gitlab/database/count/tablesample_count_strategy_spec.rb
index a57f033b5ed..0c480709c22 100644
--- a/spec/lib/gitlab/database/count/tablesample_count_strategy_spec.rb
+++ b/spec/lib/gitlab/database/count/tablesample_count_strategy_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Database::Count::TablesampleCountStrategy do
@@ -12,7 +14,7 @@ describe Gitlab::Database::Count::TablesampleCountStrategy do
subject { strategy.count }
- describe '#count', :postgresql do
+ describe '#count' do
let(:estimates) do
{
Project => threshold + 1,
diff --git a/spec/lib/gitlab/database/count_spec.rb b/spec/lib/gitlab/database/count_spec.rb
index 71d6633f62f..71c25f23b6b 100644
--- a/spec/lib/gitlab/database/count_spec.rb
+++ b/spec/lib/gitlab/database/count_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Database::Count do
diff --git a/spec/lib/gitlab/database/grant_spec.rb b/spec/lib/gitlab/database/grant_spec.rb
index 5ebf3f399b6..02697eb2a16 100644
--- a/spec/lib/gitlab/database/grant_spec.rb
+++ b/spec/lib/gitlab/database/grant_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Database::Grant do
@@ -8,7 +10,7 @@ describe Gitlab::Database::Grant do
expect(described_class.create_and_execute_trigger?('users')).to eq(true)
end
- it 'returns false when the user can not create and/or execute a trigger', :postgresql do
+ it 'returns false when the user can not create and/or execute a trigger' do
# In case of MySQL the user may have SUPER permissions, making it
# impossible to have `false` returned when running tests; hence we only
# run these tests on PostgreSQL.
diff --git a/spec/lib/gitlab/database/migration_helpers_spec.rb b/spec/lib/gitlab/database/migration_helpers_spec.rb
index b73828b9554..2731fc8573f 100644
--- a/spec/lib/gitlab/database/migration_helpers_spec.rb
+++ b/spec/lib/gitlab/database/migration_helpers_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Database::MigrationHelpers do
diff --git a/spec/lib/gitlab/database/multi_threaded_migration_spec.rb b/spec/lib/gitlab/database/multi_threaded_migration_spec.rb
index 6c45f13bb5a..53c001fbc1b 100644
--- a/spec/lib/gitlab/database/multi_threaded_migration_spec.rb
+++ b/spec/lib/gitlab/database/multi_threaded_migration_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Database::MultiThreadedMigration do
diff --git a/spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_base_spec.rb b/spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_base_spec.rb
index 81419e51635..612c418e8bb 100644
--- a/spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_base_spec.rb
+++ b/spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_base_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Database::RenameReservedPathsMigration::V1::RenameBase, :delete do
diff --git a/spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_namespaces_spec.rb b/spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_namespaces_spec.rb
index b6096d4faf6..8c4d7e323fa 100644
--- a/spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_namespaces_spec.rb
+++ b/spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_namespaces_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Database::RenameReservedPathsMigration::V1::RenameNamespaces, :delete do
diff --git a/spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_projects_spec.rb b/spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_projects_spec.rb
index d4d7a83921c..1ccdb1d9447 100644
--- a/spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_projects_spec.rb
+++ b/spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_projects_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Database::RenameReservedPathsMigration::V1::RenameProjects, :delete do
diff --git a/spec/lib/gitlab/database/rename_reserved_paths_migration/v1_spec.rb b/spec/lib/gitlab/database/rename_reserved_paths_migration/v1_spec.rb
index ddd54a669a3..b09258ae227 100644
--- a/spec/lib/gitlab/database/rename_reserved_paths_migration/v1_spec.rb
+++ b/spec/lib/gitlab/database/rename_reserved_paths_migration/v1_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
shared_examples 'renames child namespaces' do |type|
diff --git a/spec/lib/gitlab/database/sha_attribute_spec.rb b/spec/lib/gitlab/database/sha_attribute_spec.rb
index 778bfa2cc47..9dd80e0a229 100644
--- a/spec/lib/gitlab/database/sha_attribute_spec.rb
+++ b/spec/lib/gitlab/database/sha_attribute_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Database::ShaAttribute do
diff --git a/spec/lib/gitlab/database_spec.rb b/spec/lib/gitlab/database_spec.rb
index 9e8712266e8..bdc48934589 100644
--- a/spec/lib/gitlab/database_spec.rb
+++ b/spec/lib/gitlab/database_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Database do
diff --git a/spec/lib/gitlab/dependency_linker/cartfile_linker_spec.rb b/spec/lib/gitlab/dependency_linker/cartfile_linker_spec.rb
index 3a93d5e1e97..3eb5db51224 100644
--- a/spec/lib/gitlab/dependency_linker/cartfile_linker_spec.rb
+++ b/spec/lib/gitlab/dependency_linker/cartfile_linker_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'rails_helper'
describe Gitlab::DependencyLinker::CartfileLinker do
diff --git a/spec/lib/gitlab/dependency_linker/composer_json_linker_spec.rb b/spec/lib/gitlab/dependency_linker/composer_json_linker_spec.rb
index 0ebd8994636..6bef6f57e64 100644
--- a/spec/lib/gitlab/dependency_linker/composer_json_linker_spec.rb
+++ b/spec/lib/gitlab/dependency_linker/composer_json_linker_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'rails_helper'
describe Gitlab::DependencyLinker::ComposerJsonLinker do
diff --git a/spec/lib/gitlab/dependency_linker/gemfile_linker_spec.rb b/spec/lib/gitlab/dependency_linker/gemfile_linker_spec.rb
index f00f6b47b94..6ecdb0d1247 100644
--- a/spec/lib/gitlab/dependency_linker/gemfile_linker_spec.rb
+++ b/spec/lib/gitlab/dependency_linker/gemfile_linker_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'rails_helper'
describe Gitlab::DependencyLinker::GemfileLinker do
diff --git a/spec/lib/gitlab/dependency_linker/gemspec_linker_spec.rb b/spec/lib/gitlab/dependency_linker/gemspec_linker_spec.rb
index 6c6a5d70576..256fe58925c 100644
--- a/spec/lib/gitlab/dependency_linker/gemspec_linker_spec.rb
+++ b/spec/lib/gitlab/dependency_linker/gemspec_linker_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'rails_helper'
describe Gitlab::DependencyLinker::GemspecLinker do
diff --git a/spec/lib/gitlab/dependency_linker/godeps_json_linker_spec.rb b/spec/lib/gitlab/dependency_linker/godeps_json_linker_spec.rb
index ae5ad39ad11..f620d1b590c 100644
--- a/spec/lib/gitlab/dependency_linker/godeps_json_linker_spec.rb
+++ b/spec/lib/gitlab/dependency_linker/godeps_json_linker_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'rails_helper'
describe Gitlab::DependencyLinker::GodepsJsonLinker do
diff --git a/spec/lib/gitlab/dependency_linker/package_json_linker_spec.rb b/spec/lib/gitlab/dependency_linker/package_json_linker_spec.rb
index 9050127af7f..71e9381eaad 100644
--- a/spec/lib/gitlab/dependency_linker/package_json_linker_spec.rb
+++ b/spec/lib/gitlab/dependency_linker/package_json_linker_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'rails_helper'
describe Gitlab::DependencyLinker::PackageJsonLinker do
diff --git a/spec/lib/gitlab/dependency_linker/podfile_linker_spec.rb b/spec/lib/gitlab/dependency_linker/podfile_linker_spec.rb
index 8f1b523653e..eb81bc07760 100644
--- a/spec/lib/gitlab/dependency_linker/podfile_linker_spec.rb
+++ b/spec/lib/gitlab/dependency_linker/podfile_linker_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'rails_helper'
describe Gitlab::DependencyLinker::PodfileLinker do
diff --git a/spec/lib/gitlab/dependency_linker/podspec_json_linker_spec.rb b/spec/lib/gitlab/dependency_linker/podspec_json_linker_spec.rb
index d4a398c5948..938726dd434 100644
--- a/spec/lib/gitlab/dependency_linker/podspec_json_linker_spec.rb
+++ b/spec/lib/gitlab/dependency_linker/podspec_json_linker_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'rails_helper'
describe Gitlab::DependencyLinker::PodspecJsonLinker do
diff --git a/spec/lib/gitlab/dependency_linker/podspec_linker_spec.rb b/spec/lib/gitlab/dependency_linker/podspec_linker_spec.rb
index bacec830103..540eb2fadfe 100644
--- a/spec/lib/gitlab/dependency_linker/podspec_linker_spec.rb
+++ b/spec/lib/gitlab/dependency_linker/podspec_linker_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'rails_helper'
describe Gitlab::DependencyLinker::PodspecLinker do
diff --git a/spec/lib/gitlab/dependency_linker/requirements_txt_linker_spec.rb b/spec/lib/gitlab/dependency_linker/requirements_txt_linker_spec.rb
index ef952b3abd5..957a87985a2 100644
--- a/spec/lib/gitlab/dependency_linker/requirements_txt_linker_spec.rb
+++ b/spec/lib/gitlab/dependency_linker/requirements_txt_linker_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'rails_helper'
describe Gitlab::DependencyLinker::RequirementsTxtLinker do
diff --git a/spec/lib/gitlab/dependency_linker_spec.rb b/spec/lib/gitlab/dependency_linker_spec.rb
index 10d2f701298..98e46d62ca0 100644
--- a/spec/lib/gitlab/dependency_linker_spec.rb
+++ b/spec/lib/gitlab/dependency_linker_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'rails_helper'
describe Gitlab::DependencyLinker do
diff --git a/spec/lib/gitlab/diff/diff_refs_spec.rb b/spec/lib/gitlab/diff/diff_refs_spec.rb
index f9bfb4c469e..e12b46c15ad 100644
--- a/spec/lib/gitlab/diff/diff_refs_spec.rb
+++ b/spec/lib/gitlab/diff/diff_refs_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Diff::DiffRefs do
diff --git a/spec/lib/gitlab/diff/file_collection/merge_request_diff_spec.rb b/spec/lib/gitlab/diff/file_collection/merge_request_diff_spec.rb
index 0697594c725..d89be6fef4e 100644
--- a/spec/lib/gitlab/diff/file_collection/merge_request_diff_spec.rb
+++ b/spec/lib/gitlab/diff/file_collection/merge_request_diff_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Diff::FileCollection::MergeRequestDiff do
diff --git a/spec/lib/gitlab/diff/file_spec.rb b/spec/lib/gitlab/diff/file_spec.rb
index cc36060f864..716fc8ae987 100644
--- a/spec/lib/gitlab/diff/file_spec.rb
+++ b/spec/lib/gitlab/diff/file_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Diff::File do
diff --git a/spec/lib/gitlab/diff/formatters/image_formatter_spec.rb b/spec/lib/gitlab/diff/formatters/image_formatter_spec.rb
index 2f99febe04e..2e6eb71d37d 100644
--- a/spec/lib/gitlab/diff/formatters/image_formatter_spec.rb
+++ b/spec/lib/gitlab/diff/formatters/image_formatter_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Diff::Formatters::ImageFormatter do
diff --git a/spec/lib/gitlab/diff/formatters/text_formatter_spec.rb b/spec/lib/gitlab/diff/formatters/text_formatter_spec.rb
index 897dc917f6a..33d4994f5db 100644
--- a/spec/lib/gitlab/diff/formatters/text_formatter_spec.rb
+++ b/spec/lib/gitlab/diff/formatters/text_formatter_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Diff::Formatters::TextFormatter do
diff --git a/spec/lib/gitlab/diff/highlight_spec.rb b/spec/lib/gitlab/diff/highlight_spec.rb
index 5d0a603d11d..f5d3d14ccc5 100644
--- a/spec/lib/gitlab/diff/highlight_spec.rb
+++ b/spec/lib/gitlab/diff/highlight_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Diff::Highlight do
diff --git a/spec/lib/gitlab/diff/inline_diff_markdown_marker_spec.rb b/spec/lib/gitlab/diff/inline_diff_markdown_marker_spec.rb
index 7e17437fa2a..a668bb464a4 100644
--- a/spec/lib/gitlab/diff/inline_diff_markdown_marker_spec.rb
+++ b/spec/lib/gitlab/diff/inline_diff_markdown_marker_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Diff::InlineDiffMarkdownMarker do
diff --git a/spec/lib/gitlab/diff/inline_diff_marker_spec.rb b/spec/lib/gitlab/diff/inline_diff_marker_spec.rb
index 97e65318059..26b99870b31 100644
--- a/spec/lib/gitlab/diff/inline_diff_marker_spec.rb
+++ b/spec/lib/gitlab/diff/inline_diff_marker_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Diff::InlineDiffMarker do
diff --git a/spec/lib/gitlab/diff/inline_diff_spec.rb b/spec/lib/gitlab/diff/inline_diff_spec.rb
index 0a41362f606..fdbee3b4230 100644
--- a/spec/lib/gitlab/diff/inline_diff_spec.rb
+++ b/spec/lib/gitlab/diff/inline_diff_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Diff::InlineDiff do
diff --git a/spec/lib/gitlab/diff/line_mapper_spec.rb b/spec/lib/gitlab/diff/line_mapper_spec.rb
index 42750bf9ea1..1739bcd14a8 100644
--- a/spec/lib/gitlab/diff/line_mapper_spec.rb
+++ b/spec/lib/gitlab/diff/line_mapper_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Diff::LineMapper do
diff --git a/spec/lib/gitlab/diff/line_spec.rb b/spec/lib/gitlab/diff/line_spec.rb
index 76d411973c7..29b9951ba4c 100644
--- a/spec/lib/gitlab/diff/line_spec.rb
+++ b/spec/lib/gitlab/diff/line_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
describe Gitlab::Diff::Line do
describe '.init_from_hash' do
it 'round-trips correctly with to_hash' do
diff --git a/spec/lib/gitlab/diff/parallel_diff_spec.rb b/spec/lib/gitlab/diff/parallel_diff_spec.rb
index e9fc7be366a..7540da71086 100644
--- a/spec/lib/gitlab/diff/parallel_diff_spec.rb
+++ b/spec/lib/gitlab/diff/parallel_diff_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Diff::ParallelDiff do
diff --git a/spec/lib/gitlab/diff/parser_spec.rb b/spec/lib/gitlab/diff/parser_spec.rb
index 80c8c189665..00a446c4e20 100644
--- a/spec/lib/gitlab/diff/parser_spec.rb
+++ b/spec/lib/gitlab/diff/parser_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Diff::Parser do
diff --git a/spec/lib/gitlab/diff/position_spec.rb b/spec/lib/gitlab/diff/position_spec.rb
index b755cd1aff0..399787635c0 100644
--- a/spec/lib/gitlab/diff/position_spec.rb
+++ b/spec/lib/gitlab/diff/position_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Diff::Position do
diff --git a/spec/lib/gitlab/diff/position_tracer_spec.rb b/spec/lib/gitlab/diff/position_tracer_spec.rb
index 79b33d4d276..47d78e0b18c 100644
--- a/spec/lib/gitlab/diff/position_tracer_spec.rb
+++ b/spec/lib/gitlab/diff/position_tracer_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Diff::PositionTracer do
diff --git a/spec/lib/gitlab/downtime_check/message_spec.rb b/spec/lib/gitlab/downtime_check/message_spec.rb
index a5a398abf78..2beb5a19a32 100644
--- a/spec/lib/gitlab/downtime_check/message_spec.rb
+++ b/spec/lib/gitlab/downtime_check/message_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::DowntimeCheck::Message do
diff --git a/spec/lib/gitlab/downtime_check_spec.rb b/spec/lib/gitlab/downtime_check_spec.rb
index 1f1e4e0216c..56ad49d528f 100644
--- a/spec/lib/gitlab/downtime_check_spec.rb
+++ b/spec/lib/gitlab/downtime_check_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::DowntimeCheck do
diff --git a/spec/lib/gitlab/email/attachment_uploader_spec.rb b/spec/lib/gitlab/email/attachment_uploader_spec.rb
index 45c690842bc..d66a746284d 100644
--- a/spec/lib/gitlab/email/attachment_uploader_spec.rb
+++ b/spec/lib/gitlab/email/attachment_uploader_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require "spec_helper"
describe Gitlab::Email::AttachmentUploader do
diff --git a/spec/lib/gitlab/email/hook/additional_headers_interceptor_spec.rb b/spec/lib/gitlab/email/hook/additional_headers_interceptor_spec.rb
index ae61ece8029..65e4e27d56f 100644
--- a/spec/lib/gitlab/email/hook/additional_headers_interceptor_spec.rb
+++ b/spec/lib/gitlab/email/hook/additional_headers_interceptor_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Email::Hook::AdditionalHeadersInterceptor do
diff --git a/spec/lib/gitlab/email/hook/delivery_metrics_observer_spec.rb b/spec/lib/gitlab/email/hook/delivery_metrics_observer_spec.rb
index 4497d4002da..24da47c42ac 100644
--- a/spec/lib/gitlab/email/hook/delivery_metrics_observer_spec.rb
+++ b/spec/lib/gitlab/email/hook/delivery_metrics_observer_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Email::Hook::DeliveryMetricsObserver do
diff --git a/spec/lib/gitlab/email/hook/disable_email_interceptor_spec.rb b/spec/lib/gitlab/email/hook/disable_email_interceptor_spec.rb
index 91aa3bc7c2e..0c58cf088cc 100644
--- a/spec/lib/gitlab/email/hook/disable_email_interceptor_spec.rb
+++ b/spec/lib/gitlab/email/hook/disable_email_interceptor_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Email::Hook::DisableEmailInterceptor do
diff --git a/spec/lib/gitlab/email/message/repository_push_spec.rb b/spec/lib/gitlab/email/message/repository_push_spec.rb
index 0ec1f931037..84c5b38127e 100644
--- a/spec/lib/gitlab/email/message/repository_push_spec.rb
+++ b/spec/lib/gitlab/email/message/repository_push_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Email::Message::RepositoryPush do
diff --git a/spec/lib/gitlab/email/receiver_spec.rb b/spec/lib/gitlab/email/receiver_spec.rb
index 0af978eced3..c9fde06cbae 100644
--- a/spec/lib/gitlab/email/receiver_spec.rb
+++ b/spec/lib/gitlab/email/receiver_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Email::Receiver do
diff --git a/spec/lib/gitlab/email/reply_parser_spec.rb b/spec/lib/gitlab/email/reply_parser_spec.rb
index 376d3accd55..646575b2edd 100644
--- a/spec/lib/gitlab/email/reply_parser_spec.rb
+++ b/spec/lib/gitlab/email/reply_parser_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require "spec_helper"
# Inspired in great part by Discourse's Email::Receiver
diff --git a/spec/lib/gitlab/encoding_helper_spec.rb b/spec/lib/gitlab/encoding_helper_spec.rb
index 88ea98eb1e1..b24b71522ec 100644
--- a/spec/lib/gitlab/encoding_helper_spec.rb
+++ b/spec/lib/gitlab/encoding_helper_spec.rb
@@ -1,4 +1,6 @@
# coding: utf-8
+# frozen_string_literal: true
+
require "spec_helper"
describe Gitlab::EncodingHelper do
@@ -9,8 +11,8 @@ describe Gitlab::EncodingHelper do
[
["nil", nil, nil],
["empty string", "".encode("ASCII-8BIT"), "".encode("UTF-8")],
- ["invalid utf-8 encoded string", "my bad string\xE5".force_encoding("UTF-8"), "my bad string"],
- ["frozen non-ascii string", "é".force_encoding("ASCII-8BIT").freeze, "é".encode("UTF-8")],
+ ["invalid utf-8 encoded string", (+"my bad string\xE5").force_encoding("UTF-8"), "my bad string"],
+ ["frozen non-ascii string", (+"é").force_encoding("ASCII-8BIT").freeze, "é".encode("UTF-8")],
[
'leaves ascii only string as is',
'ascii only string',
@@ -23,7 +25,7 @@ describe Gitlab::EncodingHelper do
],
[
'removes invalid bytes from ASCII-8bit encoded multibyte string. This can occur when a git diff match line truncates in the middle of a multibyte character. This occurs after the second word in this example. The test string is as short as we can get while still triggering the error condition when not looking at `detect[:confidence]`.',
- "mu ns\xC3\n Lorem ipsum dolor sit amet, consectetur adipisicing ut\xC3\xA0y\xC3\xB9abcd\xC3\xB9efg kia elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non p\n {: .normal_pn}\n \n-Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in\n# *Lorem ipsum\xC3\xB9l\xC3\xB9l\xC3\xA0 dolor\xC3\xB9k\xC3\xB9 sit\xC3\xA8b\xC3\xA8 N\xC3\xA8 amet b\xC3\xA0d\xC3\xAC*\n+# *consectetur\xC3\xB9l\xC3\xB9l\xC3\xA0 adipisicing\xC3\xB9k\xC3\xB9 elit\xC3\xA8b\xC3\xA8 N\xC3\xA8 sed do\xC3\xA0d\xC3\xAC*{: .italic .smcaps}\n \n \xEF\x9B\xA1 eiusmod tempor incididunt, ut\xC3\xAAn\xC3\xB9 labore et dolore. Tw\xC4\x83nj\xC3\xAC magna aliqua. Ut enim ad minim veniam\n {: .normal}\n@@ -9,5 +9,5 @@ quis nostrud\xC3\xAAt\xC3\xB9 exercitiation ullamco laboris m\xC3\xB9s\xC3\xB9k\xC3\xB9abc\xC3\xB9 nisi ".force_encoding('ASCII-8BIT'),
+ (+"mu ns\xC3\n Lorem ipsum dolor sit amet, consectetur adipisicing ut\xC3\xA0y\xC3\xB9abcd\xC3\xB9efg kia elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non p\n {: .normal_pn}\n \n-Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in\n# *Lorem ipsum\xC3\xB9l\xC3\xB9l\xC3\xA0 dolor\xC3\xB9k\xC3\xB9 sit\xC3\xA8b\xC3\xA8 N\xC3\xA8 amet b\xC3\xA0d\xC3\xAC*\n+# *consectetur\xC3\xB9l\xC3\xB9l\xC3\xA0 adipisicing\xC3\xB9k\xC3\xB9 elit\xC3\xA8b\xC3\xA8 N\xC3\xA8 sed do\xC3\xA0d\xC3\xAC*{: .italic .smcaps}\n \n \xEF\x9B\xA1 eiusmod tempor incididunt, ut\xC3\xAAn\xC3\xB9 labore et dolore. Tw\xC4\x83nj\xC3\xAC magna aliqua. Ut enim ad minim veniam\n {: .normal}\n@@ -9,5 +9,5 @@ quis nostrud\xC3\xAAt\xC3\xB9 exercitiation ullamco laboris m\xC3\xB9s\xC3\xB9k\xC3\xB9abc\xC3\xB9 nisi ").force_encoding('ASCII-8BIT'),
"mu ns\n Lorem ipsum dolor sit amet, consectetur adipisicing ut\xC3\xA0y\xC3\xB9abcd\xC3\xB9efg kia elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non p\n {: .normal_pn}\n \n-Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in\n# *Lorem ipsum\xC3\xB9l\xC3\xB9l\xC3\xA0 dolor\xC3\xB9k\xC3\xB9 sit\xC3\xA8b\xC3\xA8 N\xC3\xA8 amet b\xC3\xA0d\xC3\xAC*\n+# *consectetur\xC3\xB9l\xC3\xB9l\xC3\xA0 adipisicing\xC3\xB9k\xC3\xB9 elit\xC3\xA8b\xC3\xA8 N\xC3\xA8 sed do\xC3\xA0d\xC3\xAC*{: .italic .smcaps}\n \n \xEF\x9B\xA1 eiusmod tempor incididunt, ut\xC3\xAAn\xC3\xB9 labore et dolore. Tw\xC4\x83nj\xC3\xAC magna aliqua. Ut enim ad minim veniam\n {: .normal}\n@@ -9,5 +9,5 @@ quis nostrud\xC3\xAAt\xC3\xB9 exercitiation ullamco laboris m\xC3\xB9s\xC3\xB9k\xC3\xB9abc\xC3\xB9 nisi "
],
[
@@ -93,7 +95,7 @@ describe Gitlab::EncodingHelper do
[
["nil", nil, nil],
["empty string", "".encode("ASCII-8BIT"), "".encode("UTF-8")],
- ["invalid utf-8 encoded string", "my bad string\xE5".force_encoding("UTF-8"), "my bad stringå"],
+ ["invalid utf-8 encoded string", (+"my bad string\xE5").force_encoding("UTF-8"), "my bad stringå"],
[
"encodes valid utf8 encoded string to utf8",
"λ, λ, λ".encode("UTF-8"),
@@ -160,12 +162,12 @@ describe Gitlab::EncodingHelper do
],
[
'removes invalid bytes from ASCII-8bit encoded multibyte string.',
- "Lorem ipsum\xC3\n dolor sit amet, xy\xC3\xA0y\xC3\xB9abcd\xC3\xB9efg".force_encoding('ASCII-8BIT'),
+ (+"Lorem ipsum\xC3\n dolor sit amet, xy\xC3\xA0y\xC3\xB9abcd\xC3\xB9efg").force_encoding('ASCII-8BIT'),
"Lorem ipsum\n dolor sit amet, xyàyùabcdùefg"
],
[
'handles UTF-16BE encoded strings',
- "\xFE\xFF\x00\x41".force_encoding('ASCII-8BIT'), # An "A" prepended with UTF-16 BOM
+ (+"\xFE\xFF\x00\x41").force_encoding('ASCII-8BIT'), # An "A" prepended with UTF-16 BOM
"\xEF\xBB\xBFA" # An "A" prepended with UTF-8 BOM
]
].each do |description, test_string, xpect|
diff --git a/spec/lib/gitlab/etag_caching/middleware_spec.rb b/spec/lib/gitlab/etag_caching/middleware_spec.rb
index 4a54d641b4e..9ead55075fa 100644
--- a/spec/lib/gitlab/etag_caching/middleware_spec.rb
+++ b/spec/lib/gitlab/etag_caching/middleware_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::EtagCaching::Middleware do
diff --git a/spec/lib/gitlab/etag_caching/router_spec.rb b/spec/lib/gitlab/etag_caching/router_spec.rb
index a7cb0bb2a87..fbc49d894a6 100644
--- a/spec/lib/gitlab/etag_caching/router_spec.rb
+++ b/spec/lib/gitlab/etag_caching/router_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::EtagCaching::Router do
diff --git a/spec/lib/gitlab/group_search_results_spec.rb b/spec/lib/gitlab/group_search_results_spec.rb
index 2734fcef0a0..53a91a35ec9 100644
--- a/spec/lib/gitlab/group_search_results_spec.rb
+++ b/spec/lib/gitlab/group_search_results_spec.rb
@@ -20,7 +20,7 @@ describe Gitlab::GroupSearchResults do
expect(result).to eq [user1]
end
- it 'returns the user belonging to the subgroup matching the search query', :nested_groups do
+ it 'returns the user belonging to the subgroup matching the search query' do
user1 = create(:user, username: 'gob_bluth')
subgroup = create(:group, parent: group)
create(:group_member, :developer, user: user1, group: subgroup)
@@ -32,7 +32,7 @@ describe Gitlab::GroupSearchResults do
expect(result).to eq [user1]
end
- it 'returns the user belonging to the parent group matching the search query', :nested_groups do
+ it 'returns the user belonging to the parent group matching the search query' do
user1 = create(:user, username: 'gob_bluth')
parent_group = create(:group, children: [group])
create(:group_member, :developer, user: user1, group: parent_group)
@@ -44,7 +44,7 @@ describe Gitlab::GroupSearchResults do
expect(result).to eq [user1]
end
- it 'does not return the user belonging to the private subgroup', :nested_groups do
+ it 'does not return the user belonging to the private subgroup' do
user1 = create(:user, username: 'gob_bluth')
subgroup = create(:group, :private, parent: group)
create(:group_member, :developer, user: user1, group: subgroup)
diff --git a/spec/lib/gitlab/manifest_import/manifest_spec.rb b/spec/lib/gitlab/manifest_import/manifest_spec.rb
index ab305fb2316..ded93e23c08 100644
--- a/spec/lib/gitlab/manifest_import/manifest_spec.rb
+++ b/spec/lib/gitlab/manifest_import/manifest_spec.rb
@@ -1,6 +1,6 @@
require 'spec_helper'
-describe Gitlab::ManifestImport::Manifest, :postgresql do
+describe Gitlab::ManifestImport::Manifest do
let(:file) { File.open(Rails.root.join('spec/fixtures/aosp_manifest.xml')) }
let(:manifest) { described_class.new(file) }
diff --git a/spec/lib/gitlab/manifest_import/project_creator_spec.rb b/spec/lib/gitlab/manifest_import/project_creator_spec.rb
index 1d01d437535..a7487972f51 100644
--- a/spec/lib/gitlab/manifest_import/project_creator_spec.rb
+++ b/spec/lib/gitlab/manifest_import/project_creator_spec.rb
@@ -1,6 +1,6 @@
require 'spec_helper'
-describe Gitlab::ManifestImport::ProjectCreator, :postgresql do
+describe Gitlab::ManifestImport::ProjectCreator do
let(:group) { create(:group) }
let(:user) { create(:user) }
let(:repository) do
diff --git a/spec/lib/gitlab/object_hierarchy_spec.rb b/spec/lib/gitlab/object_hierarchy_spec.rb
index e6e9ae3223e..bfd456cdd7e 100644
--- a/spec/lib/gitlab/object_hierarchy_spec.rb
+++ b/spec/lib/gitlab/object_hierarchy_spec.rb
@@ -1,6 +1,6 @@
require 'spec_helper'
-describe Gitlab::ObjectHierarchy, :postgresql do
+describe Gitlab::ObjectHierarchy do
let!(:parent) { create(:group) }
let!(:child1) { create(:group, parent: parent) }
let!(:child2) { create(:group, parent: child1) }
diff --git a/spec/lib/gitlab/performance_bar_spec.rb b/spec/lib/gitlab/performance_bar_spec.rb
index ee3c571c9c0..71c109db1f1 100644
--- a/spec/lib/gitlab/performance_bar_spec.rb
+++ b/spec/lib/gitlab/performance_bar_spec.rb
@@ -96,7 +96,7 @@ describe Gitlab::PerformanceBar do
end
end
- context 'when allowed group is nested', :nested_groups do
+ context 'when allowed group is nested' do
let!(:nested_my_group) { create(:group, parent: create(:group, path: 'my-org'), path: 'my-group') }
before do
@@ -110,7 +110,7 @@ describe Gitlab::PerformanceBar do
end
end
- context 'when a nested group has the same path', :nested_groups do
+ context 'when a nested group has the same path' do
before do
create(:group, :nested, path: 'my-group').add_developer(user)
end
diff --git a/spec/lib/gitlab/project_authorizations_spec.rb b/spec/lib/gitlab/project_authorizations_spec.rb
index bd0bc2c9044..75e2d5e1319 100644
--- a/spec/lib/gitlab/project_authorizations_spec.rb
+++ b/spec/lib/gitlab/project_authorizations_spec.rb
@@ -20,13 +20,7 @@ describe Gitlab::ProjectAuthorizations do
end
let(:authorizations) do
- klass = if Group.supports_nested_objects?
- Gitlab::ProjectAuthorizations::WithNestedGroups
- else
- Gitlab::ProjectAuthorizations::WithoutNestedGroups
- end
-
- klass.new(user).calculate
+ described_class.new(user).calculate
end
it 'returns the correct number of authorizations' do
@@ -46,28 +40,26 @@ describe Gitlab::ProjectAuthorizations do
expect(mapping[group_project.id]).to eq(Gitlab::Access::DEVELOPER)
end
- if Group.supports_nested_objects?
- context 'with nested groups' do
- let!(:nested_group) { create(:group, parent: group) }
- let!(:nested_project) { create(:project, namespace: nested_group) }
+ context 'with nested groups' do
+ let!(:nested_group) { create(:group, parent: group) }
+ let!(:nested_project) { create(:project, namespace: nested_group) }
- it 'includes nested groups' do
- expect(authorizations.pluck(:project_id)).to include(nested_project.id)
- end
+ it 'includes nested groups' do
+ expect(authorizations.pluck(:project_id)).to include(nested_project.id)
+ end
- it 'inherits access levels when the user is not a member of a nested group' do
- mapping = map_access_levels(authorizations)
+ it 'inherits access levels when the user is not a member of a nested group' do
+ mapping = map_access_levels(authorizations)
- expect(mapping[nested_project.id]).to eq(Gitlab::Access::DEVELOPER)
- end
+ expect(mapping[nested_project.id]).to eq(Gitlab::Access::DEVELOPER)
+ end
- it 'uses the greatest access level when a user is a member of a nested group' do
- nested_group.add_maintainer(user)
+ it 'uses the greatest access level when a user is a member of a nested group' do
+ nested_group.add_maintainer(user)
- mapping = map_access_levels(authorizations)
+ mapping = map_access_levels(authorizations)
- expect(mapping[nested_project.id]).to eq(Gitlab::Access::MAINTAINER)
- end
+ expect(mapping[nested_project.id]).to eq(Gitlab::Access::MAINTAINER)
end
end
end
diff --git a/spec/lib/gitlab/sql/cte_spec.rb b/spec/lib/gitlab/sql/cte_spec.rb
index d6763c7b2e1..5d2164491b5 100644
--- a/spec/lib/gitlab/sql/cte_spec.rb
+++ b/spec/lib/gitlab/sql/cte_spec.rb
@@ -1,6 +1,6 @@
require 'spec_helper'
-describe Gitlab::SQL::CTE, :postgresql do
+describe Gitlab::SQL::CTE do
describe '#to_arel' do
it 'generates an Arel relation for the CTE body' do
relation = User.where(id: 1)
diff --git a/spec/lib/gitlab/sql/recursive_cte_spec.rb b/spec/lib/gitlab/sql/recursive_cte_spec.rb
index 7fe39dd5a96..407a4d8a247 100644
--- a/spec/lib/gitlab/sql/recursive_cte_spec.rb
+++ b/spec/lib/gitlab/sql/recursive_cte_spec.rb
@@ -1,6 +1,6 @@
require 'spec_helper'
-describe Gitlab::SQL::RecursiveCTE, :postgresql do
+describe Gitlab::SQL::RecursiveCTE do
let(:cte) { described_class.new(:cte_name) }
describe '#to_arel' do
diff --git a/spec/lib/gitlab/submodule_links_spec.rb b/spec/lib/gitlab/submodule_links_spec.rb
new file mode 100644
index 00000000000..a84602cd07d
--- /dev/null
+++ b/spec/lib/gitlab/submodule_links_spec.rb
@@ -0,0 +1,47 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Gitlab::SubmoduleLinks do
+ let(:submodule_item) { double(id: 'hash', path: 'gitlab-ce') }
+ let(:repo) { double }
+ let(:links) { described_class.new(repo) }
+
+ describe '#for' do
+ subject { links.for(submodule_item, 'ref') }
+
+ context 'when there is no .gitmodules file' do
+ before do
+ stub_urls(nil)
+ end
+
+ it 'returns no links' do
+ expect(subject).to eq([nil, nil])
+ end
+ end
+
+ context 'when the submodule is unknown' do
+ before do
+ stub_urls({ 'path' => 'url' })
+ end
+
+ it 'returns no links' do
+ expect(subject).to eq([nil, nil])
+ end
+ end
+
+ context 'when the submodule is known' do
+ before do
+ stub_urls({ 'gitlab-ce' => 'git@gitlab.com:gitlab-org/gitlab-ce.git' })
+ end
+
+ it 'returns links' do
+ expect(subject).to eq(['https://gitlab.com/gitlab-org/gitlab-ce', 'https://gitlab.com/gitlab-org/gitlab-ce/tree/hash'])
+ end
+ end
+ end
+
+ def stub_urls(urls)
+ allow(repo).to receive(:submodule_urls_for).and_return(urls)
+ end
+end
diff --git a/spec/lib/prometheus/pid_provider_spec.rb b/spec/lib/prometheus/pid_provider_spec.rb
index e7d500612b1..ba843b27254 100644
--- a/spec/lib/prometheus/pid_provider_spec.rb
+++ b/spec/lib/prometheus/pid_provider_spec.rb
@@ -25,22 +25,60 @@ describe Prometheus::PidProvider do
before do
stub_const('Unicorn::Worker', Class.new)
hide_const('Puma')
+
+ expect(described_class).to receive(:process_name)
+ .at_least(:once)
+ .and_return(process_name)
end
- context 'when `Prometheus::Client::Support::Unicorn` provides worker_id' do
- before do
- expect(::Prometheus::Client::Support::Unicorn).to receive(:worker_id).and_return(1)
+ context 'when unicorn master is specified in process name' do
+ context 'when running in Omnibus' do
+ context 'before the process was renamed' do
+ let(:process_name) { "/opt/gitlab/embedded/bin/unicorn"}
+
+ it { is_expected.to eq 'unicorn_master' }
+ end
+
+ context 'after the process was renamed' do
+ let(:process_name) { "unicorn master -D -E production -c /var/opt/gitlab/gitlab-rails/etc/unicorn.rb /opt/gitlab/embedded/service/gitlab-rails/config.ru" }
+
+ it { is_expected.to eq 'unicorn_master' }
+ end
end
- it { is_expected.to eq 'unicorn_1' }
+ context 'when in development env' do
+ context 'before the process was renamed' do
+ let(:process_name) { "path_to_bindir/bin/unicorn_rails"}
+
+ it { is_expected.to eq 'unicorn_master' }
+ end
+
+ context 'after the process was renamed' do
+ let(:process_name) { "unicorn_rails master -c /gitlab_dir/config/unicorn.rb -E development" }
+
+ it { is_expected.to eq 'unicorn_master' }
+ end
+ end
end
- context 'when no worker_id is provided from `Prometheus::Client::Support::Unicorn`' do
- before do
- expect(::Prometheus::Client::Support::Unicorn).to receive(:worker_id).and_return(nil)
+ context 'when unicorn worker id is specified in process name' do
+ context 'when running in Omnibus' do
+ let(:process_name) { "unicorn worker[1] -D -E production -c /var/opt/gitlab/gitlab-rails/etc/unicorn.rb /opt/gitlab/embedded/service/gitlab-rails/config.ru" }
+
+ it { is_expected.to eq 'unicorn_1' }
end
- it { is_expected.to eq 'unicorn_master' }
+ context 'when in development env' do
+ let(:process_name) { "unicorn_rails worker[1] -c gitlab_dir/config/unicorn.rb -E development" }
+
+ it { is_expected.to eq 'unicorn_1' }
+ end
+ end
+
+ context 'when no specified unicorn master or worker id in process name' do
+ let(:process_name) { "bin/unknown_process"}
+
+ it { is_expected.to eq "process_#{Process.pid}" }
end
end
@@ -48,20 +86,20 @@ describe Prometheus::PidProvider do
before do
stub_const('Puma', Module.new)
hide_const('Unicorn::Worker')
+
+ expect(described_class).to receive(:process_name)
+ .at_least(:once)
+ .and_return(process_name)
end
context 'when cluster worker id is specified in process name' do
- before do
- expect(described_class).to receive(:process_name).and_return('puma: cluster worker 1: 17483 [gitlab-puma-worker]')
- end
+ let(:process_name) { 'puma: cluster worker 1: 17483 [gitlab-puma-worker]' }
it { is_expected.to eq 'puma_1' }
end
context 'when no worker id is specified in process name' do
- before do
- expect(described_class).to receive(:process_name).and_return('bin/puma')
- end
+ let(:process_name) { 'bin/puma' }
it { is_expected.to eq 'puma_master' }
end
diff --git a/spec/mailers/notify_spec.rb b/spec/mailers/notify_spec.rb
index 56bbcc4c306..dcc4b70a382 100644
--- a/spec/mailers/notify_spec.rb
+++ b/spec/mailers/notify_spec.rb
@@ -640,7 +640,7 @@ describe Notify do
project.request_access(user)
project.requesters.find_by(user_id: user.id)
end
- subject { described_class.member_access_requested_email('project', project_member.id, recipient.notification_email) }
+ subject { described_class.member_access_requested_email('project', project_member.id, recipient.id) }
it_behaves_like 'an email sent from GitLab'
it_behaves_like 'it should not have Gmail Actions links'
@@ -737,9 +737,9 @@ describe Notify do
describe 'project invitation accepted' do
let(:invited_user) { create(:user, name: 'invited user') }
- let(:maintainer) { create(:user).tap { |u| project.add_maintainer(u) } }
+ let(:recipient) { create(:user).tap { |u| project.add_maintainer(u) } }
let(:project_member) do
- invitee = invite_to_project(project, inviter: maintainer)
+ invitee = invite_to_project(project, inviter: recipient)
invitee.accept_invite!(invited_user)
invitee
end
@@ -747,6 +747,7 @@ describe Notify do
subject { described_class.member_invite_accepted_email('project', project_member.id) }
it_behaves_like 'an email sent from GitLab'
+ it_behaves_like 'an email sent to a user'
it_behaves_like 'it should not have Gmail Actions links'
it_behaves_like "a user cannot unsubscribe through footer link"
it_behaves_like 'appearance header and footer enabled'
@@ -762,16 +763,17 @@ describe Notify do
end
describe 'project invitation declined' do
- let(:maintainer) { create(:user).tap { |u| project.add_maintainer(u) } }
+ let(:recipient) { create(:user).tap { |u| project.add_maintainer(u) } }
let(:project_member) do
- invitee = invite_to_project(project, inviter: maintainer)
+ invitee = invite_to_project(project, inviter: recipient)
invitee.decline_invite!
invitee
end
- subject { described_class.member_invite_declined_email('Project', project.id, project_member.invite_email, maintainer.id) }
+ subject { described_class.member_invite_declined_email('Project', project.id, project_member.invite_email, recipient.id) }
it_behaves_like 'an email sent from GitLab'
+ it_behaves_like 'an email sent to a user'
it_behaves_like 'it should not have Gmail Actions links'
it_behaves_like "a user cannot unsubscribe through footer link"
it_behaves_like 'appearance header and footer enabled'
@@ -1087,9 +1089,10 @@ describe Notify do
group.request_access(user)
group.requesters.find_by(user_id: user.id)
end
- subject { described_class.member_access_requested_email('group', group_member.id, recipient.notification_email) }
+ subject { described_class.member_access_requested_email('group', group_member.id, recipient.id) }
it_behaves_like 'an email sent from GitLab'
+ it_behaves_like 'an email sent to a user'
it_behaves_like 'it should not have Gmail Actions links'
it_behaves_like "a user cannot unsubscribe through footer link"
it_behaves_like 'appearance header and footer enabled'
@@ -1111,9 +1114,11 @@ describe Notify do
group.request_access(user)
group.requesters.find_by(user_id: user.id)
end
+ let(:recipient) { user }
subject { described_class.member_access_denied_email('group', group.id, user.id) }
it_behaves_like 'an email sent from GitLab'
+ it_behaves_like 'an email sent to a user'
it_behaves_like 'it should not have Gmail Actions links'
it_behaves_like "a user cannot unsubscribe through footer link"
it_behaves_like 'appearance header and footer enabled'
@@ -1128,10 +1133,12 @@ describe Notify do
describe 'group access changed' do
let(:group_member) { create(:group_member, group: group, user: user) }
+ let(:recipient) { user }
subject { described_class.member_access_granted_email('group', group_member.id) }
it_behaves_like 'an email sent from GitLab'
+ it_behaves_like 'an email sent to a user'
it_behaves_like 'it should not have Gmail Actions links'
it_behaves_like "a user cannot unsubscribe through footer link"
it_behaves_like 'appearance header and footer enabled'
diff --git a/spec/models/ci/pipeline_spec.rb b/spec/models/ci/pipeline_spec.rb
index e24bbc39761..1fb83fbb088 100644
--- a/spec/models/ci/pipeline_spec.rb
+++ b/spec/models/ci/pipeline_spec.rb
@@ -1799,7 +1799,7 @@ describe Ci::Pipeline, :mailer do
end
end
- describe '.latest_successful_for' do
+ describe '.latest_successful_for_ref' do
include_context 'with some outdated pipelines'
let!(:latest_successful_pipeline) do
@@ -1807,7 +1807,20 @@ describe Ci::Pipeline, :mailer do
end
it 'returns the latest successful pipeline' do
- expect(described_class.latest_successful_for('ref'))
+ expect(described_class.latest_successful_for_ref('ref'))
+ .to eq(latest_successful_pipeline)
+ end
+ end
+
+ describe '.latest_successful_for_sha' do
+ include_context 'with some outdated pipelines'
+
+ let!(:latest_successful_pipeline) do
+ create_pipeline(:success, 'ref', 'awesomesha', project)
+ end
+
+ it 'returns the latest successful pipeline' do
+ expect(described_class.latest_successful_for_sha('awesomesha'))
.to eq(latest_successful_pipeline)
end
end
diff --git a/spec/models/ci/runner_spec.rb b/spec/models/ci/runner_spec.rb
index 24ea059e871..78b151631c1 100644
--- a/spec/models/ci/runner_spec.rb
+++ b/spec/models/ci/runner_spec.rb
@@ -146,7 +146,7 @@ describe Ci::Runner do
expect(described_class.belonging_to_parent_group_of_project(project.id)).to contain_exactly(runner)
end
- context 'with a parent group with a runner', :nested_groups do
+ context 'with a parent group with a runner' do
let(:runner) { create(:ci_runner, :group, groups: [parent_group]) }
let(:project) { create(:project, group: group) }
let(:group) { create(:group, parent: parent_group) }
diff --git a/spec/models/clusters/cluster_spec.rb b/spec/models/clusters/cluster_spec.rb
index 52661178d76..8f2f1b200e4 100644
--- a/spec/models/clusters/cluster_spec.rb
+++ b/spec/models/clusters/cluster_spec.rb
@@ -342,7 +342,7 @@ describe Clusters::Cluster, :use_clean_rails_memory_store_caching do
end
end
- context 'when sub-group has configured kubernetes cluster', :nested_groups do
+ context 'when sub-group has configured kubernetes cluster' do
let(:sub_group_cluster) { create(:cluster, :provided_by_gcp, :group) }
let(:sub_group) { sub_group_cluster.group }
let(:project) { create(:project, group: sub_group) }
diff --git a/spec/models/concerns/deployment_platform_spec.rb b/spec/models/concerns/deployment_platform_spec.rb
index c4f9f62ece5..27f535487c8 100644
--- a/spec/models/concerns/deployment_platform_spec.rb
+++ b/spec/models/concerns/deployment_platform_spec.rb
@@ -45,7 +45,7 @@ describe DeploymentPlatform do
is_expected.to eq(group_cluster.platform_kubernetes)
end
- context 'when child group has configured kubernetes cluster', :nested_groups do
+ context 'when child group has configured kubernetes cluster' do
let(:child_group1) { create(:group, parent: group) }
let!(:child_group1_cluster) { create(:cluster_for_group, groups: [child_group1]) }
diff --git a/spec/models/concerns/group_descendant_spec.rb b/spec/models/concerns/group_descendant_spec.rb
index 194caac3fce..192e884f3e8 100644
--- a/spec/models/concerns/group_descendant_spec.rb
+++ b/spec/models/concerns/group_descendant_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe GroupDescendant, :nested_groups do
+describe GroupDescendant do
let(:parent) { create(:group) }
let(:subgroup) { create(:group, parent: parent) }
let(:subsub_group) { create(:group, parent: subgroup) }
@@ -84,7 +84,7 @@ describe GroupDescendant, :nested_groups do
it 'tracks the exception when a parent was not preloaded' do
expect(Gitlab::Sentry).to receive(:track_exception).and_call_original
- expect { GroupDescendant.build_hierarchy([subsub_group]) }.to raise_error(ArgumentError)
+ expect { described_class.build_hierarchy([subsub_group]) }.to raise_error(ArgumentError)
end
it 'recovers if a parent was not reloaded by querying for the parent' do
@@ -93,7 +93,7 @@ describe GroupDescendant, :nested_groups do
# this does not raise in production, so stubbing it here.
allow(Gitlab::Sentry).to receive(:track_exception)
- expect(GroupDescendant.build_hierarchy([subsub_group])).to eq(expected_hierarchy)
+ expect(described_class.build_hierarchy([subsub_group])).to eq(expected_hierarchy)
end
it 'raises an error if not all elements were preloaded' do
diff --git a/spec/models/concerns/issuable_spec.rb b/spec/models/concerns/issuable_spec.rb
index e19da41c3fe..39680c0e51a 100644
--- a/spec/models/concerns/issuable_spec.rb
+++ b/spec/models/concerns/issuable_spec.rb
@@ -128,7 +128,7 @@ describe Issuable do
expect(build_issuable(milestone.id).milestone_available?).to be_truthy
end
- it 'returns true with a milestone from the the parent of the issue project group', :nested_groups do
+ it 'returns true with a milestone from the the parent of the issue project group' do
parent = create(:group)
group.update(parent: parent)
milestone = create(:milestone, group: parent)
diff --git a/spec/models/deployment_metrics_spec.rb b/spec/models/deployment_metrics_spec.rb
index 0aadb1f3a5e..7c574a8b6c8 100644
--- a/spec/models/deployment_metrics_spec.rb
+++ b/spec/models/deployment_metrics_spec.rb
@@ -49,18 +49,6 @@ describe DeploymentMetrics do
it { is_expected.to be_truthy }
end
-
- context 'fallback deployment platform' do
- let(:cluster) { create(:cluster, :provided_by_user, environment_scope: '*', projects: [deployment.project]) }
- let!(:prometheus) { create(:clusters_applications_prometheus, :installed, cluster: cluster) }
-
- before do
- expect(deployment.project).to receive(:deployment_platform).and_return(cluster.platform)
- expect(cluster.application_prometheus).to receive(:can_query?).and_return(true)
- end
-
- it { is_expected.to be_truthy }
- end
end
end
diff --git a/spec/models/group_spec.rb b/spec/models/group_spec.rb
index 90e0900445e..7e9bbf5a407 100644
--- a/spec/models/group_spec.rb
+++ b/spec/models/group_spec.rb
@@ -71,7 +71,7 @@ describe Group do
end
end
- describe '#notification_settings', :nested_groups do
+ describe '#notification_settings' do
let(:user) { create(:user) }
let(:group) { create(:group) }
let(:sub_group) { create(:group, parent_id: group.id) }
@@ -237,7 +237,7 @@ describe Group do
it { is_expected.to match_array([private_group, internal_group, group]) }
end
- context 'when user is a member of private subgroup', :postgresql do
+ context 'when user is a member of private subgroup' do
let!(:private_subgroup) { create(:group, :private, parent: private_group) }
before do
@@ -416,7 +416,7 @@ describe Group do
it { expect(group.last_owner?(@members[:owner])).to be_falsy }
end
- context 'with owners from a parent', :postgresql do
+ context 'with owners from a parent' do
before do
parent_group = create(:group)
create(:group_member, :owner, group: parent_group)
@@ -524,7 +524,7 @@ describe Group do
it { expect(subject.parent).to be_kind_of(described_class) }
end
- describe '#members_with_parents', :nested_groups do
+ describe '#members_with_parents' do
let!(:group) { create(:group, :nested) }
let!(:maintainer) { group.parent.add_user(create(:user), GroupMember::MAINTAINER) }
let!(:developer) { group.add_user(create(:user), GroupMember::DEVELOPER) }
@@ -535,7 +535,7 @@ describe Group do
end
end
- describe '#direct_and_indirect_members', :nested_groups do
+ describe '#direct_and_indirect_members' do
let!(:group) { create(:group, :nested) }
let!(:sub_group) { create(:group, parent: group) }
let!(:maintainer) { group.parent.add_user(create(:user), GroupMember::MAINTAINER) }
@@ -552,7 +552,7 @@ describe Group do
end
end
- describe '#users_with_descendants', :nested_groups do
+ describe '#users_with_descendants' do
let(:user_a) { create(:user) }
let(:user_b) { create(:user) }
@@ -571,7 +571,7 @@ describe Group do
end
end
- describe '#direct_and_indirect_users', :nested_groups do
+ describe '#direct_and_indirect_users' do
let(:user_a) { create(:user) }
let(:user_b) { create(:user) }
let(:user_c) { create(:user) }
@@ -601,7 +601,7 @@ describe Group do
end
end
- describe '#project_users_with_descendants', :nested_groups do
+ describe '#project_users_with_descendants' do
let(:user_a) { create(:user) }
let(:user_b) { create(:user) }
let(:user_c) { create(:user) }
@@ -678,7 +678,7 @@ describe Group do
end
end
- context 'sub groups and projects', :nested_groups do
+ context 'sub groups and projects' do
it 'enables two_factor_requirement for group member' do
group.add_user(user, GroupMember::OWNER)
@@ -687,7 +687,7 @@ describe Group do
expect(user.reload.require_two_factor_authentication_from_group).to be_truthy
end
- context 'expanded group members', :nested_groups do
+ context 'expanded group members' do
let(:indirect_user) { create(:user) }
it 'enables two_factor_requirement for subgroup member' do
@@ -720,7 +720,7 @@ describe Group do
expect(user.reload.require_two_factor_authentication_from_group).to be_falsey
end
- it 'does not enable two_factor_requirement for subgroup child project member', :nested_groups do
+ it 'does not enable two_factor_requirement for subgroup child project member' do
subgroup = create(:group, :nested, parent: group)
project = create(:project, group: subgroup)
project.add_maintainer(user)
@@ -820,7 +820,7 @@ describe Group do
it_behaves_like 'ref is protected'
end
- context 'when group has children', :postgresql do
+ context 'when group has children' do
let(:group_child) { create(:group, parent: group) }
let(:group_child_2) { create(:group, parent: group_child) }
let(:group_child_3) { create(:group, parent: group_child_2) }
@@ -843,7 +843,7 @@ describe Group do
end
end
- describe '#highest_group_member', :nested_groups do
+ describe '#highest_group_member' do
let(:nested_group) { create(:group, parent: group) }
let(:nested_group_2) { create(:group, parent: nested_group) }
let(:user) { create(:user) }
@@ -932,7 +932,7 @@ describe Group do
it { is_expected.to eq(config) }
end
- context 'with parent groups', :nested_groups do
+ context 'with parent groups' do
where(:instance_value, :parent_value, :group_value, :config) do
# Instance level enabled
true | nil | nil | { status: true, scope: :instance }
diff --git a/spec/models/members/group_member_spec.rb b/spec/models/members/group_member_spec.rb
index f227abd3dae..ebb0bfca369 100644
--- a/spec/models/members/group_member_spec.rb
+++ b/spec/models/members/group_member_spec.rb
@@ -69,7 +69,7 @@ describe GroupMember do
end
end
- context 'access levels', :nested_groups do
+ context 'access levels' do
context 'with parent group' do
it_behaves_like 'inherited access level as a member of entity' do
let(:entity) { create(:group, parent: parent_entity) }
diff --git a/spec/models/members/project_member_spec.rb b/spec/models/members/project_member_spec.rb
index 497764b6825..79c39b81196 100644
--- a/spec/models/members/project_member_spec.rb
+++ b/spec/models/members/project_member_spec.rb
@@ -130,7 +130,7 @@ describe ProjectMember do
end
end
- context 'with parent group and a subgroup', :nested_groups do
+ context 'with parent group and a subgroup' do
it_behaves_like 'inherited access level as a member of entity' do
let(:subgroup) { create(:group, parent: parent_entity) }
let(:entity) { create(:project, group: subgroup) }
diff --git a/spec/models/namespace/root_storage_statistics_spec.rb b/spec/models/namespace/root_storage_statistics_spec.rb
index 3229a32234e..5341278db7c 100644
--- a/spec/models/namespace/root_storage_statistics_spec.rb
+++ b/spec/models/namespace/root_storage_statistics_spec.rb
@@ -56,7 +56,7 @@ RSpec.describe Namespace::RootStorageStatistics, type: :model do
it_behaves_like 'data refresh'
- context 'with subgroups', :nested_groups do
+ context 'with subgroups' do
let(:subgroup1) { create(:group, parent: namespace)}
let(:subgroup2) { create(:group, parent: subgroup1)}
diff --git a/spec/models/namespace_spec.rb b/spec/models/namespace_spec.rb
index f908f3504e0..2b9c3c43af9 100644
--- a/spec/models/namespace_spec.rb
+++ b/spec/models/namespace_spec.rb
@@ -191,7 +191,7 @@ describe Namespace do
end
end
- describe '#ancestors_upto', :nested_groups do
+ describe '#ancestors_upto' do
let(:parent) { create(:group) }
let(:child) { create(:group, parent: parent) }
let(:child2) { create(:group, parent: child) }
@@ -271,7 +271,7 @@ describe Namespace do
end
end
- context 'with subgroups', :nested_groups do
+ context 'with subgroups' do
let(:parent) { create(:group, name: 'parent', path: 'parent') }
let(:new_parent) { create(:group, name: 'new_parent', path: 'new_parent') }
let(:child) { create(:group, name: 'child', path: 'child', parent: parent) }
@@ -475,7 +475,7 @@ describe Namespace do
end
end
- describe '#self_and_hierarchy', :nested_groups do
+ describe '#self_and_hierarchy' do
let!(:group) { create(:group, path: 'git_lab') }
let!(:nested_group) { create(:group, parent: group) }
let!(:deep_nested_group) { create(:group, parent: nested_group) }
@@ -490,7 +490,7 @@ describe Namespace do
end
end
- describe '#ancestors', :nested_groups do
+ describe '#ancestors' do
let(:group) { create(:group) }
let(:nested_group) { create(:group, parent: group) }
let(:deep_nested_group) { create(:group, parent: nested_group) }
@@ -504,7 +504,7 @@ describe Namespace do
end
end
- describe '#self_and_ancestors', :nested_groups do
+ describe '#self_and_ancestors' do
let(:group) { create(:group) }
let(:nested_group) { create(:group, parent: group) }
let(:deep_nested_group) { create(:group, parent: nested_group) }
@@ -518,7 +518,7 @@ describe Namespace do
end
end
- describe '#descendants', :nested_groups do
+ describe '#descendants' do
let!(:group) { create(:group, path: 'git_lab') }
let!(:nested_group) { create(:group, parent: group) }
let!(:deep_nested_group) { create(:group, parent: nested_group) }
@@ -534,7 +534,7 @@ describe Namespace do
end
end
- describe '#self_and_descendants', :nested_groups do
+ describe '#self_and_descendants' do
let!(:group) { create(:group, path: 'git_lab') }
let!(:nested_group) { create(:group, parent: group) }
let!(:deep_nested_group) { create(:group, parent: nested_group) }
@@ -550,7 +550,7 @@ describe Namespace do
end
end
- describe '#users_with_descendants', :nested_groups do
+ describe '#users_with_descendants' do
let(:user_a) { create(:user) }
let(:user_b) { create(:user) }
@@ -597,7 +597,7 @@ describe Namespace do
it { expect(group.all_pipelines.to_a).to match_array([pipeline1, pipeline2]) }
end
- describe '#share_with_group_lock with subgroups', :nested_groups do
+ describe '#share_with_group_lock with subgroups' do
context 'when creating a subgroup' do
let(:subgroup) { create(:group, parent: root_group )}
@@ -738,7 +738,7 @@ describe Namespace do
end
describe '#root_ancestor' do
- it 'returns the top most ancestor', :nested_groups do
+ it 'returns the top most ancestor' do
root_group = create(:group)
nested_group = create(:group, parent: root_group)
deep_nested_group = create(:group, parent: nested_group)
diff --git a/spec/models/notification_recipient_spec.rb b/spec/models/notification_recipient_spec.rb
index 20278d81f6d..4122736c148 100644
--- a/spec/models/notification_recipient_spec.rb
+++ b/spec/models/notification_recipient_spec.rb
@@ -49,7 +49,7 @@ describe NotificationRecipient do
end
context '#notification_setting' do
- context 'for child groups', :nested_groups do
+ context 'for child groups' do
let!(:moved_group) { create(:group) }
let(:group) { create(:group) }
let(:sub_group_1) { create(:group, parent: group) }
diff --git a/spec/models/postgresql/replication_slot_spec.rb b/spec/models/postgresql/replication_slot_spec.rb
index 95ae204a8a8..d435fccc09a 100644
--- a/spec/models/postgresql/replication_slot_spec.rb
+++ b/spec/models/postgresql/replication_slot_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Postgresql::ReplicationSlot, :postgresql do
+describe Postgresql::ReplicationSlot do
describe '.in_use?' do
it 'returns true when replication slots are present' do
expect(described_class).to receive(:exists?).and_return(true)
diff --git a/spec/models/project_group_link_spec.rb b/spec/models/project_group_link_spec.rb
index dad5506900b..cd997224122 100644
--- a/spec/models/project_group_link_spec.rb
+++ b/spec/models/project_group_link_spec.rb
@@ -25,7 +25,7 @@ describe ProjectGroupLink do
expect(project_group_link).not_to be_valid
end
- it "doesn't allow a project to be shared with an ancestor of the group it is in", :nested_groups do
+ it "doesn't allow a project to be shared with an ancestor of the group it is in" do
project_group_link.group = parent_group
expect(project_group_link).not_to be_valid
diff --git a/spec/models/project_services/chat_message/pipeline_message_spec.rb b/spec/models/project_services/chat_message/pipeline_message_spec.rb
index 8f9fa310ad4..619ab96af94 100644
--- a/spec/models/project_services/chat_message/pipeline_message_spec.rb
+++ b/spec/models/project_services/chat_message/pipeline_message_spec.rb
@@ -1,12 +1,9 @@
# frozen_string_literal: true
-
require 'spec_helper'
describe ChatMessage::PipelineMessage do
subject { described_class.new(args) }
- let(:user) { { name: "The Hacker", username: 'hacker' } }
- let(:duration) { 7210 }
let(:args) do
{
object_attributes: {
@@ -14,122 +11,437 @@ describe ChatMessage::PipelineMessage do
sha: '97de212e80737a608d939f648d959671fb0a0142',
tag: false,
ref: 'develop',
- status: status,
- duration: duration
+ status: 'success',
+ detailed_status: nil,
+ duration: 7210,
+ finished_at: "2019-05-27 11:56:36 -0300"
},
project: {
- path_with_namespace: 'project_name',
- web_url: 'http://example.gitlab.com'
+ id: 234,
+ name: "project_name",
+ path_with_namespace: 'group/project_name',
+ web_url: 'http://example.gitlab.com',
+ avatar_url: 'http://example.com/project_avatar'
+ },
+ user: {
+ id: 345,
+ name: "The Hacker",
+ username: "hacker",
+ email: "hacker@example.gitlab.com",
+ avatar_url: "http://example.com/avatar"
+ },
+ commit: {
+ id: "abcdef"
},
- user: user
+ builds: nil,
+ markdown: false
}
end
- let(:combined_name) { "The Hacker (hacker)" }
- context 'without markdown' do
- context 'pipeline succeeded' do
- let(:status) { 'success' }
- let(:color) { 'good' }
- let(:message) { build_message('passed', combined_name) }
+ let(:has_yaml_errors) { false }
+
+ before do
+ test_commit = double("A test commit", committer: args[:user], title: "A test commit message")
+ test_project = double("A test project",
+ commit_by: test_commit, name: args[:project][:name],
+ web_url: args[:project][:web_url], avatar_url: args[:project][:avatar_url])
+ allow(Project).to receive(:find) { test_project }
+
+ test_pipeline = double("A test pipeline", has_yaml_errors?: has_yaml_errors,
+ yaml_errors: "yaml error description here")
+ allow(Ci::Pipeline).to receive(:find) { test_pipeline }
+
+ allow(Gitlab::UrlBuilder).to receive(:build).with(test_commit).and_return("http://example.com/commit")
+ allow(Gitlab::UrlBuilder).to receive(:build).with(args[:user]).and_return("http://example.gitlab.com/hacker")
+ end
+
+ context 'when the fancy_pipeline_slack_notifications feature flag is disabled' do
+ before do
+ stub_feature_flags(fancy_pipeline_slack_notifications: false)
+ end
+
+ it 'returns an empty pretext' do
+ expect(subject.pretext).to be_empty
+ end
+
+ it "returns the pipeline summary in the activity's title" do
+ expect(subject.activity[:title]).to eq(
+ "Pipeline [#123](http://example.gitlab.com/pipelines/123)" \
+ " of branch [develop](http://example.gitlab.com/commits/develop)" \
+ " by The Hacker (hacker) passed"
+ )
+ end
- it 'returns a message with information about succeeded build' do
- expect(subject.pretext).to be_empty
- expect(subject.fallback).to eq(message)
- expect(subject.attachments).to eq([text: message, color: color])
+ context "when the pipeline failed" do
+ before do
+ args[:object_attributes][:status] = 'failed'
+ end
+
+ it "returns the summary with a 'failed' status" do
+ expect(subject.activity[:title]).to eq(
+ "Pipeline [#123](http://example.gitlab.com/pipelines/123)" \
+ " of branch [develop](http://example.gitlab.com/commits/develop)" \
+ " by The Hacker (hacker) failed"
+ )
end
end
- context 'pipeline failed' do
- let(:status) { 'failed' }
- let(:color) { 'danger' }
- let(:message) { build_message(status, combined_name) }
+ context 'when no user is provided because the pipeline was triggered by the API' do
+ before do
+ args[:user] = nil
+ end
- it 'returns a message with information about failed build' do
- expect(subject.pretext).to be_empty
- expect(subject.fallback).to eq(message)
- expect(subject.attachments).to eq([text: message, color: color])
+ it "returns the summary with 'API' as the username" do
+ expect(subject.activity[:title]).to eq(
+ "Pipeline [#123](http://example.gitlab.com/pipelines/123)" \
+ " of branch [develop](http://example.gitlab.com/commits/develop)" \
+ " by API passed"
+ )
end
+ end
- context 'when triggered by API therefore lacking user' do
- let(:user) { nil }
- let(:message) { build_message(status, 'API') }
+ it "returns a link to the project in the activity's subtitle" do
+ expect(subject.activity[:subtitle]).to eq("in [project_name](http://example.gitlab.com)")
+ end
- it 'returns a message stating it is by API' do
- expect(subject.pretext).to be_empty
- expect(subject.fallback).to eq(message)
- expect(subject.attachments).to eq([text: message, color: color])
- end
+ it "returns the build duration in the activity's text property" do
+ expect(subject.activity[:text]).to eq("in 02:00:10")
+ end
+
+ it "returns the user's avatar image URL in the activity's image property" do
+ expect(subject.activity[:image]).to eq("http://example.com/avatar")
+ end
+
+ context 'when the user does not have an avatar' do
+ before do
+ args[:user][:avatar_url] = nil
+ end
+
+ it "returns an empty string in the activity's image property" do
+ expect(subject.activity[:image]).to be_empty
+ end
+ end
+
+ it "returns the pipeline summary as the attachment's text property" do
+ expect(subject.attachments.first[:text]).to eq(
+ "<http://example.gitlab.com|project_name>:" \
+ " Pipeline <http://example.gitlab.com/pipelines/123|#123>" \
+ " of branch <http://example.gitlab.com/commits/develop|develop>" \
+ " by The Hacker (hacker) passed in 02:00:10"
+ )
+ end
+
+ it "returns 'good' as the attachment's color property" do
+ expect(subject.attachments.first[:color]).to eq('good')
+ end
+
+ context "when the pipeline failed" do
+ before do
+ args[:object_attributes][:status] = 'failed'
+ end
+
+ it "returns 'danger' as the attachment's color property" do
+ expect(subject.attachments.first[:color]).to eq('danger')
end
end
- def build_message(status_text = status, name = user[:name])
- "<http://example.gitlab.com|project_name>:" \
- " Pipeline <http://example.gitlab.com/pipelines/123|#123>" \
- " of branch <http://example.gitlab.com/commits/develop|develop>" \
- " by #{name} #{status_text} in 02:00:10"
+ context 'when rendering markdown' do
+ before do
+ args[:markdown] = true
+ end
+
+ it 'returns the pipeline summary as the attachments in markdown format' do
+ expect(subject.attachments).to eq(
+ "[project_name](http://example.gitlab.com):" \
+ " Pipeline [#123](http://example.gitlab.com/pipelines/123)" \
+ " of branch [develop](http://example.gitlab.com/commits/develop)" \
+ " by The Hacker (hacker) passed in 02:00:10"
+ )
+ end
end
end
- context 'with markdown' do
+ context 'when the fancy_pipeline_slack_notifications feature flag is enabled' do
before do
- args[:markdown] = true
- end
-
- context 'pipeline succeeded' do
- let(:status) { 'success' }
- let(:color) { 'good' }
- let(:message) { build_markdown_message('passed', combined_name) }
-
- it 'returns a message with information about succeeded build' do
- expect(subject.pretext).to be_empty
- expect(subject.attachments).to eq(message)
- expect(subject.activity).to eq({
- title: 'Pipeline [#123](http://example.gitlab.com/pipelines/123) of branch [develop](http://example.gitlab.com/commits/develop) by The Hacker (hacker) passed',
- subtitle: 'in [project_name](http://example.gitlab.com)',
- text: 'in 02:00:10',
- image: ''
- })
+ stub_feature_flags(fancy_pipeline_slack_notifications: true)
+ end
+
+ it 'returns an empty pretext' do
+ expect(subject.pretext).to be_empty
+ end
+
+ it "returns the pipeline summary in the activity's title" do
+ expect(subject.activity[:title]).to eq(
+ "Pipeline [#123](http://example.gitlab.com/pipelines/123)" \
+ " of branch [develop](http://example.gitlab.com/commits/develop)" \
+ " by The Hacker (hacker) has passed"
+ )
+ end
+
+ context "when the pipeline failed" do
+ before do
+ args[:object_attributes][:status] = 'failed'
+ end
+
+ it "returns the summary with a 'failed' status" do
+ expect(subject.activity[:title]).to eq(
+ "Pipeline [#123](http://example.gitlab.com/pipelines/123)" \
+ " of branch [develop](http://example.gitlab.com/commits/develop)" \
+ " by The Hacker (hacker) has failed"
+ )
+ end
+ end
+
+ context "when the pipeline passed with warnings" do
+ before do
+ args[:object_attributes][:detailed_status] = 'passed with warnings'
+ end
+
+ it "returns the summary with a 'passed with warnings' status" do
+ expect(subject.activity[:title]).to eq(
+ "Pipeline [#123](http://example.gitlab.com/pipelines/123)" \
+ " of branch [develop](http://example.gitlab.com/commits/develop)" \
+ " by The Hacker (hacker) has passed with warnings"
+ )
+ end
+ end
+
+ context 'when no user is provided because the pipeline was triggered by the API' do
+ before do
+ args[:user] = nil
+ end
+
+ it "returns the summary with 'API' as the username" do
+ expect(subject.activity[:title]).to eq(
+ "Pipeline [#123](http://example.gitlab.com/pipelines/123)" \
+ " of branch [develop](http://example.gitlab.com/commits/develop)" \
+ " by API has passed"
+ )
+ end
+ end
+
+ it "returns a link to the project in the activity's subtitle" do
+ expect(subject.activity[:subtitle]).to eq("in [project_name](http://example.gitlab.com)")
+ end
+
+ it "returns the build duration in the activity's text property" do
+ expect(subject.activity[:text]).to eq("in 02:00:10")
+ end
+
+ it "returns the user's avatar image URL in the activity's image property" do
+ expect(subject.activity[:image]).to eq("http://example.com/avatar")
+ end
+
+ context 'when the user does not have an avatar' do
+ before do
+ args[:user][:avatar_url] = nil
+ end
+
+ it "returns an empty string in the activity's image property" do
+ expect(subject.activity[:image]).to be_empty
+ end
+ end
+
+ it "returns the pipeline summary as the attachment's fallback property" do
+ expect(subject.attachments.first[:fallback]).to eq(
+ "<http://example.gitlab.com|project_name>:" \
+ " Pipeline <http://example.gitlab.com/pipelines/123|#123>" \
+ " of branch <http://example.gitlab.com/commits/develop|develop>" \
+ " by The Hacker (hacker) has passed in 02:00:10"
+ )
+ end
+
+ it "returns 'good' as the attachment's color property" do
+ expect(subject.attachments.first[:color]).to eq('good')
+ end
+
+ context "when the pipeline failed" do
+ before do
+ args[:object_attributes][:status] = 'failed'
+ end
+
+ it "returns 'danger' as the attachment's color property" do
+ expect(subject.attachments.first[:color]).to eq('danger')
+ end
+ end
+
+ context "when the pipeline passed with warnings" do
+ before do
+ args[:object_attributes][:detailed_status] = 'passed with warnings'
+ end
+
+ it "returns 'warning' as the attachment's color property" do
+ expect(subject.attachments.first[:color]).to eq('warning')
end
end
- context 'pipeline failed' do
- let(:status) { 'failed' }
- let(:color) { 'danger' }
- let(:message) { build_markdown_message(status, combined_name) }
+ it "returns the committer's name and username as the attachment's author_name property" do
+ expect(subject.attachments.first[:author_name]).to eq('The Hacker (hacker)')
+ end
+
+ it "returns the committer's avatar URL as the attachment's author_icon property" do
+ expect(subject.attachments.first[:author_icon]).to eq('http://example.com/avatar')
+ end
+
+ it "returns the committer's GitLab profile URL as the attachment's author_link property" do
+ expect(subject.attachments.first[:author_link]).to eq('http://example.gitlab.com/hacker')
+ end
+
+ context 'when no user is provided because the pipeline was triggered by the API' do
+ before do
+ args[:user] = nil
+ end
+
+ it "returns the committer's name and username as the attachment's author_name property" do
+ expect(subject.attachments.first[:author_name]).to eq('API')
+ end
+
+ it "returns nil as the attachment's author_icon property" do
+ expect(subject.attachments.first[:author_icon]).to be_nil
+ end
+
+ it "returns nil as the attachment's author_link property" do
+ expect(subject.attachments.first[:author_link]).to be_nil
+ end
+ end
+
+ it "returns the pipeline ID, status, and duration as the attachment's title property" do
+ expect(subject.attachments.first[:title]).to eq("Pipeline #123 has passed in 02:00:10")
+ end
+
+ it "returns the pipeline URL as the attachment's title_link property" do
+ expect(subject.attachments.first[:title_link]).to eq("http://example.gitlab.com/pipelines/123")
+ end
+
+ it "returns two attachment fields" do
+ expect(subject.attachments.first[:fields].count).to eq(2)
+ end
+
+ it "returns the commit message as the attachment's second field property" do
+ expect(subject.attachments.first[:fields][0]).to eq({
+ title: "Branch",
+ value: "<http://example.gitlab.com/commits/develop|develop>",
+ short: true
+ })
+ end
+
+ it "returns the ref name and link as the attachment's second field property" do
+ expect(subject.attachments.first[:fields][1]).to eq({
+ title: "Commit",
+ value: "<http://example.com/commit|A test commit message>",
+ short: true
+ })
+ end
+
+ context "when a job in the pipeline fails" do
+ before do
+ args[:builds] = [
+ { id: 1, name: "rspec", status: "failed", stage: "test" },
+ { id: 2, name: "karma", status: "success", stage: "test" }
+ ]
+ end
+
+ it "returns four attachment fields" do
+ expect(subject.attachments.first[:fields].count).to eq(4)
+ end
- it 'returns a message with information about failed build' do
- expect(subject.pretext).to be_empty
- expect(subject.attachments).to eq(message)
- expect(subject.activity).to eq({
- title: 'Pipeline [#123](http://example.gitlab.com/pipelines/123) of branch [develop](http://example.gitlab.com/commits/develop) by The Hacker (hacker) failed',
- subtitle: 'in [project_name](http://example.gitlab.com)',
- text: 'in 02:00:10',
- image: ''
+ it "returns the stage name and link to the 'Failed jobs' tab on the pipeline's page as the attachment's third field property" do
+ expect(subject.attachments.first[:fields][2]).to eq({
+ title: "Failed stage",
+ value: "<http://example.gitlab.com/pipelines/123/failures|test>",
+ short: true
})
end
- context 'when triggered by API therefore lacking user' do
- let(:user) { nil }
- let(:message) { build_markdown_message(status, 'API') }
+ it "returns the job name and link as the attachment's fourth field property" do
+ expect(subject.attachments.first[:fields][3]).to eq({
+ title: "Failed job",
+ value: "<http://example.gitlab.com/-/jobs/1|rspec>",
+ short: true
+ })
+ end
+ end
+
+ context "when lots of jobs across multiple stages fail" do
+ before do
+ args[:builds] = (1..25).map do |i|
+ { id: i, name: "job-#{i}", status: "failed", stage: "stage-" + ((i % 3) + 1).to_s }
+ end
+ end
+
+ it "returns the stage names and links to the 'Failed jobs' tab on the pipeline's page as the attachment's third field property" do
+ expect(subject.attachments.first[:fields][2]).to eq({
+ title: "Failed stages",
+ value: "<http://example.gitlab.com/pipelines/123/failures|stage-2>, <http://example.gitlab.com/pipelines/123/failures|stage-1>, <http://example.gitlab.com/pipelines/123/failures|stage-3>",
+ short: true
+ })
+ end
- it 'returns a message stating it is by API' do
- expect(subject.pretext).to be_empty
- expect(subject.attachments).to eq(message)
- expect(subject.activity).to eq({
- title: 'Pipeline [#123](http://example.gitlab.com/pipelines/123) of branch [develop](http://example.gitlab.com/commits/develop) by API failed',
- subtitle: 'in [project_name](http://example.gitlab.com)',
- text: 'in 02:00:10',
- image: ''
- })
+ it "returns the job names and links as the attachment's fourth field property" do
+ expected_jobs = 25.downto(16).map do |i|
+ "<http://example.gitlab.com/-/jobs/#{i}|job-#{i}>"
end
+
+ expected_jobs << "and <http://example.gitlab.com/pipelines/123/failures|15 more>"
+
+ expect(subject.attachments.first[:fields][3]).to eq({
+ title: "Failed jobs",
+ value: expected_jobs.join(", "),
+ short: true
+ })
end
end
- def build_markdown_message(status_text = status, name = user[:name])
- "[project_name](http://example.gitlab.com):" \
- " Pipeline [#123](http://example.gitlab.com/pipelines/123)" \
- " of branch [develop](http://example.gitlab.com/commits/develop)" \
- " by #{name} #{status_text} in 02:00:10"
+ context "when the CI config file contains a YAML error" do
+ let(:has_yaml_errors) { true }
+
+ it "returns three attachment fields" do
+ expect(subject.attachments.first[:fields].count).to eq(3)
+ end
+
+ it "returns the YAML error deatils as the attachment's third field property" do
+ expect(subject.attachments.first[:fields][2]).to eq({
+ title: "Invalid CI config YAML file",
+ value: "yaml error description here",
+ short: false
+ })
+ end
+ end
+
+ it "returns the stage name and link as the attachment's second field property" do
+ expect(subject.attachments.first[:fields][1]).to eq({
+ title: "Commit",
+ value: "<http://example.com/commit|A test commit message>",
+ short: true
+ })
+ end
+
+ it "returns the project's name as the attachment's footer property" do
+ expect(subject.attachments.first[:footer]).to eq("project_name")
+ end
+
+ it "returns the project's avatar URL as the attachment's footer_icon property" do
+ expect(subject.attachments.first[:footer_icon]).to eq("http://example.com/project_avatar")
+ end
+
+ it "returns the pipeline's timestamp as the attachment's ts property" do
+ expected_ts = Time.parse(args[:object_attributes][:finished_at]).to_i
+ expect(subject.attachments.first[:ts]).to eq(expected_ts)
+ end
+
+ context 'when rendering markdown' do
+ before do
+ args[:markdown] = true
+ end
+
+ it 'returns the pipeline summary as the attachments in markdown format' do
+ expect(subject.attachments).to eq(
+ "[project_name](http://example.gitlab.com):" \
+ " Pipeline [#123](http://example.gitlab.com/pipelines/123)" \
+ " of branch [develop](http://example.gitlab.com/commits/develop)" \
+ " by The Hacker (hacker) has passed in 02:00:10"
+ )
+ end
end
end
end
diff --git a/spec/models/project_services/microsoft_teams_service_spec.rb b/spec/models/project_services/microsoft_teams_service_spec.rb
index 3ffe633868f..73c20359091 100644
--- a/spec/models/project_services/microsoft_teams_service_spec.rb
+++ b/spec/models/project_services/microsoft_teams_service_spec.rb
@@ -292,7 +292,8 @@ describe MicrosoftTeamsService do
context 'when disabled' do
let(:pipeline) do
- create(:ci_pipeline, :failed, project: project, ref: 'not-the-default-branch')
+ create(:ci_pipeline, :failed, project: project,
+ sha: project.commit.sha, ref: 'not-the-default-branch')
end
before do
diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb
index 7d458324c20..24dfd0c5605 100644
--- a/spec/models/project_spec.rb
+++ b/spec/models/project_spec.rb
@@ -2019,62 +2019,33 @@ describe Project do
end
end
- describe '#latest_successful_build_for' do
+ describe '#latest_successful_build_for_ref' do
let(:project) { create(:project, :repository) }
let(:pipeline) { create_pipeline(project) }
- context 'with many builds' do
- it 'gives the latest builds from latest pipeline' do
- pipeline1 = create_pipeline(project)
- pipeline2 = create_pipeline(project)
- create_build(pipeline1, 'test')
- create_build(pipeline1, 'test2')
- build1_p2 = create_build(pipeline2, 'test')
- create_build(pipeline2, 'test2')
-
- expect(project.latest_successful_build_for(build1_p2.name))
- .to eq(build1_p2)
- end
- end
+ it_behaves_like 'latest successful build for sha or ref'
- context 'with succeeded pipeline' do
- let!(:build) { create_build }
+ subject { project.latest_successful_build_for_ref(build_name) }
- context 'standalone pipeline' do
- it 'returns builds for ref for default_branch' do
- expect(project.latest_successful_build_for(build.name))
- .to eq(build)
- end
+ context 'with a specified ref' do
+ let(:build) { create_build }
- it 'returns empty relation if the build cannot be found' do
- expect(project.latest_successful_build_for('TAIL'))
- .to be_nil
- end
- end
-
- context 'with some pending pipeline' do
- before do
- create_build(create_pipeline(project, 'pending'))
- end
+ subject { project.latest_successful_build_for_ref(build.name, project.default_branch) }
- it 'gives the latest build from latest pipeline' do
- expect(project.latest_successful_build_for(build.name))
- .to eq(build)
- end
- end
+ it { is_expected.to eq(build) }
end
+ end
- context 'with pending pipeline' do
- it 'returns empty relation' do
- pipeline.update(status: 'pending')
- pending_build = create_build(pipeline)
+ describe '#latest_successful_build_for_sha' do
+ let(:project) { create(:project, :repository) }
+ let(:pipeline) { create_pipeline(project) }
- expect(project.latest_successful_build_for(pending_build.name)).to be_nil
- end
- end
+ it_behaves_like 'latest successful build for sha or ref'
+
+ subject { project.latest_successful_build_for_sha(build_name, project.commit.sha) }
end
- describe '#latest_successful_build_for!' do
+ describe '#latest_successful_build_for_ref!' do
let(:project) { create(:project, :repository) }
let(:pipeline) { create_pipeline(project) }
@@ -2087,7 +2058,7 @@ describe Project do
build1_p2 = create_build(pipeline2, 'test')
create_build(pipeline2, 'test2')
- expect(project.latest_successful_build_for(build1_p2.name))
+ expect(project.latest_successful_build_for_ref!(build1_p2.name))
.to eq(build1_p2)
end
end
@@ -2097,12 +2068,12 @@ describe Project do
context 'standalone pipeline' do
it 'returns builds for ref for default_branch' do
- expect(project.latest_successful_build_for!(build.name))
+ expect(project.latest_successful_build_for_ref!(build.name))
.to eq(build)
end
it 'returns exception if the build cannot be found' do
- expect { project.latest_successful_build_for!(build.name, 'TAIL') }
+ expect { project.latest_successful_build_for_ref!(build.name, 'TAIL') }
.to raise_error(ActiveRecord::RecordNotFound)
end
end
@@ -2113,7 +2084,7 @@ describe Project do
end
it 'gives the latest build from latest pipeline' do
- expect(project.latest_successful_build_for!(build.name))
+ expect(project.latest_successful_build_for_ref!(build.name))
.to eq(build)
end
end
@@ -2124,7 +2095,7 @@ describe Project do
pipeline.update(status: 'pending')
pending_build = create_build(pipeline)
- expect { project.latest_successful_build_for!(pending_build.name) }
+ expect { project.latest_successful_build_for_ref!(pending_build.name) }
.to raise_error(ActiveRecord::RecordNotFound)
end
end
@@ -2292,7 +2263,7 @@ describe Project do
end
end
- describe '#ancestors_upto', :nested_groups do
+ describe '#ancestors_upto' do
let(:parent) { create(:group) }
let(:child) { create(:group, parent: parent) }
let(:child2) { create(:group, parent: child) }
@@ -2331,7 +2302,7 @@ describe Project do
it { is_expected.to eq(group) }
end
- context 'in a nested group', :nested_groups do
+ context 'in a nested group' do
let(:root) { create(:group) }
let(:child) { create(:group, parent: root) }
let(:project) { create(:project, group: child) }
@@ -2479,7 +2450,7 @@ describe Project do
expect(forked_project.in_fork_network_of?(project)).to be_truthy
end
- it 'is true for a fork of a fork', :postgresql do
+ it 'is true for a fork of a fork' do
other_fork = fork_project(forked_project)
expect(other_fork.in_fork_network_of?(project)).to be_truthy
@@ -3801,7 +3772,7 @@ describe Project do
end
end
- context 'when enabled on root parent', :nested_groups do
+ context 'when enabled on root parent' do
let(:parent_group) { create(:group, parent: create(:group, :auto_devops_enabled)) }
context 'when auto devops instance enabled' do
@@ -3821,7 +3792,7 @@ describe Project do
end
end
- context 'when disabled on root parent', :nested_groups do
+ context 'when disabled on root parent' do
let(:parent_group) { create(:group, parent: create(:group, :auto_devops_disabled)) }
context 'when auto devops instance enabled' do
@@ -4033,7 +4004,7 @@ describe Project do
context 'with a ref that is not the default branch' do
it 'returns the latest successful pipeline for the given ref' do
- expect(project.ci_pipelines).to receive(:latest_successful_for).with('foo')
+ expect(project.ci_pipelines).to receive(:latest_successful_for_ref).with('foo')
project.latest_successful_pipeline_for('foo')
end
@@ -4061,7 +4032,7 @@ describe Project do
it 'memoizes and returns the latest successful pipeline for the default branch' do
pipeline = double(:pipeline)
- expect(project.ci_pipelines).to receive(:latest_successful_for)
+ expect(project.ci_pipelines).to receive(:latest_successful_for_ref)
.with(project.default_branch)
.and_return(pipeline)
.once
@@ -4264,18 +4235,16 @@ describe Project do
expect(project.badges.count).to eq 3
end
- if Group.supports_nested_objects?
- context 'with nested_groups' do
- let(:parent_group) { create(:group) }
+ context 'with nested_groups' do
+ let(:parent_group) { create(:group) }
- before do
- create_list(:group_badge, 2, group: project_group)
- project_group.update(parent: parent_group)
- end
+ before do
+ create_list(:group_badge, 2, group: project_group)
+ project_group.update(parent: parent_group)
+ end
- it 'returns the project and the project nested groups badges' do
- expect(project.badges.count).to eq 5
- end
+ it 'returns the project and the project nested groups badges' do
+ expect(project.badges.count).to eq 5
end
end
end
diff --git a/spec/models/todo_spec.rb b/spec/models/todo_spec.rb
index b5bf294790a..9aeef7c3b4b 100644
--- a/spec/models/todo_spec.rb
+++ b/spec/models/todo_spec.rb
@@ -262,11 +262,7 @@ describe Todo do
todo2 = create(:todo, group: child_group)
todos = described_class.for_group_and_descendants(parent_group)
- expect(todos).to include(todo1)
-
- # Nested groups only work on PostgreSQL, so on MySQL todo2 won't be
- # present.
- expect(todos).to include(todo2) if Gitlab::Database.postgresql?
+ expect(todos).to contain_exactly(todo1, todo2)
end
end
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
index 2d20f8c78cc..35c335c5b5c 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -985,7 +985,7 @@ describe User do
it { expect(user.namespaces).to contain_exactly(user.namespace, group) }
it { expect(user.manageable_namespaces).to contain_exactly(user.namespace, group) }
- context 'with child groups', :nested_groups do
+ context 'with child groups' do
let!(:subgroup) { create(:group, parent: group) }
describe '#manageable_namespaces' do
@@ -2082,11 +2082,7 @@ describe User do
subject { user.membership_groups }
- if Group.supports_nested_objects?
- it { is_expected.to contain_exactly parent_group, child_group }
- else
- it { is_expected.to contain_exactly parent_group }
- end
+ it { is_expected.to contain_exactly parent_group, child_group }
end
describe '#authorizations_for_projects' do
@@ -2386,7 +2382,7 @@ describe User do
it_behaves_like :member
end
- context 'with subgroup with different owner for project runner', :nested_groups do
+ context 'with subgroup with different owner for project runner' do
let(:group) { create(:group) }
let(:another_user) { create(:user) }
let(:subgroup) { create(:group, parent: group) }
@@ -2490,22 +2486,16 @@ describe User do
group.add_owner(user)
end
- if Group.supports_nested_objects?
- it 'returns all groups' do
- is_expected.to match_array [
- group,
- nested_group_1, nested_group_1_1,
- nested_group_2, nested_group_2_1
- ]
- end
- else
- it 'returns the top-level groups' do
- is_expected.to match_array [group]
- end
+ it 'returns all groups' do
+ is_expected.to match_array [
+ group,
+ nested_group_1, nested_group_1_1,
+ nested_group_2, nested_group_2_1
+ ]
end
end
- context 'user is member of the first child (internal node), branch 1', :nested_groups do
+ context 'user is member of the first child (internal node), branch 1' do
before do
nested_group_1.add_owner(user)
end
@@ -2518,7 +2508,7 @@ describe User do
end
end
- context 'user is member of the first child (internal node), branch 2', :nested_groups do
+ context 'user is member of the first child (internal node), branch 2' do
before do
nested_group_2.add_owner(user)
end
@@ -2531,7 +2521,7 @@ describe User do
end
end
- context 'user is member of the last child (leaf node)', :nested_groups do
+ context 'user is member of the last child (leaf node)' do
before do
nested_group_1_1.add_owner(user)
end
@@ -2687,7 +2677,7 @@ describe User do
end
end
- context 'with 2FA requirement from expanded groups', :nested_groups do
+ context 'with 2FA requirement from expanded groups' do
let!(:group1) { create :group, require_two_factor_authentication: true }
let!(:group1a) { create :group, parent: group1 }
@@ -2702,7 +2692,7 @@ describe User do
end
end
- context 'with 2FA requirement on nested child group', :nested_groups do
+ context 'with 2FA requirement on nested child group' do
let!(:group1) { create :group, require_two_factor_authentication: false }
let!(:group1a) { create :group, require_two_factor_authentication: true, parent: group1 }
diff --git a/spec/policies/group_member_policy_spec.rb b/spec/policies/group_member_policy_spec.rb
index 7bd7184cffe..a4f3301a064 100644
--- a/spec/policies/group_member_policy_spec.rb
+++ b/spec/policies/group_member_policy_spec.rb
@@ -58,7 +58,7 @@ describe GroupMemberPolicy do
end
end
- context 'with the group parent', :postgresql do
+ context 'with the group parent' do
let(:current_user) { create :user }
let(:subgroup) { create(:group, :private, parent: group)}
diff --git a/spec/policies/group_policy_spec.rb b/spec/policies/group_policy_spec.rb
index dc3675a7b9e..be55d94daec 100644
--- a/spec/policies/group_policy_spec.rb
+++ b/spec/policies/group_policy_spec.rb
@@ -51,7 +51,7 @@ describe GroupPolicy do
it { expect_allowed(:read_label, :read_list) }
- context 'in subgroups', :nested_groups do
+ context 'in subgroups' do
let(:subgroup) { create(:group, :private, parent: group) }
let(:project) { create(:project, namespace: subgroup) }
@@ -104,8 +104,6 @@ describe GroupPolicy do
end
it 'allows every maintainer permission plus creating subgroups' do
- allow(Group).to receive(:supports_nested_objects?).and_return(true)
-
create_subgroup_permission = [:create_subgroup]
updated_maintainer_permissions =
maintainer_permissions + create_subgroup_permission
@@ -122,8 +120,6 @@ describe GroupPolicy do
context 'with subgroup_creation_level set to owner' do
it 'allows every maintainer permission' do
- allow(Group).to receive(:supports_nested_objects?).and_return(true)
-
expect_allowed(*guest_permissions)
expect_allowed(*reporter_permissions)
expect_allowed(*developer_permissions)
@@ -137,8 +133,6 @@ describe GroupPolicy do
let(:current_user) { owner }
it do
- allow(Group).to receive(:supports_nested_objects?).and_return(true)
-
expect_allowed(*guest_permissions)
expect_allowed(*reporter_permissions)
expect_allowed(*developer_permissions)
@@ -151,8 +145,6 @@ describe GroupPolicy do
let(:current_user) { admin }
it do
- allow(Group).to receive(:supports_nested_objects?).and_return(true)
-
expect_allowed(*guest_permissions)
expect_allowed(*reporter_permissions)
expect_allowed(*developer_permissions)
@@ -161,52 +153,7 @@ describe GroupPolicy do
end
end
- describe 'when nested group support feature is disabled' do
- before do
- allow(Group).to receive(:supports_nested_objects?).and_return(false)
- end
-
- context 'admin' do
- let(:current_user) { admin }
-
- it 'allows every owner permission except creating subgroups' do
- create_subgroup_permission = [:create_subgroup]
- updated_owner_permissions =
- owner_permissions - create_subgroup_permission
-
- expect_disallowed(*create_subgroup_permission)
- expect_allowed(*updated_owner_permissions)
- end
- end
-
- context 'owner' do
- let(:current_user) { owner }
-
- it 'allows every owner permission except creating subgroups' do
- create_subgroup_permission = [:create_subgroup]
- updated_owner_permissions =
- owner_permissions - create_subgroup_permission
-
- expect_disallowed(*create_subgroup_permission)
- expect_allowed(*updated_owner_permissions)
- end
- end
-
- context 'maintainer' do
- let(:current_user) { maintainer }
-
- it 'allows every maintainer permission except creating subgroups' do
- create_subgroup_permission = [:create_subgroup]
- updated_maintainer_permissions =
- maintainer_permissions - create_subgroup_permission
-
- expect_disallowed(*create_subgroup_permission)
- expect_allowed(*updated_maintainer_permissions)
- end
- end
- end
-
- describe 'private nested group use the highest access level from the group and inherited permissions', :nested_groups do
+ describe 'private nested group use the highest access level from the group and inherited permissions' do
let(:nested_group) do
create(:group, :private, :owner_subgroup_creation_only, parent: group)
end
@@ -289,8 +236,6 @@ describe GroupPolicy do
let(:current_user) { owner }
it do
- allow(Group).to receive(:supports_nested_objects?).and_return(true)
-
expect_allowed(*guest_permissions)
expect_allowed(*reporter_permissions)
expect_allowed(*developer_permissions)
diff --git a/spec/presenters/clusters/cluster_presenter_spec.rb b/spec/presenters/clusters/cluster_presenter_spec.rb
index 7054a70e2ed..6b988e2645b 100644
--- a/spec/presenters/clusters/cluster_presenter_spec.rb
+++ b/spec/presenters/clusters/cluster_presenter_spec.rb
@@ -43,7 +43,7 @@ describe Clusters::ClusterPresenter do
end
shared_examples 'ancestor clusters' do
- context 'ancestor clusters', :nested_groups do
+ context 'ancestor clusters' do
let(:root_group) { create(:group, name: 'Root Group') }
let(:parent) { create(:group, name: 'parent', parent: root_group) }
let(:child) { create(:group, name: 'child', parent: parent) }
diff --git a/spec/requests/api/boards_spec.rb b/spec/requests/api/boards_spec.rb
index de79e8c4c5c..0b9c0c2ebe9 100644
--- a/spec/requests/api/boards_spec.rb
+++ b/spec/requests/api/boards_spec.rb
@@ -63,7 +63,7 @@ describe API::Boards do
end
end
- describe "POST /groups/:id/boards/lists", :nested_groups do
+ describe "POST /groups/:id/boards/lists" do
set(:group) { create(:group) }
set(:board_parent) { create(:group, parent: group ) }
let(:url) { "/groups/#{board_parent.id}/boards/#{board.id}/lists" }
diff --git a/spec/requests/api/graphql/namespace/projects_spec.rb b/spec/requests/api/graphql/namespace/projects_spec.rb
index 63fa16c79ca..815e9531ecf 100644
--- a/spec/requests/api/graphql/namespace/projects_spec.rb
+++ b/spec/requests/api/graphql/namespace/projects_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'getting projects', :nested_groups do
+describe 'getting projects' do
include GraphqlHelpers
let(:group) { create(:group) }
diff --git a/spec/requests/api/group_labels_spec.rb b/spec/requests/api/group_labels_spec.rb
index 3769f8b78e4..fcea57d9df7 100644
--- a/spec/requests/api/group_labels_spec.rb
+++ b/spec/requests/api/group_labels_spec.rb
@@ -94,7 +94,7 @@ describe API::GroupLabels do
expect(response).to have_gitlab_http_status(400)
end
- it "does not delete parent's group labels", :nested_groups do
+ it "does not delete parent's group labels" do
subgroup = create(:group, parent: group)
subgroup_label = create(:group_label, title: 'feature', group: subgroup)
@@ -127,7 +127,7 @@ describe API::GroupLabels do
expect(json_response['description']).to eq('test')
end
- it "does not update parent's group label", :nested_groups do
+ it "does not update parent's group label" do
subgroup = create(:group, parent: group)
subgroup_label = create(:group_label, title: 'feature', group: subgroup)
diff --git a/spec/requests/api/groups_spec.rb b/spec/requests/api/groups_spec.rb
index 52d926d5484..50f36141aed 100644
--- a/spec/requests/api/groups_spec.rb
+++ b/spec/requests/api/groups_spec.rb
@@ -530,7 +530,7 @@ describe API::Groups do
expect(json_response.length).to eq(2)
end
- it "returns projects including those in subgroups", :nested_groups do
+ it "returns projects including those in subgroups" do
subgroup = create(:group, parent: group1)
create(:project, group: subgroup)
create(:project, group: subgroup)
@@ -642,7 +642,7 @@ describe API::Groups do
end
end
- describe 'GET /groups/:id/subgroups', :nested_groups do
+ describe 'GET /groups/:id/subgroups' do
let!(:subgroup1) { create(:group, parent: group1) }
let!(:subgroup2) { create(:group, :private, parent: group1) }
let!(:subgroup3) { create(:group, :private, parent: group2) }
@@ -786,7 +786,7 @@ describe API::Groups do
expect(response).to have_gitlab_http_status(403)
end
- context 'as owner', :nested_groups do
+ context 'as owner' do
before do
group2.add_owner(user1)
end
@@ -798,7 +798,7 @@ describe API::Groups do
end
end
- context 'as maintainer', :nested_groups do
+ context 'as maintainer' do
before do
group2.add_maintainer(user1)
end
@@ -825,7 +825,7 @@ describe API::Groups do
expect(json_response["visibility"]).to eq(Gitlab::VisibilityLevel.string_level(Gitlab::CurrentSettings.current_application_settings.default_group_visibility))
end
- it "creates a nested group", :nested_groups do
+ it "creates a nested group" do
parent = create(:group)
parent.add_owner(user3)
group = attributes_for(:group, { parent_id: parent.id })
diff --git a/spec/requests/api/issues/get_group_issues_spec.rb b/spec/requests/api/issues/get_group_issues_spec.rb
index 9a41d790945..5916bb11516 100644
--- a/spec/requests/api/issues/get_group_issues_spec.rb
+++ b/spec/requests/api/issues/get_group_issues_spec.rb
@@ -82,7 +82,7 @@ describe API::Issues do
end
end
- context 'when group has subgroups', :nested_groups do
+ context 'when group has subgroups' do
let(:subgroup_1) { create(:group, parent: group) }
let(:subgroup_2) { create(:group, parent: subgroup_1) }
diff --git a/spec/requests/api/members_spec.rb b/spec/requests/api/members_spec.rb
index 55f38079b1f..26f6e705528 100644
--- a/spec/requests/api/members_spec.rb
+++ b/spec/requests/api/members_spec.rb
@@ -99,7 +99,7 @@ describe API::Members do
end
end
- describe 'GET /:source_type/:id/members/all', :nested_groups do
+ describe 'GET /:source_type/:id/members/all' do
let(:nested_user) { create(:user) }
let(:project_user) { create(:user) }
let(:linked_group_user) { create(:user) }
@@ -238,7 +238,7 @@ describe API::Members do
end
context 'access levels' do
- it 'does not create the member if group level is higher', :nested_groups do
+ it 'does not create the member if group level is higher' do
parent = create(:group)
group.update(parent: parent)
@@ -252,7 +252,7 @@ describe API::Members do
expect(json_response['message']['access_level']).to eq(["should be greater than or equal to Developer inherited membership from group #{parent.name}"])
end
- it 'creates the member if group level is lower', :nested_groups do
+ it 'creates the member if group level is lower' do
parent = create(:group)
group.update(parent: parent)
diff --git a/spec/requests/api/merge_requests_spec.rb b/spec/requests/api/merge_requests_spec.rb
index ced853caab4..7a6f1cd548c 100644
--- a/spec/requests/api/merge_requests_spec.rb
+++ b/spec/requests/api/merge_requests_spec.rb
@@ -723,7 +723,7 @@ describe API::MergeRequests do
it_behaves_like 'merge requests list'
- context 'when have subgroups', :nested_groups do
+ context 'when have subgroups' do
let!(:group) { create(:group, :public) }
let!(:subgroup) { create(:group, parent: group) }
let!(:project) { create(:project, :public, :repository, creator: user, namespace: subgroup, only_allow_merge_if_pipeline_succeeds: false) }
diff --git a/spec/requests/api/projects_spec.rb b/spec/requests/api/projects_spec.rb
index fee300e9d7a..5b3a2412aff 100644
--- a/spec/requests/api/projects_spec.rb
+++ b/spec/requests/api/projects_spec.rb
@@ -1357,7 +1357,7 @@ describe API::Projects do
end
end
- context 'nested group project', :nested_groups do
+ context 'nested group project' do
let(:group) { create(:group) }
let(:nested_group) { create(:group, parent: group) }
let(:project2) { create(:project, group: nested_group) }
diff --git a/spec/requests/api/resource_label_events_spec.rb b/spec/requests/api/resource_label_events_spec.rb
index 37b46eaeb86..25bea627b0c 100644
--- a/spec/requests/api/resource_label_events_spec.rb
+++ b/spec/requests/api/resource_label_events_spec.rb
@@ -4,55 +4,12 @@ require 'spec_helper'
describe API::ResourceLabelEvents do
set(:user) { create(:user) }
- set(:project) { create(:project, :public, :repository, namespace: user.namespace) }
- set(:private_user) { create(:user) }
+ set(:project) { create(:project, :public, namespace: user.namespace) }
before do
project.add_developer(user)
end
- shared_examples 'resource_label_events API' do |parent_type, eventable_type, id_name|
- describe "GET /#{parent_type}/:id/#{eventable_type}/:noteable_id/resource_label_events" do
- it "returns an array of resource label events" do
- get api("/#{parent_type}/#{parent.id}/#{eventable_type}/#{eventable[id_name]}/resource_label_events", user)
-
- expect(response).to have_gitlab_http_status(200)
- expect(response).to include_pagination_headers
- expect(json_response).to be_an Array
- expect(json_response.first['id']).to eq(event.id)
- end
-
- it "returns a 404 error when eventable id not found" do
- get api("/#{parent_type}/#{parent.id}/#{eventable_type}/12345/resource_label_events", user)
-
- expect(response).to have_gitlab_http_status(404)
- end
-
- it "returns 404 when not authorized" do
- parent.update!(visibility_level: Gitlab::VisibilityLevel::PRIVATE)
-
- get api("/#{parent_type}/#{parent.id}/#{eventable_type}/#{eventable[id_name]}/resource_label_events", private_user)
-
- expect(response).to have_gitlab_http_status(404)
- end
- end
-
- describe "GET /#{parent_type}/:id/#{eventable_type}/:noteable_id/resource_label_events/:event_id" do
- it "returns a resource label event by id" do
- get api("/#{parent_type}/#{parent.id}/#{eventable_type}/#{eventable[id_name]}/resource_label_events/#{event.id}", user)
-
- expect(response).to have_gitlab_http_status(200)
- expect(json_response['id']).to eq(event.id)
- end
-
- it "returns a 404 error if resource label event not found" do
- get api("/#{parent_type}/#{parent.id}/#{eventable_type}/#{eventable[id_name]}/resource_label_events/12345", user)
-
- expect(response).to have_gitlab_http_status(404)
- end
- end
- end
-
context 'when eventable is an Issue' do
let(:issue) { create(:issue, project: project, author: user) }
diff --git a/spec/requests/openid_connect_spec.rb b/spec/requests/openid_connect_spec.rb
index 86e41cbdf00..025568d8bea 100644
--- a/spec/requests/openid_connect_spec.rb
+++ b/spec/requests/openid_connect_spec.rb
@@ -104,7 +104,7 @@ describe 'OpenID Connect requests' do
expect(json_response).to match(id_token_claims.merge(user_info_claims))
expected_groups = [group1.full_path, group3.full_path]
- expected_groups << group4.full_path if Group.supports_nested_objects?
+ expected_groups << group4.full_path
expect(json_response['groups']).to match_array(expected_groups)
end
diff --git a/spec/serializers/group_child_entity_spec.rb b/spec/serializers/group_child_entity_spec.rb
index b58d95ccb43..00e2f931549 100644
--- a/spec/serializers/group_child_entity_spec.rb
+++ b/spec/serializers/group_child_entity_spec.rb
@@ -62,7 +62,7 @@ describe GroupChildEntity do
it_behaves_like 'group child json'
end
- describe 'for a group', :nested_groups do
+ describe 'for a group' do
let(:description) { 'Awesomeness' }
let(:object) do
create(:group, :nested, :with_avatar,
diff --git a/spec/serializers/group_child_serializer_spec.rb b/spec/serializers/group_child_serializer_spec.rb
index 5541ada3750..c9e8535585b 100644
--- a/spec/serializers/group_child_serializer_spec.rb
+++ b/spec/serializers/group_child_serializer_spec.rb
@@ -16,7 +16,7 @@ describe GroupChildSerializer do
end
end
- context 'with a hierarchy', :nested_groups do
+ context 'with a hierarchy' do
let(:parent) { create(:group) }
subject(:serializer) do
@@ -75,7 +75,7 @@ describe GroupChildSerializer do
expect(serializer.represent(build_list(:project, 2))).to be_kind_of(Array)
end
- context 'with a hierarchy', :nested_groups do
+ context 'with a hierarchy' do
let(:parent) { create(:group) }
subject(:serializer) do
diff --git a/spec/serializers/pipeline_serializer_spec.rb b/spec/serializers/pipeline_serializer_spec.rb
index 54e6abc2d3a..7f9827329b3 100644
--- a/spec/serializers/pipeline_serializer_spec.rb
+++ b/spec/serializers/pipeline_serializer_spec.rb
@@ -126,7 +126,7 @@ describe PipelineSerializer do
expect(subject.all? { |entry| entry[:merge_request].present? }).to be_truthy
end
- it 'preloads related merge requests', :postgresql do
+ it 'preloads related merge requests' do
recorded = ActiveRecord::QueryRecorder.new { subject }
expect(recorded.log)
diff --git a/spec/services/boards/issues/list_service_spec.rb b/spec/services/boards/issues/list_service_spec.rb
index 40878e24cb4..931b67b2950 100644
--- a/spec/services/boards/issues/list_service_spec.rb
+++ b/spec/services/boards/issues/list_service_spec.rb
@@ -112,7 +112,7 @@ describe Boards::Issues::ListService do
it_behaves_like 'issues list service'
end
- context 'and group is an ancestor', :nested_groups do
+ context 'and group is an ancestor' do
let(:parent) { create(:group) }
let(:group) { create(:group, parent: parent) }
let!(:backlog) { create(:backlog_list, board: board) }
diff --git a/spec/services/groups/auto_devops_service_spec.rb b/spec/services/groups/auto_devops_service_spec.rb
index 7f8ab517cef..7591b2f6f12 100644
--- a/spec/services/groups/auto_devops_service_spec.rb
+++ b/spec/services/groups/auto_devops_service_spec.rb
@@ -47,7 +47,7 @@ describe Groups::AutoDevopsService, '#execute' do
expect(subgroup_1.auto_devops_enabled?).to eq(false)
end
- context 'when subgroups have projects', :nested_groups do
+ context 'when subgroups have projects' do
it 'reflects changes on projects' do
subgroup_1 = create(:group, parent: group)
project_1 = create(:project, namespace: subgroup_1)
diff --git a/spec/services/groups/create_service_spec.rb b/spec/services/groups/create_service_spec.rb
index a7c95428485..0f9f20de586 100644
--- a/spec/services/groups/create_service_spec.rb
+++ b/spec/services/groups/create_service_spec.rb
@@ -44,7 +44,7 @@ describe Groups::CreateService, '#execute' do
end
end
- describe 'creating subgroup', :nested_groups do
+ describe 'creating subgroup' do
let!(:group) { create(:group) }
let!(:service) { described_class.new(user, group_params.merge(parent_id: group.id)) }
@@ -54,47 +54,31 @@ describe Groups::CreateService, '#execute' do
end
it { is_expected.to be_persisted }
+ end
- context 'when nested groups feature is disabled' do
- it 'does not save group and returns an error' do
- allow(Group).to receive(:supports_nested_objects?).and_return(false)
+ context 'as guest' do
+ it 'does not save group and returns an error' do
+ is_expected.not_to be_persisted
- is_expected.not_to be_persisted
- expect(subject.errors[:parent_id]).to include('You don’t have permission to create a subgroup in this group.')
- expect(subject.parent_id).to be_nil
- end
+ expect(subject.errors[:parent_id].first).to eq('You don’t have permission to create a subgroup in this group.')
+ expect(subject.parent_id).to be_nil
end
end
- context 'when nested groups feature is enabled' do
+ context 'as owner' do
before do
- allow(Group).to receive(:supports_nested_objects?).and_return(true)
- end
-
- context 'as guest' do
- it 'does not save group and returns an error' do
- is_expected.not_to be_persisted
-
- expect(subject.errors[:parent_id].first).to eq('You don’t have permission to create a subgroup in this group.')
- expect(subject.parent_id).to be_nil
- end
+ group.add_owner(user)
end
- context 'as owner' do
- before do
- group.add_owner(user)
- end
+ it { is_expected.to be_persisted }
+ end
- it { is_expected.to be_persisted }
+ context 'as maintainer' do
+ before do
+ group.add_maintainer(user)
end
- context 'as maintainer' do
- before do
- group.add_maintainer(user)
- end
-
- it { is_expected.to be_persisted }
- end
+ it { is_expected.to be_persisted }
end
end
diff --git a/spec/services/groups/nested_create_service_spec.rb b/spec/services/groups/nested_create_service_spec.rb
index 13acf9e055b..b30392c1b12 100644
--- a/spec/services/groups/nested_create_service_spec.rb
+++ b/spec/services/groups/nested_create_service_spec.rb
@@ -28,35 +28,7 @@ describe Groups::NestedCreateService do
end
end
- describe 'without subgroups' do
- let(:params) { { group_path: 'a-group' } }
-
- before do
- allow(Group).to receive(:supports_nested_objects?) { false }
- end
-
- it 'creates the group' do
- group = service.execute
-
- expect(group).to be_persisted
- end
-
- it 'returns the group if it already existed' do
- existing_group = create(:group, path: 'a-group')
-
- expect(service.execute).to eq(existing_group)
- end
-
- it 'raises an error when tring to create a subgroup' do
- service = described_class.new(user, group_path: 'a-group/a-sub-group')
-
- expect { service.execute }.to raise_error('Nested groups are not supported on MySQL')
- end
-
- it_behaves_like 'with a visibility level'
- end
-
- describe 'with subgroups', :nested_groups do
+ describe 'with subgroups' do
let(:params) { { group_path: 'a-group/a-sub-group' } }
describe "#execute" do
diff --git a/spec/services/groups/transfer_service_spec.rb b/spec/services/groups/transfer_service_spec.rb
index b5708ebba76..f3af8cf5f3b 100644
--- a/spec/services/groups/transfer_service_spec.rb
+++ b/spec/services/groups/transfer_service_spec.rb
@@ -2,28 +2,13 @@
require 'rails_helper'
-describe Groups::TransferService, :postgresql do
+describe Groups::TransferService do
let(:user) { create(:user) }
let(:new_parent_group) { create(:group, :public) }
let!(:group_member) { create(:group_member, :owner, group: group, user: user) }
let(:transfer_service) { described_class.new(group, user) }
shared_examples 'ensuring allowed transfer for a group' do
- context 'with other database than PostgreSQL' do
- before do
- allow(Group).to receive(:supports_nested_objects?).and_return(false)
- end
-
- it 'returns false' do
- expect(transfer_service.execute(new_parent_group)).to be_falsy
- end
-
- it 'adds an error on group' do
- transfer_service.execute(new_parent_group)
- expect(transfer_service.error).to eq('Transfer failed: Database is not supported.')
- end
- end
-
context "when there's an exception on GitLab shell directories" do
let(:new_parent_group) { create(:group, :public) }
diff --git a/spec/services/groups/update_service_spec.rb b/spec/services/groups/update_service_spec.rb
index d081c20f669..5d4576139f7 100644
--- a/spec/services/groups/update_service_spec.rb
+++ b/spec/services/groups/update_service_spec.rb
@@ -133,7 +133,7 @@ describe Groups::UpdateService do
end
end
- context 'for a subgroup', :nested_groups do
+ context 'for a subgroup' do
let(:subgroup) { create(:group, :private, parent: private_group) }
context 'when the parent group share_with_group_lock is enabled' do
diff --git a/spec/services/issues/update_service_spec.rb b/spec/services/issues/update_service_spec.rb
index 68b79132096..3ae7c7b1c1d 100644
--- a/spec/services/issues/update_service_spec.rb
+++ b/spec/services/issues/update_service_spec.rb
@@ -116,7 +116,7 @@ describe Issues::UpdateService, :mailer do
expect(issue.relative_position).to be_between(issue1.relative_position, issue2.relative_position)
end
- context 'when moving issue between issues from different projects', :nested_groups do
+ context 'when moving issue between issues from different projects' do
let(:group) { create(:group) }
let(:subgroup) { create(:group, parent: group) }
@@ -703,7 +703,7 @@ describe Issues::UpdateService, :mailer do
end
end
- context 'when moving an issue ', :nested_groups do
+ context 'when moving an issue ' do
it 'raises an error for invalid move ids within a project' do
opts = { move_between_ids: [9000, 9999] }
diff --git a/spec/services/members/destroy_service_spec.rb b/spec/services/members/destroy_service_spec.rb
index 52f9a305d8f..7dce7f035d4 100644
--- a/spec/services/members/destroy_service_spec.rb
+++ b/spec/services/members/destroy_service_spec.rb
@@ -267,15 +267,15 @@ describe Members::DestroyService do
expect(group.members.map(&:user)).not_to include(member_user)
end
- it 'removes the subgroup membership', :postgresql do
+ it 'removes the subgroup membership' do
expect(subgroup.members.map(&:user)).not_to include(member_user)
end
- it 'removes the subsubgroup membership', :postgresql do
+ it 'removes the subsubgroup membership' do
expect(subsubgroup.members.map(&:user)).not_to include(member_user)
end
- it 'removes the subsubproject membership', :postgresql do
+ it 'removes the subsubproject membership' do
expect(subsubproject.members.map(&:user)).not_to include(member_user)
end
diff --git a/spec/services/notification_service_spec.rb b/spec/services/notification_service_spec.rb
index c20de1fd079..1dcade1de0d 100644
--- a/spec/services/notification_service_spec.rb
+++ b/spec/services/notification_service_spec.rb
@@ -111,7 +111,7 @@ describe NotificationService, :mailer do
should_email(participant)
end
- context 'for subgroups', :nested_groups do
+ context 'for subgroups' do
before do
build_group(project)
end
@@ -337,7 +337,7 @@ describe NotificationService, :mailer do
it_behaves_like 'new note notifications'
- context 'which is a subgroup', :nested_groups do
+ context 'which is a subgroup' do
let!(:parent) { create(:group) }
let!(:group) { create(:group, parent: parent) }
@@ -388,7 +388,7 @@ describe NotificationService, :mailer do
should_email(admin)
end
- context 'on project that belongs to subgroup', :nested_groups do
+ context 'on project that belongs to subgroup' do
let(:group_reporter) { create(:user) }
let(:group_guest) { create(:user) }
let(:parent_group) { create(:group) }
@@ -458,7 +458,7 @@ describe NotificationService, :mailer do
should_not_email_nested_group_user(@pg_disabled)
end
- it 'notifies parent group members with mention level', :nested_groups do
+ it 'notifies parent group members with mention level' do
note = create(:note_on_issue, noteable: issue, project_id: issue.project_id, note: "@#{@pg_mention.username}")
notification.new_note(note)
@@ -2410,52 +2410,40 @@ describe NotificationService, :mailer do
group
end
- # Creates a nested group only if supported
- # to avoid errors on MySQL
def create_nested_group(visibility)
- if Group.supports_nested_objects?
- parent_group = create(:group, visibility)
- child_group = create(:group, visibility, parent: parent_group)
+ parent_group = create(:group, visibility)
+ child_group = create(:group, visibility, parent: parent_group)
- # Parent group member: global=disabled, parent_group=watch, child_group=global
- @pg_watcher ||= create_user_with_notification(:watch, 'parent_group_watcher', parent_group)
- @pg_watcher.notification_settings_for(nil).disabled!
+ # Parent group member: global=disabled, parent_group=watch, child_group=global
+ @pg_watcher ||= create_user_with_notification(:watch, 'parent_group_watcher', parent_group)
+ @pg_watcher.notification_settings_for(nil).disabled!
- # Parent group member: global=global, parent_group=disabled, child_group=global
- @pg_disabled ||= create_user_with_notification(:disabled, 'parent_group_disabled', parent_group)
- @pg_disabled.notification_settings_for(nil).global!
+ # Parent group member: global=global, parent_group=disabled, child_group=global
+ @pg_disabled ||= create_user_with_notification(:disabled, 'parent_group_disabled', parent_group)
+ @pg_disabled.notification_settings_for(nil).global!
- # Parent group member: global=global, parent_group=mention, child_group=global
- @pg_mention ||= create_user_with_notification(:mention, 'parent_group_mention', parent_group)
- @pg_mention.notification_settings_for(nil).global!
+ # Parent group member: global=global, parent_group=mention, child_group=global
+ @pg_mention ||= create_user_with_notification(:mention, 'parent_group_mention', parent_group)
+ @pg_mention.notification_settings_for(nil).global!
- # Parent group member: global=global, parent_group=participating, child_group=global
- @pg_participant ||= create_user_with_notification(:participating, 'parent_group_participant', parent_group)
- @pg_mention.notification_settings_for(nil).global!
+ # Parent group member: global=global, parent_group=participating, child_group=global
+ @pg_participant ||= create_user_with_notification(:participating, 'parent_group_participant', parent_group)
+ @pg_mention.notification_settings_for(nil).global!
- child_group
- else
- create(:group, visibility)
- end
+ child_group
end
def add_member_for_parent_group(user, project)
- return unless Group.supports_nested_objects?
-
project.reload
project.group.parent.add_maintainer(user)
end
def should_email_nested_group_user(user, times: 1, recipients: email_recipients)
- return unless Group.supports_nested_objects?
-
should_email(user, times: 1, recipients: email_recipients)
end
def should_not_email_nested_group_user(user, recipients: email_recipients)
- return unless Group.supports_nested_objects?
-
should_not_email(user, recipients: email_recipients)
end
diff --git a/spec/services/projects/autocomplete_service_spec.rb b/spec/services/projects/autocomplete_service_spec.rb
index 2f70c8ea94d..b625653bc77 100644
--- a/spec/services/projects/autocomplete_service_spec.rb
+++ b/spec/services/projects/autocomplete_service_spec.rb
@@ -118,7 +118,7 @@ describe Projects::AutocompleteService do
expect(milestone_titles).to eq([group_milestone2.title, group_milestone1.title])
end
- context 'with nested groups', :nested_groups do
+ context 'with nested groups' do
let(:subgroup) { create(:group, :public, parent: group) }
let!(:subgroup_milestone) { create(:milestone, group: subgroup) }
diff --git a/spec/services/todos/destroy/entity_leave_service_spec.rb b/spec/services/todos/destroy/entity_leave_service_spec.rb
index 2a553e18807..ce809bbf6c5 100644
--- a/spec/services/todos/destroy/entity_leave_service_spec.rb
+++ b/spec/services/todos/destroy/entity_leave_service_spec.rb
@@ -176,7 +176,7 @@ describe Todos::Destroy::EntityLeaveService do
end
end
- context 'with nested groups', :nested_groups do
+ context 'with nested groups' do
let(:subgroup) { create(:group, :private, parent: group) }
let(:subgroup2) { create(:group, :private, parent: group) }
let(:subproject) { create(:project, group: subgroup) }
diff --git a/spec/services/todos/destroy/group_private_service_spec.rb b/spec/services/todos/destroy/group_private_service_spec.rb
index a1798686d7c..7dd495847b3 100644
--- a/spec/services/todos/destroy/group_private_service_spec.rb
+++ b/spec/services/todos/destroy/group_private_service_spec.rb
@@ -35,7 +35,7 @@ describe Todos::Destroy::GroupPrivateService do
expect(project_member.todos).to match_array([todo_project_member])
end
- context 'with nested groups', :nested_groups do
+ context 'with nested groups' do
let(:parent_group) { create(:group) }
let(:subgroup) { create(:group, :private, parent: group) }
let(:subproject) { create(:project, group: subgroup) }
diff --git a/spec/services/users/refresh_authorized_projects_service_spec.rb b/spec/services/users/refresh_authorized_projects_service_spec.rb
index 0287a24808d..f5a914bb482 100644
--- a/spec/services/users/refresh_authorized_projects_service_spec.rb
+++ b/spec/services/users/refresh_authorized_projects_service_spec.rb
@@ -135,7 +135,7 @@ describe Users::RefreshAuthorizedProjectsService do
end
end
- context 'projects of subgroups of groups the user is a member of', :nested_groups do
+ context 'projects of subgroups of groups the user is a member of' do
let(:group) { create(:group) }
let(:nested_group) { create(:group, parent: group) }
let!(:other_project) { create(:project, group: nested_group) }
@@ -163,7 +163,7 @@ describe Users::RefreshAuthorizedProjectsService do
end
end
- context 'projects shared with subgroups of groups the user is a member of', :nested_groups do
+ context 'projects shared with subgroups of groups the user is a member of' do
let(:group) { create(:group) }
let(:nested_group) { create(:group, parent: group) }
let(:other_project) { create(:project) }
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index a44b5069ade..6ef5f46c81b 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -258,14 +258,6 @@ RSpec.configure do |config|
Gitlab::CurrentSettings.clear_in_memory_application_settings!
end
- config.around(:each, :nested_groups) do |example|
- example.run if Group.supports_nested_objects?
- end
-
- config.around(:each, :postgresql) do |example|
- example.run if Gitlab::Database.postgresql?
- end
-
# This makes sure the `ApplicationController#can?` method is stubbed with the
# original implementation for all view specs.
config.before(:each, type: :view) do
diff --git a/spec/support/controllers/githubish_import_controller_shared_examples.rb b/spec/support/controllers/githubish_import_controller_shared_examples.rb
index 7ddec49bfdf..718d9857b18 100644
--- a/spec/support/controllers/githubish_import_controller_shared_examples.rb
+++ b/spec/support/controllers/githubish_import_controller_shared_examples.rb
@@ -323,7 +323,7 @@ shared_examples 'a GitHub-ish import controller: POST create' do
end
end
- context 'user has chosen an existing nested namespace and name for the project', :postgresql do
+ context 'user has chosen an existing nested namespace and name for the project' do
let(:parent_namespace) { create(:group, name: 'foo') }
let(:nested_namespace) { create(:group, name: 'bar', parent: parent_namespace) }
let(:test_name) { 'test_name' }
@@ -342,7 +342,7 @@ shared_examples 'a GitHub-ish import controller: POST create' do
end
end
- context 'user has chosen a non-existent nested namespaces and name for the project', :postgresql do
+ context 'user has chosen a non-existent nested namespaces and name for the project' do
let(:test_name) { 'test_name' }
it 'takes the selected namespace and name' do
@@ -373,7 +373,7 @@ shared_examples 'a GitHub-ish import controller: POST create' do
end
end
- context 'user has chosen existent and non-existent nested namespaces and name for the project', :postgresql do
+ context 'user has chosen existent and non-existent nested namespaces and name for the project' do
let(:test_name) { 'test_name' }
let!(:parent_namespace) { create(:group, name: 'foo') }
diff --git a/spec/support/helpers/prometheus_helpers.rb b/spec/support/helpers/prometheus_helpers.rb
index 4d39d9df494..7c03746a395 100644
--- a/spec/support/helpers/prometheus_helpers.rb
+++ b/spec/support/helpers/prometheus_helpers.rb
@@ -76,6 +76,14 @@ module PrometheusHelpers
WebMock.stub_request(:any, /prometheus.example.com/)
end
+ def stub_any_prometheus_request_with_response(status: 200, headers: {}, body: nil)
+ stub_any_prometheus_request.to_return({
+ status: status,
+ headers: { 'Content-Type' => 'application/json' }.merge(headers),
+ body: body || prometheus_values_body.to_json
+ })
+ end
+
def stub_all_prometheus_requests(environment_slug, body: nil, status: 200)
stub_prometheus_request(
prometheus_query_with_time_url(prometheus_memory_query(environment_slug), Time.now.utc),
diff --git a/spec/support/shared_contexts/policies/group_policy_shared_context.rb b/spec/support/shared_contexts/policies/group_policy_shared_context.rb
index 74389c4d82b..c11725c63d2 100644
--- a/spec/support/shared_contexts/policies/group_policy_shared_context.rb
+++ b/spec/support/shared_contexts/policies/group_policy_shared_context.rb
@@ -31,7 +31,7 @@ RSpec.shared_context 'GroupPolicy context' do
:admin_group_member,
:change_visibility_level,
:set_note_created_at,
- (Gitlab::Database.postgresql? ? :create_subgroup : nil)
+ :create_subgroup
].compact
end
diff --git a/spec/support/shared_examples/models/chat_service_shared_examples.rb b/spec/support/shared_examples/models/chat_service_shared_examples.rb
index 71c0c57f302..b6a3d50d14a 100644
--- a/spec/support/shared_examples/models/chat_service_shared_examples.rb
+++ b/spec/support/shared_examples/models/chat_service_shared_examples.rb
@@ -222,7 +222,8 @@ shared_examples_for "chat service" do |service_name|
context "with not default branch" do
let(:pipeline) do
- create(:ci_pipeline, project: project, status: "failed", ref: "not-the-default-branch")
+ create(:ci_pipeline, :failed, project: project,
+ sha: project.commit.sha, ref: "not-the-default-branch")
end
context "when notify_only_default_branch enabled" do
diff --git a/spec/support/shared_examples/notify_shared_examples.rb b/spec/support/shared_examples/notify_shared_examples.rb
index a537fab4bcd..ca031df000e 100644
--- a/spec/support/shared_examples/notify_shared_examples.rb
+++ b/spec/support/shared_examples/notify_shared_examples.rb
@@ -52,7 +52,7 @@ shared_examples 'an email sent to a user' do
it 'is sent to user\'s group notification email' do
group_notification_email = 'user+group@example.com'
- create(:notification_setting, user: recipient, source: project.group, notification_email: group_notification_email)
+ create(:notification_setting, user: recipient, source: group, notification_email: group_notification_email)
expect(subject).to deliver_to(group_notification_email)
end
diff --git a/spec/support/shared_examples/project_latest_successful_build_for_examples.rb b/spec/support/shared_examples/project_latest_successful_build_for_examples.rb
new file mode 100644
index 00000000000..a9bd23e9fc9
--- /dev/null
+++ b/spec/support/shared_examples/project_latest_successful_build_for_examples.rb
@@ -0,0 +1,63 @@
+# frozen_string_literal: true
+
+shared_examples 'latest successful build for sha or ref' do
+ context 'with many builds' do
+ let(:other_pipeline) { create_pipeline(project) }
+ let(:other_build) { create_build(other_pipeline, 'test') }
+ let(:build_name) { other_build.name }
+
+ before do
+ pipeline1 = create_pipeline(project)
+ pipeline2 = create_pipeline(project)
+ create_build(pipeline1, 'test')
+ create_build(pipeline1, 'test2')
+ create_build(pipeline2, 'test2')
+ end
+
+ it 'gives the latest builds from latest pipeline' do
+ expect(subject).to eq(other_build)
+ end
+ end
+
+ context 'with succeeded pipeline' do
+ let!(:build) { create_build }
+ let(:build_name) { build.name }
+
+ context 'standalone pipeline' do
+ it 'returns builds for ref for default_branch' do
+ expect(subject).to eq(build)
+ end
+
+ context 'with nonexistent build' do
+ let(:build_name) { 'TAIL' }
+
+ it 'returns empty relation if the build cannot be found' do
+ expect(subject).to be_nil
+ end
+ end
+ end
+
+ context 'with some pending pipeline' do
+ before do
+ create_build(create_pipeline(project, 'pending'))
+ end
+
+ it 'gives the latest build from latest pipeline' do
+ expect(subject).to eq(build)
+ end
+ end
+ end
+
+ context 'with pending pipeline' do
+ let!(:pending_build) { create_build(pipeline) }
+ let(:build_name) { pending_build.name }
+
+ before do
+ pipeline.update(status: 'pending')
+ end
+
+ it 'returns empty relation' do
+ expect(subject).to be_nil
+ end
+ end
+end
diff --git a/spec/support/shared_examples/resource_label_events_api.rb b/spec/support/shared_examples/resource_label_events_api.rb
new file mode 100644
index 00000000000..945cb8d9f2c
--- /dev/null
+++ b/spec/support/shared_examples/resource_label_events_api.rb
@@ -0,0 +1,44 @@
+# frozen_string_literal: true
+
+shared_examples 'resource_label_events API' do |parent_type, eventable_type, id_name|
+ describe "GET /#{parent_type}/:id/#{eventable_type}/:noteable_id/resource_label_events" do
+ it "returns an array of resource label events" do
+ get api("/#{parent_type}/#{parent.id}/#{eventable_type}/#{eventable[id_name]}/resource_label_events", user)
+
+ expect(response).to have_gitlab_http_status(200)
+ expect(response).to include_pagination_headers
+ expect(json_response).to be_an Array
+ expect(json_response.first['id']).to eq(event.id)
+ end
+
+ it "returns a 404 error when eventable id not found" do
+ get api("/#{parent_type}/#{parent.id}/#{eventable_type}/12345/resource_label_events", user)
+
+ expect(response).to have_gitlab_http_status(404)
+ end
+
+ it "returns 404 when not authorized" do
+ parent.update!(visibility_level: Gitlab::VisibilityLevel::PRIVATE)
+ private_user = create(:user)
+
+ get api("/#{parent_type}/#{parent.id}/#{eventable_type}/#{eventable[id_name]}/resource_label_events", private_user)
+
+ expect(response).to have_gitlab_http_status(404)
+ end
+ end
+
+ describe "GET /#{parent_type}/:id/#{eventable_type}/:noteable_id/resource_label_events/:event_id" do
+ it "returns a resource label event by id" do
+ get api("/#{parent_type}/#{parent.id}/#{eventable_type}/#{eventable[id_name]}/resource_label_events/#{event.id}", user)
+
+ expect(response).to have_gitlab_http_status(200)
+ expect(json_response['id']).to eq(event.id)
+ end
+
+ it "returns a 404 error if resource label event not found" do
+ get api("/#{parent_type}/#{parent.id}/#{eventable_type}/#{eventable[id_name]}/resource_label_events/12345", user)
+
+ expect(response).to have_gitlab_http_status(404)
+ end
+ end
+end
diff --git a/spec/support/shared_examples/slack_mattermost_notifications_shared_examples.rb b/spec/support/shared_examples/slack_mattermost_notifications_shared_examples.rb
index 52fef1c13e1..8ce94064dc3 100644
--- a/spec/support/shared_examples/slack_mattermost_notifications_shared_examples.rb
+++ b/spec/support/shared_examples/slack_mattermost_notifications_shared_examples.rb
@@ -454,7 +454,7 @@ RSpec.shared_examples 'slack or mattermost notifications' do
context 'only notify for the default branch' do
context 'when enabled' do
let(:pipeline) do
- create(:ci_pipeline, :failed, project: project, ref: 'not-the-default-branch')
+ create(:ci_pipeline, :failed, project: project, sha: project.commit.sha, ref: 'not-the-default-branch')
end
before do
@@ -472,7 +472,7 @@ RSpec.shared_examples 'slack or mattermost notifications' do
context 'when disabled' do
let(:pipeline) do
- create(:ci_pipeline, :failed, project: project, ref: 'not-the-default-branch')
+ create(:ci_pipeline, :failed, project: project, sha: project.commit.sha, ref: 'not-the-default-branch')
end
before do
diff --git a/spec/views/groups/edit.html.haml_spec.rb b/spec/views/groups/edit.html.haml_spec.rb
index 29e15960fb8..47804411b9d 100644
--- a/spec/views/groups/edit.html.haml_spec.rb
+++ b/spec/views/groups/edit.html.haml_spec.rb
@@ -35,7 +35,7 @@ describe 'groups/edit.html.haml' do
it_behaves_like '"Share with group lock" setting', { disabled: false, checked: false }
end
- context 'for a subgroup', :nested_groups do
+ context 'for a subgroup' do
let!(:subgroup) { create(:group, parent: root_group) }
let(:sub_owner) { create(:user) }
let(:test_group) { subgroup }
diff --git a/spec/views/layouts/header/_new_dropdown.haml_spec.rb b/spec/views/layouts/header/_new_dropdown.haml_spec.rb
index 2e19d0cec26..26e429ac5d0 100644
--- a/spec/views/layouts/header/_new_dropdown.haml_spec.rb
+++ b/spec/views/layouts/header/_new_dropdown.haml_spec.rb
@@ -28,7 +28,7 @@ describe 'layouts/header/_new_dropdown' do
)
end
- it 'has a "New subgroup" link', :nested_groups do
+ it 'has a "New subgroup" link' do
render
expect(rendered).to have_link(
diff --git a/yarn.lock b/yarn.lock
index 4fa7665b000..7095ff706c2 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -996,10 +996,10 @@
resolved "https://registry.yarnpkg.com/@gitlab/svgs/-/svgs-1.67.0.tgz#c7b94eca13b99fd3aaa737fb6dcc0abc41d3c579"
integrity sha512-hJOmWEs6RkjzyKkb1vc9wwKGZIBIP0coHkxu/KgOoxhBVudpGk4CH7xJ6UuB2TKpb0SEh5CC1CzRZfBYaFhsaA==
-"@gitlab/ui@^5.7.1":
- version "5.7.1"
- resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-5.7.1.tgz#e55d04052dd6e50ed1e90676aacc64290d62c0b6"
- integrity sha512-F06/6z6/69LbKIK0PYRDTB/teSPUnF7LijHl4JiuYHXn7Y2/iVoLsAMikhT89RVR84orHPGnw16vtCPjSjBDrA==
+"@gitlab/ui@^5.9.0":
+ version "5.9.0"
+ resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-5.9.0.tgz#a38b1b57c365608b100b95969ae7a57ce1707542"
+ integrity sha512-cgvEPWVerYZNLqkHjg5dd0VhEDBWj8aNoISZCaGOWI9K4yVtpMPVRUv19o/xYm4vUexfFsG9vg9lBgd+4ZU6Yw==
dependencies:
"@babel/standalone" "^7.0.0"
"@gitlab/vue-toasted" "^1.2.1"
@@ -8340,7 +8340,7 @@ monaco-editor@^0.15.6:
resolved "https://registry.yarnpkg.com/monaco-editor/-/monaco-editor-0.15.6.tgz#d63b3b06f86f803464f003b252627c3eb4a09483"
integrity sha512-JoU9V9k6KqT9R9Tiw1RTU8ohZ+Xnf9DMg6Ktqqw5hILumwmq7xqa/KLXw513uTUsWbhtnHoSJYYR++u3pkyxJg==
-mousetrap@^1.4.6:
+mousetrap@1.4.6:
version "1.4.6"
resolved "https://registry.yarnpkg.com/mousetrap/-/mousetrap-1.4.6.tgz#eaca72e22e56d5b769b7555873b688c3332e390a"
integrity sha1-6spy4i5W1bdpt1VYc7aIwzMuOQo=