summaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
Diffstat (limited to 'spec')
-rw-r--r--spec/factories/ci/job_artifacts.rb4
-rw-r--r--spec/factories/deploy_tokens.rb3
-rw-r--r--spec/factories/sequences.rb2
-rw-r--r--spec/features/boards/boards_spec.rb14
-rw-r--r--spec/features/dashboard/projects_spec.rb26
-rw-r--r--spec/features/oauth_login_spec.rb12
-rw-r--r--spec/features/projects/new_project_spec.rb2
-rw-r--r--spec/features/projects/show/user_sees_last_commit_ci_status_spec.rb2
-rw-r--r--spec/features/projects/tree/create_directory_spec.rb13
-rw-r--r--spec/features/projects/tree/create_file_spec.rb7
-rw-r--r--spec/frontend/ide/stores/modules/commit/mutations_spec.js8
-rw-r--r--spec/frontend/monitoring/embed/embed_spec.js8
-rw-r--r--spec/frontend/tracking_spec.js27
-rw-r--r--spec/graphql/resolvers/echo_resolver_spec.rb24
-rw-r--r--spec/graphql/types/namespace_type_spec.rb2
-rw-r--r--spec/graphql/types/root_storage_statistics_type_spec.rb14
-rw-r--r--spec/helpers/ci_status_helper_spec.rb76
-rw-r--r--spec/javascripts/create_cluster/gke_cluster/components/gke_machine_type_dropdown_spec.js (renamed from spec/javascripts/projects/gke_cluster_dropdowns/components/gke_machine_type_dropdown_spec.js)6
-rw-r--r--spec/javascripts/create_cluster/gke_cluster/components/gke_project_id_dropdown_spec.js (renamed from spec/javascripts/projects/gke_cluster_dropdowns/components/gke_project_id_dropdown_spec.js)6
-rw-r--r--spec/javascripts/create_cluster/gke_cluster/components/gke_zone_dropdown_spec.js (renamed from spec/javascripts/projects/gke_cluster_dropdowns/components/gke_zone_dropdown_spec.js)6
-rw-r--r--spec/javascripts/create_cluster/gke_cluster/helpers.js (renamed from spec/javascripts/projects/gke_cluster_dropdowns/helpers.js)0
-rw-r--r--spec/javascripts/create_cluster/gke_cluster/mock_data.js (renamed from spec/javascripts/projects/gke_cluster_dropdowns/mock_data.js)0
-rw-r--r--spec/javascripts/create_cluster/gke_cluster/stores/actions_spec.js (renamed from spec/javascripts/projects/gke_cluster_dropdowns/stores/actions_spec.js)4
-rw-r--r--spec/javascripts/create_cluster/gke_cluster/stores/getters_spec.js (renamed from spec/javascripts/projects/gke_cluster_dropdowns/stores/getters_spec.js)2
-rw-r--r--spec/javascripts/create_cluster/gke_cluster/stores/mutations_spec.js (renamed from spec/javascripts/projects/gke_cluster_dropdowns/stores/mutations_spec.js)4
-rw-r--r--spec/javascripts/ide/components/commit_sidebar/actions_spec.js188
-rw-r--r--spec/javascripts/ide/components/commit_sidebar/new_merge_request_option_spec.js160
-rw-r--r--spec/javascripts/ide/mock_data.js34
-rw-r--r--spec/javascripts/ide/stores/getters_spec.js32
-rw-r--r--spec/javascripts/ide/stores/modules/commit/actions_spec.js177
-rw-r--r--spec/javascripts/ide/stores/modules/commit/getters_spec.js162
-rw-r--r--spec/javascripts/monitoring/charts/area_spec.js8
-rw-r--r--spec/javascripts/monitoring/panel_type_spec.js7
-rw-r--r--spec/javascripts/notes/stores/actions_spec.js45
-rw-r--r--spec/lib/api/helpers/label_helpers_spec.rb33
-rw-r--r--spec/lib/gitlab/analytics/cycle_analytics/stage_events/stage_event_spec.rb10
-rw-r--r--spec/lib/gitlab/auth/o_auth/user_spec.rb22
-rw-r--r--spec/lib/gitlab/auth_spec.rb4
-rw-r--r--spec/lib/gitlab/danger/teammate_spec.rb10
-rw-r--r--spec/lib/gitlab/database/migration_helpers_spec.rb114
-rw-r--r--spec/lib/gitlab/database_importers/self_monitoring/project/create_service_spec.rb (renamed from spec/services/self_monitoring/project/create_service_spec.rb)134
-rw-r--r--spec/lib/gitlab/database_spec.rb11
-rw-r--r--spec/lib/gitlab/fogbugz_import/project_creator_spec.rb29
-rw-r--r--spec/lib/gitlab/gitaly_client_spec.rb10
-rw-r--r--spec/lib/gitlab/graphql/authorize/authorize_field_service_spec.rb5
-rw-r--r--spec/lib/gitlab/graphql/loaders/batch_root_storage_statistics_loader_spec.rb18
-rw-r--r--spec/lib/gitlab/graphql/markdown_field_spec.rb7
-rw-r--r--spec/lib/gitlab/legacy_github_import/release_formatter_spec.rb2
-rw-r--r--spec/lib/gitlab/legacy_github_import/user_formatter_spec.rb2
-rw-r--r--spec/lib/gitlab/legacy_github_import/wiki_formatter_spec.rb2
-rw-r--r--spec/lib/gitlab/loop_helpers_spec.rb2
-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/markup_helper_spec.rb2
-rw-r--r--spec/lib/gitlab/metrics/background_transaction_spec.rb2
-rw-r--r--spec/lib/gitlab/metrics/delta_spec.rb2
-rw-r--r--spec/lib/gitlab/metrics/instrumentation_spec.rb2
-rw-r--r--spec/lib/gitlab/metrics/method_call_spec.rb2
-rw-r--r--spec/lib/gitlab/metrics/methods_spec.rb2
-rw-r--r--spec/lib/gitlab/metrics/metric_spec.rb2
-rw-r--r--spec/lib/gitlab/metrics/prometheus_spec.rb2
-rw-r--r--spec/lib/gitlab/metrics/rack_middleware_spec.rb2
-rw-r--r--spec/lib/gitlab/metrics/requests_rack_middleware_spec.rb2
-rw-r--r--spec/lib/gitlab/metrics/samplers/influx_sampler_spec.rb2
-rw-r--r--spec/lib/gitlab/metrics/samplers/ruby_sampler_spec.rb2
-rw-r--r--spec/lib/gitlab/metrics/samplers/unicorn_sampler_spec.rb2
-rw-r--r--spec/lib/gitlab/metrics/sidekiq_metrics_exporter_spec.rb2
-rw-r--r--spec/lib/gitlab/metrics/sidekiq_middleware_spec.rb2
-rw-r--r--spec/lib/gitlab/metrics/subscribers/action_view_spec.rb2
-rw-r--r--spec/lib/gitlab/metrics/subscribers/active_record_spec.rb2
-rw-r--r--spec/lib/gitlab/metrics/subscribers/rails_cache_spec.rb2
-rw-r--r--spec/lib/gitlab/metrics/system_spec.rb2
-rw-r--r--spec/lib/gitlab/metrics/web_transaction_spec.rb2
-rw-r--r--spec/lib/gitlab/metrics_spec.rb2
-rw-r--r--spec/lib/gitlab/middleware/basic_health_check_spec.rb2
-rw-r--r--spec/lib/gitlab/middleware/multipart_spec.rb2
-rw-r--r--spec/lib/gitlab/middleware/rails_queue_duration_spec.rb2
-rw-r--r--spec/lib/gitlab/middleware/read_only_spec.rb2
-rw-r--r--spec/lib/gitlab/middleware/release_env_spec.rb2
-rw-r--r--spec/lib/gitlab/multi_collection_paginator_spec.rb2
-rw-r--r--spec/lib/gitlab/object_hierarchy_spec.rb2
-rw-r--r--spec/lib/gitlab/octokit/middleware_spec.rb2
-rw-r--r--spec/lib/gitlab/omniauth_initializer_spec.rb2
-rw-r--r--spec/lib/gitlab/optimistic_locking_spec.rb2
-rw-r--r--spec/lib/gitlab/other_markup_spec.rb2
-rw-r--r--spec/lib/gitlab/otp_key_rotator_spec.rb2
-rw-r--r--spec/lib/gitlab/pages_client_spec.rb2
-rw-r--r--spec/lib/gitlab/path_regex_spec.rb2
-rw-r--r--spec/lib/gitlab/performance_bar_spec.rb2
-rw-r--r--spec/lib/gitlab/phabricator_import/importer_spec.rb2
-rw-r--r--spec/lib/gitlab/phabricator_import/user_finder_spec.rb2
-rw-r--r--spec/lib/gitlab/phabricator_import/worker_state_spec.rb2
-rw-r--r--spec/lib/gitlab/plugin_spec.rb2
-rw-r--r--spec/lib/gitlab/polling_interval_spec.rb2
-rw-r--r--spec/lib/gitlab/popen/runner_spec.rb2
-rw-r--r--spec/lib/gitlab/popen_spec.rb2
-rw-r--r--spec/lib/gitlab/profiler_spec.rb2
-rw-r--r--spec/lib/gitlab/project_authorizations_spec.rb2
-rw-r--r--spec/lib/gitlab/project_search_results_spec.rb2
-rw-r--r--spec/lib/gitlab/project_template_spec.rb2
-rw-r--r--spec/lib/gitlab/project_transfer_spec.rb2
-rw-r--r--spec/lib/gitlab/prometheus/additional_metrics_parser_spec.rb2
-rw-r--r--spec/lib/gitlab/prometheus/queries/additional_metrics_deployment_query_spec.rb2
-rw-r--r--spec/lib/gitlab/prometheus/queries/additional_metrics_environment_query_spec.rb2
-rw-r--r--spec/lib/gitlab/prometheus/queries/deployment_query_spec.rb2
-rw-r--r--spec/lib/gitlab/prometheus/queries/matched_metric_query_spec.rb2
-rw-r--r--spec/lib/gitlab/prometheus_client_spec.rb2
-rw-r--r--spec/lib/gitlab/query_limiting/active_support_subscriber_spec.rb2
-rw-r--r--spec/lib/gitlab/query_limiting/middleware_spec.rb2
-rw-r--r--spec/lib/gitlab/query_limiting/transaction_spec.rb2
-rw-r--r--spec/lib/gitlab/query_limiting_spec.rb2
-rw-r--r--spec/lib/gitlab/quick_actions/command_definition_spec.rb2
-rw-r--r--spec/lib/gitlab/quick_actions/dsl_spec.rb2
-rw-r--r--spec/lib/gitlab/quick_actions/extractor_spec.rb2
-rw-r--r--spec/lib/gitlab/quick_actions/spend_time_and_date_separator_spec.rb2
-rw-r--r--spec/lib/gitlab/quick_actions/substitution_definition_spec.rb2
-rw-r--r--spec/lib/gitlab/redis/cache_spec.rb2
-rw-r--r--spec/lib/gitlab/redis/queues_spec.rb2
-rw-r--r--spec/lib/gitlab/redis/shared_state_spec.rb2
-rw-r--r--spec/lib/gitlab/redis/wrapper_spec.rb2
-rw-r--r--spec/lib/gitlab/reference_counter_spec.rb2
-rw-r--r--spec/lib/gitlab/regex_spec.rb2
-rw-r--r--spec/lib/gitlab/repo_path_spec.rb2
-rw-r--r--spec/lib/gitlab/repository_cache_adapter_spec.rb2
-rw-r--r--spec/lib/gitlab/repository_cache_spec.rb2
-rw-r--r--spec/lib/gitlab/repository_set_cache_spec.rb2
-rw-r--r--spec/lib/gitlab/request_context_spec.rb2
-rw-r--r--spec/lib/gitlab/request_forgery_protection_spec.rb2
-rw-r--r--spec/lib/gitlab/request_profiler/profile_spec.rb2
-rw-r--r--spec/lib/gitlab/request_profiler_spec.rb2
-rw-r--r--spec/lib/gitlab/route_map_spec.rb2
-rw-r--r--spec/lib/gitlab/routing_spec.rb2
-rw-r--r--spec/lib/gitlab/sanitizers/exif_spec.rb2
-rw-r--r--spec/lib/gitlab/sanitizers/svg_spec.rb2
-rw-r--r--spec/lib/gitlab/search/found_blob_spec.rb3
-rw-r--r--spec/lib/gitlab/search/query_spec.rb2
-rw-r--r--spec/lib/gitlab/search_results_spec.rb2
-rw-r--r--spec/lib/gitlab/sentry_spec.rb2
-rw-r--r--spec/lib/gitlab/serializer/ci/variables_spec.rb2
-rw-r--r--spec/lib/gitlab/serializer/pagination_spec.rb2
-rw-r--r--spec/lib/gitlab/shard_health_cache_spec.rb2
-rw-r--r--spec/lib/gitlab/shell_spec.rb2
-rw-r--r--spec/lib/gitlab/sherlock/collection_spec.rb2
-rw-r--r--spec/lib/gitlab/sherlock/file_sample_spec.rb2
-rw-r--r--spec/lib/gitlab/sherlock/line_profiler_spec.rb2
-rw-r--r--spec/lib/gitlab/sherlock/line_sample_spec.rb2
-rw-r--r--spec/lib/gitlab/sherlock/location_spec.rb2
-rw-r--r--spec/lib/gitlab/sherlock/middleware_spec.rb2
-rw-r--r--spec/lib/gitlab/sherlock/query_spec.rb2
-rw-r--r--spec/lib/gitlab/sherlock/transaction_spec.rb2
-rw-r--r--spec/lib/gitlab/sidekiq_config_spec.rb2
-rw-r--r--spec/lib/gitlab/sidekiq_logging/json_formatter_spec.rb2
-rw-r--r--spec/lib/gitlab/sidekiq_logging/structured_logger_spec.rb2
-rw-r--r--spec/lib/gitlab/sidekiq_middleware/memory_killer_spec.rb2
-rw-r--r--spec/lib/gitlab/sidekiq_signals_spec.rb2
-rw-r--r--spec/lib/gitlab/sidekiq_status/client_middleware_spec.rb2
-rw-r--r--spec/lib/gitlab/sidekiq_status/server_middleware_spec.rb2
-rw-r--r--spec/lib/gitlab/sidekiq_status_spec.rb2
-rw-r--r--spec/lib/gitlab/sidekiq_versioning/manager_spec.rb2
-rw-r--r--spec/lib/gitlab/sidekiq_versioning_spec.rb2
-rw-r--r--spec/lib/gitlab/slash_commands/command_spec.rb2
-rw-r--r--spec/lib/gitlab/slash_commands/deploy_spec.rb2
-rw-r--r--spec/lib/gitlab/slash_commands/issue_move_spec.rb2
-rw-r--r--spec/lib/gitlab/slash_commands/issue_new_spec.rb2
-rw-r--r--spec/lib/gitlab/slash_commands/issue_search_spec.rb2
-rw-r--r--spec/lib/gitlab/slash_commands/issue_show_spec.rb2
-rw-r--r--spec/lib/gitlab/slash_commands/presenters/access_spec.rb2
-rw-r--r--spec/lib/gitlab/slash_commands/presenters/deploy_spec.rb2
-rw-r--r--spec/lib/gitlab/slash_commands/presenters/issue_move_spec.rb2
-rw-r--r--spec/lib/gitlab/slash_commands/presenters/issue_new_spec.rb2
-rw-r--r--spec/lib/gitlab/slash_commands/presenters/issue_search_spec.rb2
-rw-r--r--spec/lib/gitlab/slash_commands/presenters/issue_show_spec.rb2
-rw-r--r--spec/lib/gitlab/snippet_search_results_spec.rb2
-rw-r--r--spec/lib/gitlab/sql/cte_spec.rb2
-rw-r--r--spec/lib/gitlab/sql/glob_spec.rb2
-rw-r--r--spec/lib/gitlab/sql/pattern_spec.rb2
-rw-r--r--spec/lib/gitlab/sql/recursive_cte_spec.rb2
-rw-r--r--spec/lib/gitlab/sql/union_spec.rb2
-rw-r--r--spec/lib/gitlab/ssh_public_key_spec.rb2
-rw-r--r--spec/lib/gitlab/string_placeholder_replacer_spec.rb2
-rw-r--r--spec/lib/gitlab/string_range_marker_spec.rb2
-rw-r--r--spec/lib/gitlab/string_regex_marker_spec.rb2
-rw-r--r--spec/lib/gitlab/tcp_checker_spec.rb2
-rw-r--r--spec/lib/gitlab/template/finders/global_template_finder_spec.rb2
-rw-r--r--spec/lib/gitlab/template/finders/repo_template_finders_spec.rb2
-rw-r--r--spec/lib/gitlab/template/gitignore_template_spec.rb2
-rw-r--r--spec/lib/gitlab/template/gitlab_ci_yml_template_spec.rb2
-rw-r--r--spec/lib/gitlab/template/issue_template_spec.rb2
-rw-r--r--spec/lib/gitlab/template/merge_request_template_spec.rb2
-rw-r--r--spec/lib/gitlab/themes_spec.rb2
-rw-r--r--spec/lib/gitlab/tree_summary_spec.rb2
-rw-r--r--spec/lib/gitlab/untrusted_regexp/ruby_syntax_spec.rb2
-rw-r--r--spec/lib/gitlab/untrusted_regexp_spec.rb2
-rw-r--r--spec/lib/gitlab/uploads_transfer_spec.rb2
-rw-r--r--spec/lib/gitlab/url_blocker_spec.rb2
-rw-r--r--spec/lib/gitlab/url_builder_spec.rb2
-rw-r--r--spec/lib/gitlab/url_sanitizer_spec.rb2
-rw-r--r--spec/lib/gitlab/usage_data_counters/merge_request_counter_spec.rb9
-rw-r--r--spec/lib/gitlab/usage_data_spec.rb1
-rw-r--r--spec/lib/gitlab/user_access_spec.rb2
-rw-r--r--spec/lib/gitlab/utils/deep_size_spec.rb2
-rw-r--r--spec/lib/gitlab/utils/merge_hash_spec.rb2
-rw-r--r--spec/lib/gitlab/utils/override_spec.rb2
-rw-r--r--spec/lib/gitlab/utils/sanitize_node_link_spec.rb2
-rw-r--r--spec/lib/gitlab/utils/strong_memoize_spec.rb2
-rw-r--r--spec/lib/gitlab/utils_spec.rb2
-rw-r--r--spec/lib/gitlab/verify/job_artifacts_spec.rb2
-rw-r--r--spec/lib/gitlab/verify/lfs_objects_spec.rb2
-rw-r--r--spec/lib/gitlab/verify/uploads_spec.rb2
-rw-r--r--spec/lib/gitlab/version_info_spec.rb2
-rw-r--r--spec/lib/gitlab/view/presenter/base_spec.rb2
-rw-r--r--spec/lib/gitlab/view/presenter/delegated_spec.rb2
-rw-r--r--spec/lib/gitlab/view/presenter/factory_spec.rb2
-rw-r--r--spec/lib/gitlab/view/presenter/simple_spec.rb2
-rw-r--r--spec/lib/gitlab/visibility_level_spec.rb2
-rw-r--r--spec/lib/gitlab/wiki_file_finder_spec.rb2
-rw-r--r--spec/lib/gitlab/workhorse_spec.rb2
-rw-r--r--spec/lib/gitlab_spec.rb29
-rw-r--r--spec/lib/google_api/auth_spec.rb2
-rw-r--r--spec/lib/google_api/cloud_platform/client_spec.rb2
-rw-r--r--spec/lib/json_web_token/rsa_token_spec.rb2
-rw-r--r--spec/lib/json_web_token/token_spec.rb2
-rw-r--r--spec/lib/mattermost/client_spec.rb2
-rw-r--r--spec/lib/mattermost/command_spec.rb2
-rw-r--r--spec/lib/mattermost/session_spec.rb2
-rw-r--r--spec/lib/mattermost/team_spec.rb2
-rw-r--r--spec/lib/microsoft_teams/activity_spec.rb2
-rw-r--r--spec/lib/microsoft_teams/notifier_spec.rb2
-rw-r--r--spec/lib/milestone_array_spec.rb2
-rw-r--r--spec/lib/object_storage/direct_upload_spec.rb2
-rw-r--r--spec/lib/omni_auth/strategies/jwt_spec.rb2
-rw-r--r--spec/lib/rspec_flaky/config_spec.rb2
-rw-r--r--spec/lib/rspec_flaky/example_spec.rb2
-rw-r--r--spec/lib/rspec_flaky/flaky_example_spec.rb2
-rw-r--r--spec/lib/rspec_flaky/flaky_examples_collection_spec.rb2
-rw-r--r--spec/lib/rspec_flaky/listener_spec.rb2
-rw-r--r--spec/lib/rspec_flaky/report_spec.rb2
-rw-r--r--spec/lib/safe_zip/entry_spec.rb2
-rw-r--r--spec/lib/safe_zip/extract_params_spec.rb2
-rw-r--r--spec/lib/safe_zip/extract_spec.rb2
-rw-r--r--spec/lib/serializers/json_spec.rb2
-rw-r--r--spec/lib/system_check/app/git_user_default_ssh_config_check_spec.rb2
-rw-r--r--spec/lib/system_check/base_check_spec.rb2
-rw-r--r--spec/lib/system_check/orphans/namespace_check_spec.rb2
-rw-r--r--spec/lib/system_check/orphans/repository_check_spec.rb2
-rw-r--r--spec/lib/system_check/simple_executor_spec.rb2
-rw-r--r--spec/lib/system_check_spec.rb2
-rw-r--r--spec/lib/uploaded_file_spec.rb2
-rw-r--r--spec/migrations/add_gitlab_instance_administration_project_spec.rb252
-rw-r--r--spec/migrations/encrypt_deploy_tokens_tokens_spec.rb47
-rw-r--r--spec/models/analytics/cycle_analytics/project_stage_spec.rb14
-rw-r--r--spec/models/ci/pipeline_spec.rb5
-rw-r--r--spec/models/ci/runner_spec.rb7
-rw-r--r--spec/models/deployment_spec.rb26
-rw-r--r--spec/models/namespace/root_storage_statistics_spec.rb13
-rw-r--r--spec/models/project_spec.rb31
-rw-r--r--spec/models/user_spec.rb20
-rw-r--r--spec/policies/namespace/root_storage_statistics_policy_spec.rb80
-rw-r--r--spec/policies/namespace_policy_spec.rb2
-rw-r--r--spec/policies/project_policy_spec.rb13
-rw-r--r--spec/requests/api/discussions_spec.rb54
-rw-r--r--spec/requests/api/graphql/multiplexed_queries_spec.rb8
-rw-r--r--spec/requests/api/graphql/namespace/root_storage_statistics_spec.rb55
-rw-r--r--spec/requests/api/graphql/project/project_statistics_spec.rb2
-rw-r--r--spec/requests/api/issues/get_project_issues_spec.rb8
-rw-r--r--spec/requests/api/issues/issues_spec.rb16
-rw-r--r--spec/requests/api/labels_spec.rb363
-rw-r--r--spec/requests/api/notes_spec.rb7
-rw-r--r--spec/requests/api/pipelines_spec.rb11
-rw-r--r--spec/requests/jwt_controller_spec.rb8
-rw-r--r--spec/rubocop/cop/gitlab/union_spec.rb6
-rw-r--r--spec/rubocop/cop/migration/add_limit_to_string_columns_spec.rb268
-rw-r--r--spec/rubocop/cop/rspec/env_assignment_spec.rb26
-rw-r--r--spec/rubocop/cop/rspec/factories_in_migration_specs_spec.rb22
-rw-r--r--spec/services/application_settings/update_service_spec.rb18
-rw-r--r--spec/services/ci/update_build_queue_service_spec.rb110
-rw-r--r--spec/services/merge_requests/create_service_spec.rb8
-rw-r--r--spec/services/projects/forks_count_service_spec.rb14
-rw-r--r--spec/services/projects/open_issues_count_service_spec.rb13
-rw-r--r--spec/services/projects/open_merge_requests_count_service_spec.rb11
-rw-r--r--spec/services/users/keys_count_service_spec.rb44
-rw-r--r--spec/services/web_hook_service_spec.rb33
-rw-r--r--spec/support/capybara.rb3
-rw-r--r--spec/support/helpers/drag_to_helper.rb19
-rw-r--r--spec/support/helpers/stub_configuration.rb4
-rw-r--r--spec/support/shared_contexts/policies/group_policy_shared_context.rb3
-rw-r--r--spec/support/shared_examples/cycle_analytics_stage_examples.rb74
-rw-r--r--spec/support/shared_examples/quick_actions/issue/move_quick_action_shared_examples.rb49
-rw-r--r--spec/support/shared_examples/requests/api/discussions.rb54
-rw-r--r--spec/support/shared_examples/requests/api/pipelines/visibility_table_examples.rb235
-rw-r--r--spec/support/shared_examples/services/count_service_shared_examples.rb54
-rw-r--r--spec/views/layouts/_head.html.haml_spec.rb20
292 files changed, 3412 insertions, 646 deletions
diff --git a/spec/factories/ci/job_artifacts.rb b/spec/factories/ci/job_artifacts.rb
index 2d68a8e9fe3..6f553cadfa3 100644
--- a/spec/factories/ci/job_artifacts.rb
+++ b/spec/factories/ci/job_artifacts.rb
@@ -8,6 +8,10 @@ FactoryBot.define do
file_type :archive
file_format :zip
+ trait :expired do
+ expire_at { Date.yesterday }
+ end
+
trait :remote_store do
file_store JobArtifactUploader::Store::REMOTE
end
diff --git a/spec/factories/deploy_tokens.rb b/spec/factories/deploy_tokens.rb
index a96258f5cbe..99486acc2ab 100644
--- a/spec/factories/deploy_tokens.rb
+++ b/spec/factories/deploy_tokens.rb
@@ -2,7 +2,8 @@
FactoryBot.define do
factory :deploy_token do
- token { SecureRandom.hex(50) }
+ token nil
+ token_encrypted { Gitlab::CryptoHelper.aes256_gcm_encrypt( SecureRandom.hex(50) ) }
sequence(:name) { |n| "PDT #{n}" }
read_repository true
read_registry true
diff --git a/spec/factories/sequences.rb b/spec/factories/sequences.rb
index b6f2d6d8389..17b54d69372 100644
--- a/spec/factories/sequences.rb
+++ b/spec/factories/sequences.rb
@@ -7,7 +7,7 @@ FactoryBot.define do
sequence(:email_alias) { |n| "user.alias#{n}@example.org" }
sequence(:title) { |n| "My title #{n}" }
sequence(:filename) { |n| "filename-#{n}.rb" }
- sequence(:url) { |n| "http://example#{n}.org" }
+ sequence(:url) { |n| "http://example#{n}.test" }
sequence(:label_title) { |n| "label#{n}" }
sequence(:branch) { |n| "my-branch-#{n}" }
sequence(:past_time) { |n| 4.hours.ago + (2 * n).seconds }
diff --git a/spec/features/boards/boards_spec.rb b/spec/features/boards/boards_spec.rb
index 4e7b25115d7..902ecdcd3e8 100644
--- a/spec/features/boards/boards_spec.rb
+++ b/spec/features/boards/boards_spec.rb
@@ -236,6 +236,15 @@ describe 'Issue Boards', :js do
expect(find('.board:nth-child(2)')).to have_content(planning.title)
end
+ it 'dragging does not duplicate list' do
+ selector = '.board:not(.is-ghost) .board-header'
+ expect(page).to have_selector(selector, text: development.title, count: 1)
+
+ drag(list_from_index: 2, list_to_index: 1, selector: '.board-header', perform_drop: false)
+
+ expect(page).to have_selector(selector, text: development.title, count: 1)
+ end
+
it 'issue moves between lists' do
drag(list_from_index: 1, from_index: 1, list_to_index: 2)
@@ -576,7 +585,7 @@ describe 'Issue Boards', :js do
end
end
- def drag(selector: '.board-list', list_from_index: 0, from_index: 0, to_index: 0, list_to_index: 0)
+ def drag(selector: '.board-list', list_from_index: 0, from_index: 0, to_index: 0, list_to_index: 0, perform_drop: true)
# ensure there is enough horizontal space for four boards
resize_window(2000, 800)
@@ -585,7 +594,8 @@ describe 'Issue Boards', :js do
list_from_index: list_from_index,
from_index: from_index,
to_index: to_index,
- list_to_index: list_to_index)
+ list_to_index: list_to_index,
+ perform_drop: perform_drop)
end
def wait_for_board_cards(board_number, expected_cards)
diff --git a/spec/features/dashboard/projects_spec.rb b/spec/features/dashboard/projects_spec.rb
index e2100c8562b..973d5a2dcfc 100644
--- a/spec/features/dashboard/projects_spec.rb
+++ b/spec/features/dashboard/projects_spec.rb
@@ -169,7 +169,7 @@ describe 'Dashboard Projects' do
expect(page).to have_xpath("//a[@href='#{pipelines_project_commit_path(project, project.commit, ref: pipeline.ref)}']")
expect(page).to have_css('.ci-status-link')
expect(page).to have_css('.ci-status-icon-success')
- expect(page).to have_link('Commit: passed')
+ expect(page).to have_link('Pipeline: passed')
end
end
@@ -189,7 +189,7 @@ describe 'Dashboard Projects' do
expect(page).not_to have_xpath("//a[@href='#{pipelines_project_commit_path(project, project.commit, ref: pipeline.ref)}']")
expect(page).not_to have_css('.ci-status-link')
expect(page).not_to have_css('.ci-status-icon-success')
- expect(page).not_to have_link('Commit: passed')
+ expect(page).not_to have_link('Pipeline: passed')
end
end
end
@@ -220,4 +220,26 @@ describe 'Dashboard Projects' do
expect(find('input#merge_request_target_branch', visible: false).value).to eq 'master'
end
end
+
+ it 'avoids an N+1 query in dashboard index' do
+ create(:ci_pipeline, :with_job, status: :success, project: project, ref: project.default_branch, sha: project.commit.sha)
+ visit dashboard_projects_path
+
+ control_count = ActiveRecord::QueryRecorder.new { visit dashboard_projects_path }.count
+
+ new_project = create(:project, :repository, name: 'new project')
+ create(:ci_pipeline, :with_job, status: :success, project: new_project, ref: new_project.commit.sha)
+ new_project.add_developer(user)
+
+ ActiveRecord::QueryRecorder.new { visit dashboard_projects_path }.count
+
+ # There are three known N+1 queries:
+ # 1. Project#open_issues_count
+ # 2. Project#open_merge_requests_count
+ # 3. Project#forks_count
+ #
+ # In addition, ProjectsHelper#load_pipeline_status also adds an
+ # additional query.
+ expect { visit dashboard_projects_path }.not_to exceed_query_limit(control_count + 4)
+ end
end
diff --git a/spec/features/oauth_login_spec.rb b/spec/features/oauth_login_spec.rb
index a47eaa9bda7..c6e69fa3fb0 100644
--- a/spec/features/oauth_login_spec.rb
+++ b/spec/features/oauth_login_spec.rb
@@ -55,6 +55,18 @@ describe 'OAuth Login', :js, :allow_forgery_protection do
expect(current_path).to eq root_path
end
+
+ it 'when bypass-two-factor is enabled' do
+ allow(Gitlab.config.omniauth).to receive_messages(allow_bypass_two_factor: true)
+ login_via(provider.to_s, user, uid, remember_me: false)
+ expect(current_path).to eq root_path
+ end
+
+ it 'when bypass-two-factor is disabled' do
+ allow(Gitlab.config.omniauth).to receive_messages(allow_bypass_two_factor: false)
+ login_with_provider(provider, enter_two_factor: true)
+ expect(current_path).to eq root_path
+ end
end
context 'when "remember me" is checked' do
diff --git a/spec/features/projects/new_project_spec.rb b/spec/features/projects/new_project_spec.rb
index 010a5de6930..22a0d268243 100644
--- a/spec/features/projects/new_project_spec.rb
+++ b/spec/features/projects/new_project_spec.rb
@@ -280,7 +280,7 @@ describe 'New project' do
end
it 'shows import instructions' do
- expect(page).to have_content('Import repositories from GitHub')
+ expect(page).to have_content('Authenticate with GitHub')
expect(current_path).to eq new_import_github_path
end
end
diff --git a/spec/features/projects/show/user_sees_last_commit_ci_status_spec.rb b/spec/features/projects/show/user_sees_last_commit_ci_status_spec.rb
index a1cad261875..fdc238d55cf 100644
--- a/spec/features/projects/show/user_sees_last_commit_ci_status_spec.rb
+++ b/spec/features/projects/show/user_sees_last_commit_ci_status_spec.rb
@@ -18,7 +18,7 @@ describe 'Projects > Show > User sees last commit CI status' do
page.within '.blob-commit-info' do
expect(page).to have_content(project.commit.sha[0..6])
- expect(page).to have_link('Commit: skipped')
+ expect(page).to have_link('Pipeline: skipped')
end
end
end
diff --git a/spec/features/projects/tree/create_directory_spec.rb b/spec/features/projects/tree/create_directory_spec.rb
index 7ac5da86702..99285011405 100644
--- a/spec/features/projects/tree/create_directory_spec.rb
+++ b/spec/features/projects/tree/create_directory_spec.rb
@@ -32,10 +32,12 @@ describe 'Multi-file editor new directory', :js do
click_button('Create directory')
end
+ expect(page).to have_content('folder name')
+
first('.ide-tree-actions button').click
- page.within('.modal-dialog') do
- find('.form-control').set('file name')
+ page.within('.modal') do
+ find('.form-control').set('folder name/file name')
click_button('Create file')
end
@@ -44,13 +46,18 @@ describe 'Multi-file editor new directory', :js do
find('.js-ide-commit-mode').click
- find('.multi-file-commit-list-item').hover
click_button 'Stage'
fill_in('commit-message', with: 'commit message ide')
+ find(:css, ".js-ide-commit-new-mr input").set(false)
+
+ wait_for_requests
+
page.within '.multi-file-commit-form' do
click_button('Commit')
+
+ wait_for_requests
end
find('.js-ide-edit-mode').click
diff --git a/spec/features/projects/tree/create_file_spec.rb b/spec/features/projects/tree/create_file_spec.rb
index 00eefe9db42..780575a5975 100644
--- a/spec/features/projects/tree/create_file_spec.rb
+++ b/spec/features/projects/tree/create_file_spec.rb
@@ -36,15 +36,20 @@ describe 'Multi-file editor new file', :js do
find('.js-ide-commit-mode').click
- find('.multi-file-commit-list-item').hover
click_button 'Stage'
fill_in('commit-message', with: 'commit message ide')
+ find(:css, ".js-ide-commit-new-mr input").set(false)
+
page.within '.multi-file-commit-form' do
click_button('Commit')
+
+ wait_for_requests
end
+ find('.js-ide-edit-mode').click
+
expect(page).to have_content('file name')
end
end
diff --git a/spec/frontend/ide/stores/modules/commit/mutations_spec.js b/spec/frontend/ide/stores/modules/commit/mutations_spec.js
index 246500a2f34..45ac1a86ab3 100644
--- a/spec/frontend/ide/stores/modules/commit/mutations_spec.js
+++ b/spec/frontend/ide/stores/modules/commit/mutations_spec.js
@@ -62,12 +62,4 @@ describe('IDE commit module mutations', () => {
expect(state.shouldCreateMR).toBe(false);
});
});
-
- describe('INTERACT_WITH_NEW_MR', () => {
- it('sets interactedWithNewMR to true', () => {
- mutations.INTERACT_WITH_NEW_MR(state);
-
- expect(state.interactedWithNewMR).toBe(true);
- });
- });
});
diff --git a/spec/frontend/monitoring/embed/embed_spec.js b/spec/frontend/monitoring/embed/embed_spec.js
index 3b18a0f77c7..1ce14e2418a 100644
--- a/spec/frontend/monitoring/embed/embed_spec.js
+++ b/spec/frontend/monitoring/embed/embed_spec.js
@@ -1,7 +1,7 @@
import { createLocalVue, shallowMount } from '@vue/test-utils';
import Vuex from 'vuex';
import Embed from '~/monitoring/components/embed.vue';
-import MonitorAreaChart from '~/monitoring/components/charts/area.vue';
+import MonitorTimeSeriesChart from '~/monitoring/components/charts/time_series.vue';
import { TEST_HOST } from 'helpers/test_constants';
import { groups, initialState, metricsData, metricsWithData } from './mock_data';
@@ -55,7 +55,7 @@ describe('Embed', () => {
it('shows an empty state when no metrics are present', () => {
expect(wrapper.find('.metrics-embed').exists()).toBe(true);
- expect(wrapper.find(MonitorAreaChart).exists()).toBe(false);
+ expect(wrapper.find(MonitorTimeSeriesChart).exists()).toBe(false);
});
});
@@ -71,8 +71,8 @@ describe('Embed', () => {
it('shows a chart when metrics are present', () => {
wrapper.setProps({});
expect(wrapper.find('.metrics-embed').exists()).toBe(true);
- expect(wrapper.find(MonitorAreaChart).exists()).toBe(true);
- expect(wrapper.findAll(MonitorAreaChart).length).toBe(2);
+ expect(wrapper.find(MonitorTimeSeriesChart).exists()).toBe(true);
+ expect(wrapper.findAll(MonitorTimeSeriesChart).length).toBe(2);
});
});
});
diff --git a/spec/frontend/tracking_spec.js b/spec/frontend/tracking_spec.js
index cd0bf50f8e9..0e862c683d3 100644
--- a/spec/frontend/tracking_spec.js
+++ b/spec/frontend/tracking_spec.js
@@ -15,6 +15,12 @@ describe('Tracking', () => {
snowplowSpy = jest.spyOn(window, 'snowplow');
});
+ afterEach(() => {
+ window.doNotTrack = undefined;
+ navigator.doNotTrack = undefined;
+ navigator.msDoNotTrack = undefined;
+ });
+
it('tracks to snowplow (our current tracking system)', () => {
Tracking.event('_category_', '_eventName_', { label: '_label_' });
@@ -31,6 +37,27 @@ describe('Tracking', () => {
expect(snowplowSpy).not.toHaveBeenCalled();
});
+
+ it('skips tracking if the user does not want to be tracked (general spec)', () => {
+ window.doNotTrack = '1';
+ Tracking.event('_category_', '_eventName_');
+
+ expect(snowplowSpy).not.toHaveBeenCalled();
+ });
+
+ it('skips tracking if the user does not want to be tracked (firefox legacy)', () => {
+ navigator.doNotTrack = 'yes';
+ Tracking.event('_category_', '_eventName_');
+
+ expect(snowplowSpy).not.toHaveBeenCalled();
+ });
+
+ it('skips tracking if the user does not want to be tracked (IE legacy)', () => {
+ navigator.msDoNotTrack = '1';
+ Tracking.event('_category_', '_eventName_');
+
+ expect(snowplowSpy).not.toHaveBeenCalled();
+ });
});
describe('tracking interface events', () => {
diff --git a/spec/graphql/resolvers/echo_resolver_spec.rb b/spec/graphql/resolvers/echo_resolver_spec.rb
new file mode 100644
index 00000000000..466501a4227
--- /dev/null
+++ b/spec/graphql/resolvers/echo_resolver_spec.rb
@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Resolvers::EchoResolver do
+ include GraphqlHelpers
+
+ let(:current_user) { create(:user) }
+ let(:text) { 'Message test' }
+
+ describe '#resolve' do
+ it 'echoes text and username' do
+ expect(resolve_echo(text)).to eq %Q("#{current_user.username}" says: #{text})
+ end
+
+ it 'echoes text and nil as username' do
+ expect(resolve_echo(text, { current_user: nil })).to eq "nil says: #{text}"
+ end
+ end
+
+ def resolve_echo(text, context = { current_user: current_user })
+ resolve(described_class, obj: nil, args: { text: text }, ctx: context)
+ end
+end
diff --git a/spec/graphql/types/namespace_type_spec.rb b/spec/graphql/types/namespace_type_spec.rb
index e1153832cc9..f476dd7286f 100644
--- a/spec/graphql/types/namespace_type_spec.rb
+++ b/spec/graphql/types/namespace_type_spec.rb
@@ -8,7 +8,7 @@ describe GitlabSchema.types['Namespace'] do
it 'has the expected fields' do
expected_fields = %w[
id name path full_name full_path description description_html visibility
- lfs_enabled request_access_enabled projects
+ lfs_enabled request_access_enabled projects root_storage_statistics
]
is_expected.to have_graphql_fields(*expected_fields)
diff --git a/spec/graphql/types/root_storage_statistics_type_spec.rb b/spec/graphql/types/root_storage_statistics_type_spec.rb
new file mode 100644
index 00000000000..8c69c13aa73
--- /dev/null
+++ b/spec/graphql/types/root_storage_statistics_type_spec.rb
@@ -0,0 +1,14 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe GitlabSchema.types['RootStorageStatistics'] do
+ it { expect(described_class.graphql_name).to eq('RootStorageStatistics') }
+
+ it 'has all the required fields' do
+ is_expected.to have_graphql_fields(:storage_size, :repository_size, :lfs_objects_size,
+ :build_artifacts_size, :packages_size, :wiki_size)
+ end
+
+ it { is_expected.to require_graphql_authorizations(:read_statistics) }
+end
diff --git a/spec/helpers/ci_status_helper_spec.rb b/spec/helpers/ci_status_helper_spec.rb
index bc2422aba90..4f665dc0514 100644
--- a/spec/helpers/ci_status_helper_spec.rb
+++ b/spec/helpers/ci_status_helper_spec.rb
@@ -53,4 +53,80 @@ describe CiStatusHelper do
expect(helper.pipeline_status_cache_key(pipeline_status)).to eq("pipeline-status/123abc-success")
end
end
+
+ describe "#render_status_with_link" do
+ subject { helper.render_status_with_link("success") }
+
+ it "renders a passed status icon" do
+ is_expected.to include("<span class=\"ci-status-link ci-status-icon-success d-inline-flex")
+ end
+
+ it "has 'Pipeline' as the status type in the title" do
+ is_expected.to include("title=\"Pipeline: passed\"")
+ end
+
+ it "has the success status icon" do
+ is_expected.to include("ci-status-icon-success")
+ end
+
+ context "when pipeline has commit path" do
+ subject { helper.render_status_with_link("success", "/commit-path") }
+
+ it "links to commit" do
+ is_expected.to include("href=\"/commit-path\"")
+ end
+
+ it "does not contain a span element" do
+ is_expected.not_to include("<span")
+ end
+
+ it "has 'Pipeline' as the status type in the title" do
+ is_expected.to include("title=\"Pipeline: passed\"")
+ end
+
+ it "has the correct status icon" do
+ is_expected.to include("ci-status-icon-success")
+ end
+ end
+
+ context "when different type than pipeline is provided" do
+ subject { helper.render_status_with_link("success", type: "commit") }
+
+ it "has the provided type in the title" do
+ is_expected.to include("title=\"Commit: passed\"")
+ end
+ end
+
+ context "when tooltip_placement is provided" do
+ subject { helper.render_status_with_link("success", tooltip_placement: "right") }
+
+ it "has the provided tooltip placement" do
+ is_expected.to include("data-placement=\"right\"")
+ end
+ end
+
+ context "when additional CSS classes are provided" do
+ subject { helper.render_status_with_link("success", cssclass: "extra-class") }
+
+ it "has appended extra class to icon classes" do
+ is_expected.to include("class=\"ci-status-link ci-status-icon-success d-inline-flex extra-class\"")
+ end
+ end
+
+ context "when container is provided" do
+ subject { helper.render_status_with_link("success", container: "my-container") }
+
+ it "has the provided container in data" do
+ is_expected.to include("data-container=\"my-container\"")
+ end
+ end
+
+ context "when icon_size is provided" do
+ subject { helper.render_status_with_link("success", icon_size: 24) }
+
+ it "has the svg class to change size" do
+ is_expected.to include("<svg class=\"s24\">")
+ end
+ end
+ end
end
diff --git a/spec/javascripts/projects/gke_cluster_dropdowns/components/gke_machine_type_dropdown_spec.js b/spec/javascripts/create_cluster/gke_cluster/components/gke_machine_type_dropdown_spec.js
index fdecb823cd2..7aa7aa9a112 100644
--- a/spec/javascripts/projects/gke_cluster_dropdowns/components/gke_machine_type_dropdown_spec.js
+++ b/spec/javascripts/create_cluster/gke_cluster/components/gke_machine_type_dropdown_spec.js
@@ -1,12 +1,12 @@
import Vue from 'vue';
-import GkeMachineTypeDropdown from '~/projects/gke_cluster_dropdowns/components/gke_machine_type_dropdown.vue';
-import { createStore } from '~/projects/gke_cluster_dropdowns/store';
+import GkeMachineTypeDropdown from '~/create_cluster/gke_cluster/components/gke_machine_type_dropdown.vue';
+import { createStore } from '~/create_cluster/gke_cluster/store';
import {
SET_PROJECT,
SET_PROJECT_BILLING_STATUS,
SET_ZONE,
SET_MACHINE_TYPES,
-} from '~/projects/gke_cluster_dropdowns/store/mutation_types';
+} from '~/create_cluster/gke_cluster/store/mutation_types';
import { mountComponentWithStore } from 'spec/helpers/vue_mount_component_helper';
import {
selectedZoneMock,
diff --git a/spec/javascripts/projects/gke_cluster_dropdowns/components/gke_project_id_dropdown_spec.js b/spec/javascripts/create_cluster/gke_cluster/components/gke_project_id_dropdown_spec.js
index 1eb7cb4bd5b..809da3f9088 100644
--- a/spec/javascripts/projects/gke_cluster_dropdowns/components/gke_project_id_dropdown_spec.js
+++ b/spec/javascripts/create_cluster/gke_cluster/components/gke_project_id_dropdown_spec.js
@@ -1,7 +1,7 @@
import Vue from 'vue';
-import GkeProjectIdDropdown from '~/projects/gke_cluster_dropdowns/components/gke_project_id_dropdown.vue';
-import { createStore } from '~/projects/gke_cluster_dropdowns/store';
-import { SET_PROJECTS } from '~/projects/gke_cluster_dropdowns/store/mutation_types';
+import GkeProjectIdDropdown from '~/create_cluster/gke_cluster/components/gke_project_id_dropdown.vue';
+import { createStore } from '~/create_cluster/gke_cluster/store';
+import { SET_PROJECTS } from '~/create_cluster/gke_cluster/store/mutation_types';
import { mountComponentWithStore } from 'spec/helpers/vue_mount_component_helper';
import { emptyProjectMock, selectedProjectMock } from '../mock_data';
diff --git a/spec/javascripts/projects/gke_cluster_dropdowns/components/gke_zone_dropdown_spec.js b/spec/javascripts/create_cluster/gke_cluster/components/gke_zone_dropdown_spec.js
index 95186e19ca1..9cb9419e433 100644
--- a/spec/javascripts/projects/gke_cluster_dropdowns/components/gke_zone_dropdown_spec.js
+++ b/spec/javascripts/create_cluster/gke_cluster/components/gke_zone_dropdown_spec.js
@@ -1,11 +1,11 @@
import Vue from 'vue';
-import GkeZoneDropdown from '~/projects/gke_cluster_dropdowns/components/gke_zone_dropdown.vue';
-import { createStore } from '~/projects/gke_cluster_dropdowns/store';
+import GkeZoneDropdown from '~/create_cluster/gke_cluster/components/gke_zone_dropdown.vue';
+import { createStore } from '~/create_cluster/gke_cluster/store';
import {
SET_PROJECT,
SET_ZONES,
SET_PROJECT_BILLING_STATUS,
-} from '~/projects/gke_cluster_dropdowns/store/mutation_types';
+} from '~/create_cluster/gke_cluster/store/mutation_types';
import { mountComponentWithStore } from 'spec/helpers/vue_mount_component_helper';
import { selectedZoneMock, selectedProjectMock, gapiZonesResponseMock } from '../mock_data';
diff --git a/spec/javascripts/projects/gke_cluster_dropdowns/helpers.js b/spec/javascripts/create_cluster/gke_cluster/helpers.js
index 6df511e9157..6df511e9157 100644
--- a/spec/javascripts/projects/gke_cluster_dropdowns/helpers.js
+++ b/spec/javascripts/create_cluster/gke_cluster/helpers.js
diff --git a/spec/javascripts/projects/gke_cluster_dropdowns/mock_data.js b/spec/javascripts/create_cluster/gke_cluster/mock_data.js
index d9f5dbc636f..d9f5dbc636f 100644
--- a/spec/javascripts/projects/gke_cluster_dropdowns/mock_data.js
+++ b/spec/javascripts/create_cluster/gke_cluster/mock_data.js
diff --git a/spec/javascripts/projects/gke_cluster_dropdowns/stores/actions_spec.js b/spec/javascripts/create_cluster/gke_cluster/stores/actions_spec.js
index 9d892b8185b..a7591cc38c7 100644
--- a/spec/javascripts/projects/gke_cluster_dropdowns/stores/actions_spec.js
+++ b/spec/javascripts/create_cluster/gke_cluster/stores/actions_spec.js
@@ -1,6 +1,6 @@
import testAction from 'spec/helpers/vuex_action_helper';
-import * as actions from '~/projects/gke_cluster_dropdowns/store/actions';
-import { createStore } from '~/projects/gke_cluster_dropdowns/store';
+import * as actions from '~/create_cluster/gke_cluster/store/actions';
+import { createStore } from '~/create_cluster/gke_cluster/store';
import { gapi } from '../helpers';
import { selectedProjectMock, selectedZoneMock, selectedMachineTypeMock } from '../mock_data';
diff --git a/spec/javascripts/projects/gke_cluster_dropdowns/stores/getters_spec.js b/spec/javascripts/create_cluster/gke_cluster/stores/getters_spec.js
index 6f89158f807..ac92716b0ab 100644
--- a/spec/javascripts/projects/gke_cluster_dropdowns/stores/getters_spec.js
+++ b/spec/javascripts/create_cluster/gke_cluster/stores/getters_spec.js
@@ -1,4 +1,4 @@
-import * as getters from '~/projects/gke_cluster_dropdowns/store/getters';
+import * as getters from '~/create_cluster/gke_cluster/store/getters';
import { selectedProjectMock, selectedZoneMock, selectedMachineTypeMock } from '../mock_data';
describe('GCP Cluster Dropdown Store Getters', () => {
diff --git a/spec/javascripts/projects/gke_cluster_dropdowns/stores/mutations_spec.js b/spec/javascripts/create_cluster/gke_cluster/stores/mutations_spec.js
index 7f8c4f314e4..7ee6ff436e2 100644
--- a/spec/javascripts/projects/gke_cluster_dropdowns/stores/mutations_spec.js
+++ b/spec/javascripts/create_cluster/gke_cluster/stores/mutations_spec.js
@@ -1,5 +1,5 @@
-import { createStore } from '~/projects/gke_cluster_dropdowns/store';
-import * as types from '~/projects/gke_cluster_dropdowns/store/mutation_types';
+import { createStore } from '~/create_cluster/gke_cluster/store';
+import * as types from '~/create_cluster/gke_cluster/store/mutation_types';
import {
selectedProjectMock,
selectedZoneMock,
diff --git a/spec/javascripts/ide/components/commit_sidebar/actions_spec.js b/spec/javascripts/ide/components/commit_sidebar/actions_spec.js
index b903abe63fc..a3db3ee1b18 100644
--- a/spec/javascripts/ide/components/commit_sidebar/actions_spec.js
+++ b/spec/javascripts/ide/components/commit_sidebar/actions_spec.js
@@ -1,30 +1,28 @@
import Vue from 'vue';
-import store from '~/ide/stores';
-import consts from '~/ide/stores/modules/commit/constants';
+import { createStore } from '~/ide/stores';
import commitActions from '~/ide/components/commit_sidebar/actions.vue';
+import consts from '~/ide/stores/modules/commit/constants';
import { createComponentWithStore } from 'spec/helpers/vue_mount_component_helper';
-import { resetStore } from 'spec/ide/helpers';
-import { projectData } from 'spec/ide/mock_data';
+import { projectData, branches } from 'spec/ide/mock_data';
+
+const ACTION_UPDATE_COMMIT_ACTION = 'commit/updateCommitAction';
describe('IDE commit sidebar actions', () => {
+ let store;
let vm;
- const createComponent = ({
- hasMR = false,
- commitAction = consts.COMMIT_TO_NEW_BRANCH,
- mergeRequestsEnabled = true,
- currentBranchId = 'master',
- shouldCreateMR = false,
- } = {}) => {
+
+ const createComponent = ({ hasMR = false, currentBranchId = 'master' } = {}) => {
const Component = Vue.extend(commitActions);
vm = createComponentWithStore(Component, store);
vm.$store.state.currentBranchId = currentBranchId;
vm.$store.state.currentProjectId = 'abcproject';
- vm.$store.state.commit.commitAction = commitAction;
- Vue.set(vm.$store.state.projects, 'abcproject', { ...projectData });
- vm.$store.state.projects.abcproject.merge_requests_enabled = mergeRequestsEnabled;
- vm.$store.state.commit.shouldCreateMR = shouldCreateMR;
+
+ const proj = { ...projectData };
+ proj.branches[currentBranchId] = branches.find(branch => branch.name === currentBranchId);
+
+ Vue.set(vm.$store.state.projects, 'abcproject', proj);
if (hasMR) {
vm.$store.state.currentMergeRequestId = '1';
@@ -33,13 +31,19 @@ describe('IDE commit sidebar actions', () => {
] = { foo: 'bar' };
}
- return vm.$mount();
+ vm.$mount();
+
+ return vm;
};
+ beforeEach(() => {
+ store = createStore();
+ spyOn(store, 'dispatch');
+ });
+
afterEach(() => {
vm.$destroy();
-
- resetStore(vm.$store);
+ vm = null;
});
it('renders 2 groups', () => {
@@ -73,4 +77,152 @@ describe('IDE commit sidebar actions', () => {
expect(vm.commitToCurrentBranchText).not.toContain(injectedSrc);
});
});
+
+ describe('updateSelectedCommitAction', () => {
+ it('does not return anything if currentBranch does not exist', () => {
+ createComponent({ currentBranchId: null });
+
+ expect(vm.$store.dispatch).not.toHaveBeenCalled();
+ });
+
+ it('calls again after staged changes', done => {
+ createComponent({ currentBranchId: null });
+
+ vm.$store.state.currentBranchId = 'master';
+ vm.$store.state.changedFiles.push({});
+ vm.$store.state.stagedFiles.push({});
+
+ vm.$nextTick()
+ .then(() => {
+ expect(vm.$store.dispatch).toHaveBeenCalledWith(
+ ACTION_UPDATE_COMMIT_ACTION,
+ jasmine.anything(),
+ );
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+
+ describe('default branch', () => {
+ it('dispatches correct action for default branch', () => {
+ createComponent({
+ currentBranchId: 'master',
+ });
+
+ expect(vm.$store.dispatch).toHaveBeenCalledTimes(1);
+ expect(vm.$store.dispatch).toHaveBeenCalledWith(
+ ACTION_UPDATE_COMMIT_ACTION,
+ consts.COMMIT_TO_NEW_BRANCH,
+ );
+ });
+ });
+
+ describe('protected branch', () => {
+ describe('with write access', () => {
+ it('dispatches correct action when MR exists', () => {
+ createComponent({
+ hasMR: true,
+ currentBranchId: 'protected/access',
+ });
+
+ expect(vm.$store.dispatch).toHaveBeenCalledWith(
+ ACTION_UPDATE_COMMIT_ACTION,
+ consts.COMMIT_TO_CURRENT_BRANCH,
+ );
+ });
+
+ it('dispatches correct action when MR does not exists', () => {
+ createComponent({
+ hasMR: false,
+ currentBranchId: 'protected/access',
+ });
+
+ expect(vm.$store.dispatch).toHaveBeenCalledWith(
+ ACTION_UPDATE_COMMIT_ACTION,
+ consts.COMMIT_TO_CURRENT_BRANCH,
+ );
+ });
+ });
+
+ describe('without write access', () => {
+ it('dispatches correct action when MR exists', () => {
+ createComponent({
+ hasMR: true,
+ currentBranchId: 'protected/no-access',
+ });
+
+ expect(vm.$store.dispatch).toHaveBeenCalledWith(
+ ACTION_UPDATE_COMMIT_ACTION,
+ consts.COMMIT_TO_NEW_BRANCH,
+ );
+ });
+
+ it('dispatches correct action when MR does not exists', () => {
+ createComponent({
+ hasMR: false,
+ currentBranchId: 'protected/no-access',
+ });
+
+ expect(vm.$store.dispatch).toHaveBeenCalledWith(
+ ACTION_UPDATE_COMMIT_ACTION,
+ consts.COMMIT_TO_NEW_BRANCH,
+ );
+ });
+ });
+ });
+
+ describe('regular branch', () => {
+ describe('with write access', () => {
+ it('dispatches correct action when MR exists', () => {
+ createComponent({
+ hasMR: true,
+ currentBranchId: 'regular',
+ });
+
+ expect(vm.$store.dispatch).toHaveBeenCalledWith(
+ ACTION_UPDATE_COMMIT_ACTION,
+ consts.COMMIT_TO_CURRENT_BRANCH,
+ );
+ });
+
+ it('dispatches correct action when MR does not exists', () => {
+ createComponent({
+ hasMR: false,
+ currentBranchId: 'regular',
+ });
+
+ expect(vm.$store.dispatch).toHaveBeenCalledWith(
+ ACTION_UPDATE_COMMIT_ACTION,
+ consts.COMMIT_TO_CURRENT_BRANCH,
+ );
+ });
+ });
+
+ describe('without write access', () => {
+ it('dispatches correct action when MR exists', () => {
+ createComponent({
+ hasMR: true,
+ currentBranchId: 'regular/no-access',
+ });
+
+ expect(vm.$store.dispatch).toHaveBeenCalledWith(
+ ACTION_UPDATE_COMMIT_ACTION,
+ consts.COMMIT_TO_NEW_BRANCH,
+ );
+ });
+
+ it('dispatches correct action when MR does not exists', () => {
+ createComponent({
+ hasMR: false,
+ currentBranchId: 'regular/no-access',
+ });
+
+ expect(vm.$store.dispatch).toHaveBeenCalledWith(
+ ACTION_UPDATE_COMMIT_ACTION,
+ consts.COMMIT_TO_NEW_BRANCH,
+ );
+ });
+ });
+ });
+ });
});
diff --git a/spec/javascripts/ide/components/commit_sidebar/new_merge_request_option_spec.js b/spec/javascripts/ide/components/commit_sidebar/new_merge_request_option_spec.js
index 7017bfcd6a6..5f2db695241 100644
--- a/spec/javascripts/ide/components/commit_sidebar/new_merge_request_option_spec.js
+++ b/spec/javascripts/ide/components/commit_sidebar/new_merge_request_option_spec.js
@@ -1,33 +1,36 @@
import Vue from 'vue';
import store from '~/ide/stores';
-import consts from '~/ide/stores/modules/commit/constants';
import NewMergeRequestOption from '~/ide/components/commit_sidebar/new_merge_request_option.vue';
import { createComponentWithStore } from 'spec/helpers/vue_mount_component_helper';
-import { projectData } from 'spec/ide/mock_data';
+import { projectData, branches } from 'spec/ide/mock_data';
import { resetStore } from 'spec/ide/helpers';
+import consts from '../../../../../app/assets/javascripts/ide/stores/modules/commit/constants';
describe('create new MR checkbox', () => {
let vm;
- const createComponent = ({
- hasMR = false,
- commitAction = consts.COMMIT_TO_NEW_BRANCH,
- currentBranchId = 'master',
- } = {}) => {
+ const setMR = () => {
+ vm.$store.state.currentMergeRequestId = '1';
+ vm.$store.state.projects[store.state.currentProjectId].mergeRequests[
+ store.state.currentMergeRequestId
+ ] = { foo: 'bar' };
+ };
+
+ const createComponent = ({ currentBranchId = 'master', createNewBranch = false } = {}) => {
const Component = Vue.extend(NewMergeRequestOption);
vm = createComponentWithStore(Component, store);
+ vm.$store.state.commit.commitAction = createNewBranch
+ ? consts.COMMIT_TO_NEW_BRANCH
+ : consts.COMMIT_TO_CURRENT_BRANCH;
+
vm.$store.state.currentBranchId = currentBranchId;
vm.$store.state.currentProjectId = 'abcproject';
- vm.$store.state.commit.commitAction = commitAction;
- Vue.set(vm.$store.state.projects, 'abcproject', { ...projectData });
- if (hasMR) {
- vm.$store.state.currentMergeRequestId = '1';
- vm.$store.state.projects[store.state.currentProjectId].mergeRequests[
- store.state.currentMergeRequestId
- ] = { foo: 'bar' };
- }
+ const proj = JSON.parse(JSON.stringify(projectData));
+ proj.branches[currentBranchId] = branches.find(branch => branch.name === currentBranchId);
+
+ Vue.set(vm.$store.state.projects, 'abcproject', proj);
return vm.$mount();
};
@@ -38,30 +41,131 @@ describe('create new MR checkbox', () => {
resetStore(vm.$store);
});
- it('is hidden when an MR already exists and committing to current branch', () => {
- createComponent({
- hasMR: true,
- commitAction: consts.COMMIT_TO_CURRENT_BRANCH,
- currentBranchId: 'feature',
+ describe('for default branch', () => {
+ describe('is rendered when pushing to a new branch', () => {
+ beforeEach(() => {
+ createComponent({
+ currentBranchId: 'master',
+ createNewBranch: true,
+ });
+ });
+
+ it('has NO new MR', () => {
+ expect(vm.$el.textContent).not.toBe('');
+ });
+
+ it('has new MR', done => {
+ setMR();
+
+ vm.$nextTick()
+ .then(() => {
+ expect(vm.$el.textContent).not.toBe('');
+ })
+ .then(done)
+ .catch(done.fail);
+ });
});
- expect(vm.$el.textContent).toBe('');
+ describe('is NOT rendered when pushing to the same branch', () => {
+ beforeEach(() => {
+ createComponent({
+ currentBranchId: 'master',
+ createNewBranch: false,
+ });
+ });
+
+ it('has NO new MR', () => {
+ expect(vm.$el.textContent).toBe('');
+ });
+
+ it('has new MR', done => {
+ setMR();
+
+ vm.$nextTick()
+ .then(() => {
+ expect(vm.$el.textContent).toBe('');
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+ });
});
- it('does not hide checkbox if MR does not exist', () => {
- createComponent({ hasMR: false });
+ describe('for protected branch', () => {
+ describe('when user does not have the write access', () => {
+ beforeEach(() => {
+ createComponent({
+ currentBranchId: 'protected/no-access',
+ });
+ });
+
+ it('is rendered if MR does not exists', () => {
+ expect(vm.$el.textContent).not.toBe('');
+ });
+
+ it('is rendered if MR exists', done => {
+ setMR();
- expect(vm.$el.querySelector('input[type="checkbox"]').hidden).toBe(false);
+ vm.$nextTick()
+ .then(() => {
+ expect(vm.$el.textContent).not.toBe('');
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+ });
+
+ describe('when user has the write access', () => {
+ beforeEach(() => {
+ createComponent({
+ currentBranchId: 'protected/access',
+ });
+ });
+
+ it('is rendered if MR does not exist', () => {
+ expect(vm.$el.textContent).not.toBe('');
+ });
+
+ it('is hidden if MR exists', done => {
+ setMR();
+
+ vm.$nextTick()
+ .then(() => {
+ expect(vm.$el.textContent).toBe('');
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+ });
});
- it('does not hide checkbox when creating a new branch', () => {
- createComponent({ commitAction: consts.COMMIT_TO_NEW_BRANCH });
+ describe('for regular branch', () => {
+ beforeEach(() => {
+ createComponent({
+ currentBranchId: 'regular',
+ });
+ });
- expect(vm.$el.querySelector('input[type="checkbox"]').hidden).toBe(false);
+ it('is rendered if no MR exists', () => {
+ expect(vm.$el.textContent).not.toBe('');
+ });
+
+ it('is hidden if MR exists', done => {
+ setMR();
+
+ vm.$nextTick()
+ .then(() => {
+ expect(vm.$el.textContent).toBe('');
+ })
+ .then(done)
+ .catch(done.fail);
+ });
});
it('dispatches toggleShouldCreateMR when clicking checkbox', () => {
- createComponent();
+ createComponent({
+ currentBranchId: 'regular',
+ });
const el = vm.$el.querySelector('input[type="checkbox"]');
spyOn(vm.$store, 'dispatch');
el.dispatchEvent(new Event('change'));
diff --git a/spec/javascripts/ide/mock_data.js b/spec/javascripts/ide/mock_data.js
index 570a396c5e3..c02c7e5d45e 100644
--- a/spec/javascripts/ide/mock_data.js
+++ b/spec/javascripts/ide/mock_data.js
@@ -176,23 +176,51 @@ export const branches = [
committed_date: '2018-08-01T00:20:05Z',
},
can_push: true,
+ protected: true,
+ default: true,
},
{
id: 2,
- name: 'feature/lorem-ipsum',
+ name: 'protected/no-access',
commit: {
message: 'Update some stuff',
committed_date: '2018-08-02T00:00:05Z',
},
- can_push: true,
+ can_push: false,
+ protected: true,
+ default: false,
},
{
id: 3,
- name: 'feature/dolar-amit',
+ name: 'protected/access',
+ commit: {
+ message: 'Update some stuff',
+ committed_date: '2018-08-02T00:00:05Z',
+ },
+ can_push: true,
+ protected: true,
+ default: false,
+ },
+ {
+ id: 4,
+ name: 'regular',
commit: {
message: 'Update some more stuff',
committed_date: '2018-06-30T00:20:05Z',
},
can_push: true,
+ protected: false,
+ default: false,
+ },
+ {
+ id: 5,
+ name: 'regular/no-access',
+ commit: {
+ message: 'Update some more stuff',
+ committed_date: '2018-06-30T00:20:05Z',
+ },
+ can_push: false,
+ protected: false,
+ default: false,
},
];
diff --git a/spec/javascripts/ide/stores/getters_spec.js b/spec/javascripts/ide/stores/getters_spec.js
index 735bbd47f55..73a8d993a13 100644
--- a/spec/javascripts/ide/stores/getters_spec.js
+++ b/spec/javascripts/ide/stores/getters_spec.js
@@ -221,4 +221,36 @@ describe('IDE store getters', () => {
});
});
});
+
+ describe('canPushToBranch', () => {
+ it('returns false when no currentBranch exists', () => {
+ const localGetters = {
+ currentProject: undefined,
+ };
+
+ expect(getters.canPushToBranch({}, localGetters)).toBeFalsy();
+ });
+
+ it('returns true when can_push to currentBranch', () => {
+ const localGetters = {
+ currentProject: {
+ default_branch: 'master',
+ },
+ currentBranch: { can_push: true },
+ };
+
+ expect(getters.canPushToBranch({}, localGetters)).toBeTruthy();
+ });
+
+ it('returns false when !can_push to currentBranch', () => {
+ const localGetters = {
+ currentProject: {
+ default_branch: 'master',
+ },
+ currentBranch: { can_push: false },
+ };
+
+ expect(getters.canPushToBranch({}, localGetters)).toBeFalsy();
+ });
+ });
});
diff --git a/spec/javascripts/ide/stores/modules/commit/actions_spec.js b/spec/javascripts/ide/stores/modules/commit/actions_spec.js
index 14d861f21d2..091b454c0d2 100644
--- a/spec/javascripts/ide/stores/modules/commit/actions_spec.js
+++ b/spec/javascripts/ide/stores/modules/commit/actions_spec.js
@@ -57,6 +57,44 @@ describe('IDE commit module actions', () => {
.then(done)
.catch(done.fail);
});
+
+ it('sets shouldCreateMR to true if "Create new MR" option is visible', done => {
+ store.state.shouldHideNewMrOption = false;
+
+ testAction(
+ actions.updateCommitAction,
+ {},
+ store.state,
+ [
+ {
+ type: mutationTypes.UPDATE_COMMIT_ACTION,
+ payload: { commitAction: jasmine.anything() },
+ },
+ { type: mutationTypes.TOGGLE_SHOULD_CREATE_MR, payload: true },
+ ],
+ [],
+ done,
+ );
+ });
+
+ it('sets shouldCreateMR to false if "Create new MR" option is hidden', done => {
+ store.state.shouldHideNewMrOption = true;
+
+ testAction(
+ actions.updateCommitAction,
+ {},
+ store.state,
+ [
+ {
+ type: mutationTypes.UPDATE_COMMIT_ACTION,
+ payload: { commitAction: jasmine.anything() },
+ },
+ { type: mutationTypes.TOGGLE_SHOULD_CREATE_MR, payload: false },
+ ],
+ [],
+ done,
+ );
+ });
});
describe('updateBranchName', () => {
@@ -541,147 +579,10 @@ describe('IDE commit module actions', () => {
actions.toggleShouldCreateMR,
{},
store.state,
- [
- { type: mutationTypes.TOGGLE_SHOULD_CREATE_MR },
- { type: mutationTypes.INTERACT_WITH_NEW_MR },
- ],
+ [{ type: mutationTypes.TOGGLE_SHOULD_CREATE_MR }],
[],
done,
);
});
});
-
- describe('setShouldCreateMR', () => {
- beforeEach(() => {
- store.state.projects = {
- project: {
- default_branch: 'master',
- branches: {
- master: {
- name: 'master',
- },
- feature: {
- name: 'feature',
- },
- },
- },
- };
-
- store.state.currentProjectId = 'project';
- });
-
- it('sets to false when the current branch already has an MR', done => {
- store.state.commit.currentMergeRequestId = 1;
- store.state.commit.commitAction = consts.COMMIT_TO_CURRENT_BRANCH;
- store.state.currentMergeRequestId = '1';
- store.state.currentBranchId = 'feature';
- spyOn(store, 'commit').and.callThrough();
-
- store
- .dispatch('commit/setShouldCreateMR')
- .then(() => {
- expect(store.commit.calls.allArgs()[0]).toEqual(
- jasmine.arrayContaining([`commit/${mutationTypes.TOGGLE_SHOULD_CREATE_MR}`, false]),
- );
- done();
- })
- .catch(done.fail);
- });
-
- it('changes to false when current branch is the default branch and user has not interacted', done => {
- store.state.commit.interactedWithNewMR = false;
- store.state.currentBranchId = 'master';
- store.state.commit.commitAction = consts.COMMIT_TO_CURRENT_BRANCH;
- spyOn(store, 'commit').and.callThrough();
-
- store
- .dispatch('commit/setShouldCreateMR')
- .then(() => {
- expect(store.commit.calls.allArgs()[0]).toEqual(
- jasmine.arrayContaining([`commit/${mutationTypes.TOGGLE_SHOULD_CREATE_MR}`, false]),
- );
- done();
- })
- .catch(done.fail);
- });
-
- it('changes to true when "create new branch" is selected and user has not interacted', done => {
- store.state.commit.commitAction = consts.COMMIT_TO_NEW_BRANCH;
- store.state.commit.interactedWithNewMR = false;
- spyOn(store, 'commit').and.callThrough();
-
- store
- .dispatch('commit/setShouldCreateMR')
- .then(() => {
- expect(store.commit.calls.allArgs()[0]).toEqual(
- jasmine.arrayContaining([`commit/${mutationTypes.TOGGLE_SHOULD_CREATE_MR}`, true]),
- );
- done();
- })
- .catch(done.fail);
- });
-
- it('does not change anything if user has interacted and comitting to new branch', done => {
- store.state.commit.commitAction = consts.COMMIT_TO_NEW_BRANCH;
- store.state.commit.interactedWithNewMR = true;
- spyOn(store, 'commit').and.callThrough();
-
- store
- .dispatch('commit/setShouldCreateMR')
- .then(() => {
- expect(store.commit).not.toHaveBeenCalled();
- done();
- })
- .catch(done.fail);
- });
-
- it('does not change anything if user has interacted and comitting to branch without MR', done => {
- store.state.commit.commitAction = consts.COMMIT_TO_CURRENT_BRANCH;
- store.state.commit.currentMergeRequestId = null;
- store.state.commit.interactedWithNewMR = true;
- spyOn(store, 'commit').and.callThrough();
-
- store
- .dispatch('commit/setShouldCreateMR')
- .then(() => {
- expect(store.commit).not.toHaveBeenCalled();
- done();
- })
- .catch(done.fail);
- });
-
- it('still changes to false if hiding the checkbox', done => {
- store.state.currentBranchId = 'feature';
- store.state.commit.commitAction = consts.COMMIT_TO_CURRENT_BRANCH;
- store.state.currentMergeRequestId = '1';
- store.state.commit.interactedWithNewMR = true;
- spyOn(store, 'commit').and.callThrough();
-
- store
- .dispatch('commit/setShouldCreateMR')
- .then(() => {
- expect(store.commit.calls.allArgs()[0]).toEqual(
- jasmine.arrayContaining([`commit/${mutationTypes.TOGGLE_SHOULD_CREATE_MR}`, false]),
- );
- done();
- })
- .catch(done.fail);
- });
-
- it('does not change to false when on master and user has interacted even if MR exists', done => {
- store.state.currentBranchId = 'master';
- store.state.commit.commitAction = consts.COMMIT_TO_CURRENT_BRANCH;
- store.state.currentMergeRequestId = '1';
- store.state.commit.interactedWithNewMR = true;
- spyOn(store, 'commit').and.callThrough();
-
- store
- .dispatch('commit/setShouldCreateMR')
- .then(() => {
- expect(store.commit).not.toHaveBeenCalled();
- done();
- })
- .catch(done.fail);
- });
- });
});
diff --git a/spec/javascripts/ide/stores/modules/commit/getters_spec.js b/spec/javascripts/ide/stores/modules/commit/getters_spec.js
index 6e71a790deb..07445c22917 100644
--- a/spec/javascripts/ide/stores/modules/commit/getters_spec.js
+++ b/spec/javascripts/ide/stores/modules/commit/getters_spec.js
@@ -1,6 +1,6 @@
import commitState from '~/ide/stores/modules/commit/state';
-import consts from '~/ide/stores/modules/commit/constants';
import * as getters from '~/ide/stores/modules/commit/getters';
+import consts from '~/ide/stores/modules/commit/constants';
describe('IDE commit module getters', () => {
let state;
@@ -55,15 +55,15 @@ describe('IDE commit module getters', () => {
});
});
- it('defualts to currentBranchId', () => {
- expect(getters.branchName(state, null, rootState)).toBe('master');
+ it('defaults to currentBranchId when not committing to a new branch', () => {
+ localGetters.isCreatingNewBranch = false;
+
+ expect(getters.branchName(state, localGetters, rootState)).toBe('master');
});
- describe('COMMIT_TO_NEW_BRANCH', () => {
+ describe('commit to a new branch', () => {
beforeEach(() => {
- Object.assign(state, {
- commitAction: consts.COMMIT_TO_NEW_BRANCH,
- });
+ localGetters.isCreatingNewBranch = true;
});
it('uses newBranchName when not empty', () => {
@@ -144,4 +144,152 @@ describe('IDE commit module getters', () => {
});
});
});
+
+ describe('isCreatingNewBranch', () => {
+ it('returns false if NOT creating a new branch', () => {
+ state.commitAction = consts.COMMIT_TO_CURRENT_BRANCH;
+
+ expect(getters.isCreatingNewBranch(state)).toBeFalsy();
+ });
+
+ it('returns true if creating a new branch', () => {
+ state.commitAction = consts.COMMIT_TO_NEW_BRANCH;
+
+ expect(getters.isCreatingNewBranch(state)).toBeTruthy();
+ });
+ });
+
+ describe('shouldHideNewMrOption', () => {
+ let localGetters = {};
+ let rootGetters = {};
+
+ beforeEach(() => {
+ localGetters = {
+ isCreatingNewBranch: null,
+ };
+ rootGetters = {
+ isOnDefaultBranch: null,
+ hasMergeRequest: null,
+ canPushToBranch: null,
+ };
+ });
+
+ describe('NO existing MR for the branch', () => {
+ beforeEach(() => {
+ rootGetters.hasMergeRequest = false;
+ });
+
+ it('should never hide "New MR" option', () => {
+ expect(getters.shouldHideNewMrOption(state, localGetters, null, rootGetters)).toBeFalsy();
+ });
+ });
+
+ describe('existing MR for the branch', () => {
+ beforeEach(() => {
+ rootGetters.hasMergeRequest = true;
+ });
+
+ it('should NOT hide "New MR" option if user can NOT push to the current branch', () => {
+ rootGetters.canPushToBranch = false;
+
+ expect(getters.shouldHideNewMrOption(state, localGetters, null, rootGetters)).toBeFalsy();
+ });
+
+ it('should hide "New MR" option if user can push to the current branch', () => {
+ rootGetters.canPushToBranch = true;
+
+ expect(getters.shouldHideNewMrOption(state, localGetters, null, rootGetters)).toBeTruthy();
+ });
+ });
+
+ describe('user can NOT push the branch', () => {
+ beforeEach(() => {
+ rootGetters.canPushToBranch = false;
+ });
+
+ it('should never hide "New MR" option', () => {
+ expect(getters.shouldHideNewMrOption(state, localGetters, null, rootGetters)).toBeFalsy();
+ });
+ });
+
+ describe('user can push to the branch', () => {
+ beforeEach(() => {
+ rootGetters.canPushToBranch = true;
+ });
+
+ it('should NOT hide "New MR" option if there is NO existing MR for the current branch', () => {
+ rootGetters.hasMergeRequest = false;
+
+ expect(getters.shouldHideNewMrOption(state, localGetters, null, rootGetters)).toBeFalsy();
+ });
+
+ it('should hide "New MR" option if there is existing MR for the current branch', () => {
+ rootGetters.hasMergeRequest = true;
+
+ expect(getters.shouldHideNewMrOption(state, localGetters, null, rootGetters)).toBeTruthy();
+ });
+ });
+
+ describe('default branch', () => {
+ beforeEach(() => {
+ rootGetters.isOnDefaultBranch = true;
+ });
+
+ describe('committing to the same branch', () => {
+ beforeEach(() => {
+ localGetters.isCreatingNewBranch = false;
+ rootGetters.canPushToBranch = true;
+ });
+
+ it('should hide "New MR" when there is an existing MR', () => {
+ rootGetters.hasMergeRequest = true;
+
+ expect(
+ getters.shouldHideNewMrOption(state, localGetters, null, rootGetters),
+ ).toBeTruthy();
+ });
+
+ it('should hide "New MR" when there is no existing MR', () => {
+ rootGetters.hasMergeRequest = false;
+
+ expect(
+ getters.shouldHideNewMrOption(state, localGetters, null, rootGetters),
+ ).toBeTruthy();
+ });
+ });
+
+ describe('creating a new branch', () => {
+ beforeEach(() => {
+ localGetters.isCreatingNewBranch = true;
+ });
+
+ it('should NOT hide "New MR" option no matter existence of an MR or write access', () => {
+ rootGetters.hasMergeRequest = false;
+ rootGetters.canPushToBranch = true;
+
+ expect(getters.shouldHideNewMrOption(state, localGetters, null, rootGetters)).toBeFalsy();
+
+ rootGetters.hasMergeRequest = true;
+ rootGetters.canPushToBranch = true;
+
+ expect(getters.shouldHideNewMrOption(state, localGetters, null, rootGetters)).toBeFalsy();
+
+ rootGetters.hasMergeRequest = false;
+ rootGetters.canPushToBranch = false;
+
+ expect(getters.shouldHideNewMrOption(state, localGetters, null, rootGetters)).toBeFalsy();
+ });
+ });
+ });
+
+ it('should never hide "New MR" option when creating a new branch', () => {
+ localGetters.isCreatingNewBranch = true;
+
+ rootGetters.isOnDefaultBranch = false;
+ rootGetters.hasMergeRequest = true;
+ rootGetters.canPushToBranch = true;
+
+ expect(getters.shouldHideNewMrOption(state, localGetters, null, rootGetters)).toBeFalsy();
+ });
+ });
});
diff --git a/spec/javascripts/monitoring/charts/area_spec.js b/spec/javascripts/monitoring/charts/area_spec.js
index 57f99a09002..1e49a955815 100644
--- a/spec/javascripts/monitoring/charts/area_spec.js
+++ b/spec/javascripts/monitoring/charts/area_spec.js
@@ -225,6 +225,14 @@ describe('Area component', () => {
});
describe('chartOptions', () => {
+ describe('dataZoom', () => {
+ it('contains an svg object within an array to properly render icon', () => {
+ const dataZoomObject = [{}];
+
+ expect(areaChart.vm.chartOptions.dataZoom).toEqual(dataZoomObject);
+ });
+ });
+
describe('yAxis formatter', () => {
let format;
diff --git a/spec/javascripts/monitoring/panel_type_spec.js b/spec/javascripts/monitoring/panel_type_spec.js
index 086be628093..a2366e74d43 100644
--- a/spec/javascripts/monitoring/panel_type_spec.js
+++ b/spec/javascripts/monitoring/panel_type_spec.js
@@ -1,7 +1,7 @@
import { shallowMount } from '@vue/test-utils';
import PanelType from '~/monitoring/components/panel_type.vue';
import EmptyChart from '~/monitoring/components/charts/empty_chart.vue';
-import AreaChart from '~/monitoring/components/charts/area.vue';
+import TimeSeriesChart from '~/monitoring/components/charts/time_series.vue';
import { graphDataPrometheusQueryRange } from './mock_data';
import { createStore } from '~/monitoring/stores';
@@ -62,9 +62,10 @@ describe('Panel Type component', () => {
});
});
- describe('Area Chart panel type', () => {
+ describe('Time Series Chart panel type', () => {
it('is rendered', () => {
- expect(panelType.find(AreaChart).exists()).toBe(true);
+ expect(panelType.find(TimeSeriesChart).isVueInstance()).toBe(true);
+ expect(panelType.find(TimeSeriesChart).exists()).toBe(true);
});
it('sets clipboard text on the dropdown', () => {
diff --git a/spec/javascripts/notes/stores/actions_spec.js b/spec/javascripts/notes/stores/actions_spec.js
index e55aa0e965a..1fd4a9a7612 100644
--- a/spec/javascripts/notes/stores/actions_spec.js
+++ b/spec/javascripts/notes/stores/actions_spec.js
@@ -336,7 +336,7 @@ describe('Actions Notes Store', () => {
});
});
- describe('deleteNote', () => {
+ describe('removeNote', () => {
const endpoint = `${TEST_HOST}/note`;
let axiosMock;
@@ -357,7 +357,7 @@ describe('Actions Notes Store', () => {
const note = { path: endpoint, id: 1 };
testAction(
- actions.deleteNote,
+ actions.removeNote,
note,
store.state,
[
@@ -384,7 +384,7 @@ describe('Actions Notes Store', () => {
$('body').attr('data-page', 'projects:merge_requests:show');
testAction(
- actions.deleteNote,
+ actions.removeNote,
note,
store.state,
[
@@ -409,6 +409,45 @@ describe('Actions Notes Store', () => {
});
});
+ describe('deleteNote', () => {
+ const endpoint = `${TEST_HOST}/note`;
+ let axiosMock;
+
+ beforeEach(() => {
+ axiosMock = new AxiosMockAdapter(axios);
+ axiosMock.onDelete(endpoint).replyOnce(200, {});
+
+ $('body').attr('data-page', '');
+ });
+
+ afterEach(() => {
+ axiosMock.restore();
+
+ $('body').attr('data-page', '');
+ });
+
+ it('dispatches removeNote', done => {
+ const note = { path: endpoint, id: 1 };
+
+ testAction(
+ actions.deleteNote,
+ note,
+ {},
+ [],
+ [
+ {
+ type: 'removeNote',
+ payload: {
+ id: 1,
+ path: 'http://test.host/note',
+ },
+ },
+ ],
+ done,
+ );
+ });
+ });
+
describe('createNewNote', () => {
describe('success', () => {
const res = {
diff --git a/spec/lib/api/helpers/label_helpers_spec.rb b/spec/lib/api/helpers/label_helpers_spec.rb
new file mode 100644
index 00000000000..138e9a22d70
--- /dev/null
+++ b/spec/lib/api/helpers/label_helpers_spec.rb
@@ -0,0 +1,33 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe API::Helpers::LabelHelpers do
+ describe 'create_service_params' do
+ let(:label_helper) do
+ Class.new do
+ include API::Helpers::LabelHelpers
+ end.new
+ end
+
+ context 'when a project is given' do
+ it 'returns the expected params' do
+ project = create(:project)
+ expect(label_helper.create_service_params(project)).to eq({ project: project })
+ end
+ end
+
+ context 'when a group is given' do
+ it 'returns the expected params' do
+ group = create(:group)
+ expect(label_helper.create_service_params(group)).to eq({ group: group })
+ end
+ end
+
+ context 'when something else is given' do
+ it 'raises a type error' do
+ expect { label_helper.create_service_params(Class.new) }.to raise_error(TypeError)
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/analytics/cycle_analytics/stage_events/stage_event_spec.rb b/spec/lib/gitlab/analytics/cycle_analytics/stage_events/stage_event_spec.rb
new file mode 100644
index 00000000000..29f4be76a65
--- /dev/null
+++ b/spec/lib/gitlab/analytics/cycle_analytics/stage_events/stage_event_spec.rb
@@ -0,0 +1,10 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Gitlab::Analytics::CycleAnalytics::StageEvents::StageEvent do
+ it { expect(described_class).to respond_to(:name) }
+ it { expect(described_class).to respond_to(:identifier) }
+
+ it { expect(described_class.new({})).to respond_to(:object_type) }
+end
diff --git a/spec/lib/gitlab/auth/o_auth/user_spec.rb b/spec/lib/gitlab/auth/o_auth/user_spec.rb
index a9b15c411dc..1e3da4f7c2d 100644
--- a/spec/lib/gitlab/auth/o_auth/user_spec.rb
+++ b/spec/lib/gitlab/auth/o_auth/user_spec.rb
@@ -787,11 +787,25 @@ describe Gitlab::Auth::OAuth::User do
end
end
- describe '#bypass_two_factor?' do
- subject { oauth_user.bypass_two_factor? }
+ describe "#bypass_two_factor?" do
+ it "when with allow_bypass_two_factor disabled (Default)" do
+ stub_omniauth_config(allow_bypass_two_factor: false)
+ expect(oauth_user.bypass_two_factor?).to be_falsey
+ end
+
+ it "when with allow_bypass_two_factor enabled" do
+ stub_omniauth_config(allow_bypass_two_factor: true)
+ expect(oauth_user.bypass_two_factor?).to be_truthy
+ end
+
+ it "when provider in allow_bypass_two_factor array" do
+ stub_omniauth_config(allow_bypass_two_factor: [provider])
+ expect(oauth_user.bypass_two_factor?).to be_truthy
+ end
- it 'returns always false' do
- is_expected.to be_falsey
+ it "when provider not in allow_bypass_two_factor array" do
+ stub_omniauth_config(allow_bypass_two_factor: ["foo"])
+ expect(oauth_user.bypass_two_factor?).to be_falsey
end
end
end
diff --git a/spec/lib/gitlab/auth_spec.rb b/spec/lib/gitlab/auth_spec.rb
index edff38f05ec..098c33f9cb1 100644
--- a/spec/lib/gitlab/auth_spec.rb
+++ b/spec/lib/gitlab/auth_spec.rb
@@ -86,7 +86,7 @@ describe Gitlab::Auth do
let(:project) { build.project }
before do
- expect(gl_auth).to receive(:rate_limit!).with('ip', success: true, login: 'gitlab-ci-token')
+ expect(gl_auth).not_to receive(:rate_limit!).with('ip', success: true, login: 'gitlab-ci-token')
end
it 'recognises user-less build' do
@@ -106,7 +106,7 @@ describe Gitlab::Auth do
let(:project) { build.project }
before do
- expect(gl_auth).to receive(:rate_limit!).with('ip', success: false, login: 'gitlab-ci-token')
+ expect(gl_auth).not_to receive(:rate_limit!).with('ip', success: false, login: 'gitlab-ci-token')
end
it 'denies authentication' do
diff --git a/spec/lib/gitlab/danger/teammate_spec.rb b/spec/lib/gitlab/danger/teammate_spec.rb
index 171f2344e82..afbc3896a70 100644
--- a/spec/lib/gitlab/danger/teammate_spec.rb
+++ b/spec/lib/gitlab/danger/teammate_spec.rb
@@ -28,7 +28,7 @@ describe Gitlab::Danger::Teammate do
end
context 'when labels contain Create and the category is test' do
- let(:labels) { ['Create'] }
+ let(:labels) { ['devops::create'] }
context 'when role is Test Automation Engineer, Create' do
let(:role) { 'Test Automation Engineer, Create' }
@@ -50,6 +50,14 @@ describe Gitlab::Danger::Teammate do
end
end
+ context 'when role is Test Automation Engineer' do
+ let(:role) { 'Test Automation Engineer' }
+
+ it '#reviewer? returns false' do
+ expect(subject.reviewer?(project, :test, labels)).to be_falsey
+ end
+ end
+
context 'when role is Test Automation Engineer, Manage' do
let(:role) { 'Test Automation Engineer, Manage' }
diff --git a/spec/lib/gitlab/database/migration_helpers_spec.rb b/spec/lib/gitlab/database/migration_helpers_spec.rb
index 2731fc8573f..cff4eb398bf 100644
--- a/spec/lib/gitlab/database/migration_helpers_spec.rb
+++ b/spec/lib/gitlab/database/migration_helpers_spec.rb
@@ -576,6 +576,38 @@ describe Gitlab::Database::MigrationHelpers do
model.rename_column_concurrently(:users, :old, :new)
end
+
+ context 'when default is false' do
+ let(:old_column) do
+ double(:column,
+ type: :boolean,
+ limit: nil,
+ default: false,
+ null: false,
+ precision: nil,
+ scale: nil)
+ end
+
+ it 'copies the default to the new column' do
+ expect(model).to receive(:change_column_default)
+ .with(:users, :new, old_column.default)
+
+ model.rename_column_concurrently(:users, :old, :new)
+ end
+ end
+ end
+ end
+
+ describe '#undo_rename_column_concurrently' do
+ it 'reverses the operations of rename_column_concurrently' do
+ expect(model).to receive(:check_trigger_permissions!).with(:users)
+
+ expect(model).to receive(:remove_rename_triggers_for_postgresql)
+ .with(:users, /trigger_.{12}/)
+
+ expect(model).to receive(:remove_column).with(:users, :new)
+
+ model.undo_rename_column_concurrently(:users, :old, :new)
end
end
@@ -592,6 +624,80 @@ describe Gitlab::Database::MigrationHelpers do
end
end
+ describe '#undo_cleanup_concurrent_column_rename' do
+ context 'in a transaction' do
+ it 'raises RuntimeError' do
+ allow(model).to receive(:transaction_open?).and_return(true)
+
+ expect { model.undo_cleanup_concurrent_column_rename(:users, :old, :new) }
+ .to raise_error(RuntimeError)
+ end
+ end
+
+ context 'outside a transaction' do
+ let(:new_column) do
+ double(:column,
+ type: :integer,
+ limit: 8,
+ default: 0,
+ null: false,
+ precision: 5,
+ scale: 1)
+ end
+
+ let(:trigger_name) { model.rename_trigger_name(:users, :old, :new) }
+
+ before do
+ allow(model).to receive(:transaction_open?).and_return(false)
+ allow(model).to receive(:column_for).and_return(new_column)
+ end
+
+ it 'reverses the operations of cleanup_concurrent_column_rename' do
+ expect(model).to receive(:check_trigger_permissions!).with(:users)
+
+ expect(model).to receive(:install_rename_triggers_for_postgresql)
+ .with(trigger_name, '"users"', '"old"', '"new"')
+
+ expect(model).to receive(:add_column)
+ .with(:users, :old, :integer,
+ limit: new_column.limit,
+ precision: new_column.precision,
+ scale: new_column.scale)
+
+ expect(model).to receive(:change_column_default)
+ .with(:users, :old, new_column.default)
+
+ expect(model).to receive(:update_column_in_batches)
+
+ expect(model).to receive(:change_column_null).with(:users, :old, false)
+
+ expect(model).to receive(:copy_indexes).with(:users, :new, :old)
+ expect(model).to receive(:copy_foreign_keys).with(:users, :new, :old)
+
+ model.undo_cleanup_concurrent_column_rename(:users, :old, :new)
+ end
+
+ context 'when default is false' do
+ let(:new_column) do
+ double(:column,
+ type: :boolean,
+ limit: nil,
+ default: false,
+ null: false,
+ precision: nil,
+ scale: nil)
+ end
+
+ it 'copies the default to the old column' do
+ expect(model).to receive(:change_column_default)
+ .with(:users, :old, new_column.default)
+
+ model.undo_cleanup_concurrent_column_rename(:users, :old, :new)
+ end
+ end
+ end
+ end
+
describe '#change_column_type_concurrently' do
it 'changes the column type' do
expect(model).to receive(:rename_column_concurrently)
@@ -619,10 +725,18 @@ describe Gitlab::Database::MigrationHelpers do
.with(/CREATE OR REPLACE FUNCTION foo()/m)
expect(model).to receive(:execute)
+ .with(/DROP TRIGGER IF EXISTS foo/m)
+
+ expect(model).to receive(:execute)
.with(/CREATE TRIGGER foo/m)
model.install_rename_triggers_for_postgresql('foo', :users, :old, :new)
end
+
+ it 'does not fail if trigger already exists' do
+ model.install_rename_triggers_for_postgresql('foo', :users, :old, :new)
+ model.install_rename_triggers_for_postgresql('foo', :users, :old, :new)
+ end
end
describe '#remove_rename_triggers_for_postgresql' do
diff --git a/spec/services/self_monitoring/project/create_service_spec.rb b/spec/lib/gitlab/database_importers/self_monitoring/project/create_service_spec.rb
index def20448bd9..b25f0f6b887 100644
--- a/spec/services/self_monitoring/project/create_service_spec.rb
+++ b/spec/lib/gitlab/database_importers/self_monitoring/project/create_service_spec.rb
@@ -2,29 +2,48 @@
require 'spec_helper'
-describe SelfMonitoring::Project::CreateService do
+describe Gitlab::DatabaseImporters::SelfMonitoring::Project::CreateService do
describe '#execute' do
- let(:result) { subject.execute }
+ let(:result) { subject.execute! }
let(:prometheus_settings) do
- OpenStruct.new(
+ {
enable: true,
listen_address: 'localhost:9090'
- )
+ }
end
before do
- allow(Gitlab.config).to receive(:prometheus).and_return(prometheus_settings)
+ stub_config(prometheus: prometheus_settings)
+ end
+
+ context 'without application_settings' do
+ it 'does not fail' do
+ expect(subject).to receive(:log_error).and_call_original
+ expect(result).to eq(
+ status: :success
+ )
+
+ expect(Project.count).to eq(0)
+ expect(Group.count).to eq(0)
+ end
end
context 'without admin users' do
- it 'returns error' do
+ let(:application_setting) { Gitlab::CurrentSettings.current_application_settings }
+
+ before do
+ allow(ApplicationSetting).to receive(:current_without_cache) { application_setting }
+ end
+
+ it 'does not fail' do
expect(subject).to receive(:log_error).and_call_original
expect(result).to eq(
- status: :error,
- message: 'No active admin user found',
- failed_step: :validate_admins
+ status: :success
)
+
+ expect(Project.count).to eq(0)
+ expect(Group.count).to eq(0)
end
end
@@ -36,6 +55,7 @@ describe SelfMonitoring::Project::CreateService do
let!(:user) { create(:user, :admin) }
before do
+ allow(ApplicationSetting).to receive(:current_without_cache) { application_setting }
application_setting.allow_local_requests_from_web_hooks_and_services = true
end
@@ -56,8 +76,8 @@ describe SelfMonitoring::Project::CreateService do
it 'creates group' do
expect(result[:status]).to eq(:success)
expect(group).to be_persisted
- expect(group.name).to eq(described_class::GROUP_NAME)
- expect(group.path).to start_with(described_class::GROUP_PATH)
+ expect(group.name).to eq('GitLab Instance Administrators')
+ expect(group.path).to start_with('gitlab-instance-administrators')
expect(group.path.split('-').last.length).to eq(8)
expect(group.visibility_level).to eq(described_class::VISIBILITY_LEVEL)
end
@@ -77,9 +97,16 @@ describe SelfMonitoring::Project::CreateService do
end
it 'creates project with correct name and description' do
+ path = 'administration/monitoring/gitlab_instance_administration_project/index'
+ docs_path = Rails.application.routes.url_helpers.help_page_path(path)
+
expect(result[:status]).to eq(:success)
expect(project.name).to eq(described_class::PROJECT_NAME)
- expect(project.description).to eq(described_class::PROJECT_DESCRIPTION)
+ expect(project.description).to eq(
+ 'This project is automatically generated and will be used to help monitor this GitLab instance. ' \
+ "[More information](#{docs_path})"
+ )
+ expect(File).to exist("doc/#{path}.md")
end
it 'adds all admins as maintainers' do
@@ -105,19 +132,30 @@ describe SelfMonitoring::Project::CreateService do
it 'returns error when saving project ID fails' do
allow(application_setting).to receive(:update) { false }
- expect(result[:status]).to eq(:error)
- expect(result[:failed_step]).to eq(:save_project_id)
- expect(result[:message]).to eq('Could not save project ID')
+ expect { result }.to raise_error(StandardError, 'Could not save project ID')
end
- it 'does not fail when a project already exists' do
- expect(result[:status]).to eq(:success)
+ context 'when project already exists' do
+ let(:existing_group) { create(:group) }
+ let(:existing_project) { create(:project, namespace: existing_group) }
+
+ before do
+ admin1 = create(:user, :admin)
+ admin2 = create(:user, :admin)
+
+ existing_group.add_owner(user)
+ existing_group.add_users([admin1, admin2], Gitlab::Access::MAINTAINER)
+
+ application_setting.instance_administration_project_id = existing_project.id
+ end
- second_result = subject.execute
+ it 'does not fail' do
+ expect(subject).to receive(:log_error).and_call_original
+ expect(result[:status]).to eq(:success)
- expect(second_result[:status]).to eq(:success)
- expect(second_result[:project]).to eq(project)
- expect(second_result[:group]).to eq(group)
+ expect(Project.count).to eq(1)
+ expect(Group.count).to eq(1)
+ end
end
context 'when local requests from hooks and services are not allowed' do
@@ -138,8 +176,11 @@ describe SelfMonitoring::Project::CreateService do
end
context 'with non default prometheus address' do
- before do
- prometheus_settings.listen_address = 'https://localhost:9090'
+ let(:prometheus_settings) do
+ {
+ enable: true,
+ listen_address: 'https://localhost:9090'
+ }
end
it_behaves_like 'has prometheus service', 'https://localhost:9090'
@@ -156,9 +197,23 @@ describe SelfMonitoring::Project::CreateService do
end
end
- context 'when prometheus setting is disabled in gitlab.yml' do
+ context 'when prometheus setting is nil' do
before do
- prometheus_settings.enable = false
+ stub_config(prometheus: nil)
+ end
+
+ it 'does not fail' do
+ expect(result).to include(status: :success)
+ expect(project.prometheus_service).to be_nil
+ end
+ end
+
+ context 'when prometheus setting is disabled in gitlab.yml' do
+ let(:prometheus_settings) do
+ {
+ enable: false,
+ listen_address: 'http://localhost:9090'
+ }
end
it 'does not configure prometheus' do
@@ -168,9 +223,7 @@ describe SelfMonitoring::Project::CreateService do
end
context 'when prometheus listen address is blank in gitlab.yml' do
- before do
- prometheus_settings.listen_address = ''
- end
+ let(:prometheus_settings) { { enable: true, listen_address: '' } }
it 'does not configure prometheus' do
expect(result).to include(status: :success)
@@ -192,11 +245,7 @@ describe SelfMonitoring::Project::CreateService do
it 'returns error' do
expect(subject).to receive(:log_error).and_call_original
- expect(result).to eq({
- status: :error,
- message: 'Could not create project',
- failed_step: :create_project
- })
+ expect { result }.to raise_error(StandardError, 'Could not create project')
end
end
@@ -207,26 +256,21 @@ describe SelfMonitoring::Project::CreateService do
it 'returns error' do
expect(subject).to receive(:log_error).and_call_original
- expect(result).to eq({
- status: :error,
- message: 'Could not add admins as members',
- failed_step: :add_group_members
- })
+ expect { result }.to raise_error(StandardError, 'Could not add admins as members')
end
end
context 'when prometheus manual configuration cannot be saved' do
- before do
- prometheus_settings.listen_address = 'httpinvalid://localhost:9090'
+ let(:prometheus_settings) do
+ {
+ enable: true,
+ listen_address: 'httpinvalid://localhost:9090'
+ }
end
it 'returns error' do
expect(subject).to receive(:log_error).and_call_original
- expect(result).to eq(
- status: :error,
- message: 'Could not save prometheus manual configuration',
- failed_step: :add_prometheus_manual_configuration
- )
+ expect { result }.to raise_error(StandardError, 'Could not save prometheus manual configuration')
end
end
end
diff --git a/spec/lib/gitlab/database_spec.rb b/spec/lib/gitlab/database_spec.rb
index 77e58b6d5c7..8d37de32179 100644
--- a/spec/lib/gitlab/database_spec.rb
+++ b/spec/lib/gitlab/database_spec.rb
@@ -347,6 +347,17 @@ describe Gitlab::Database do
pool.disconnect!
end
end
+
+ it 'allows setting of a custom hostname and port' do
+ pool = described_class.create_connection_pool(5, '127.0.0.1', 5432)
+
+ begin
+ expect(pool.spec.config[:host]).to eq('127.0.0.1')
+ expect(pool.spec.config[:port]).to eq(5432)
+ ensure
+ pool.disconnect!
+ end
+ end
end
describe '.cached_column_exists?' do
diff --git a/spec/lib/gitlab/fogbugz_import/project_creator_spec.rb b/spec/lib/gitlab/fogbugz_import/project_creator_spec.rb
new file mode 100644
index 00000000000..503fe897e29
--- /dev/null
+++ b/spec/lib/gitlab/fogbugz_import/project_creator_spec.rb
@@ -0,0 +1,29 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Gitlab::FogbugzImport::ProjectCreator do
+ let(:user) { create(:user) }
+
+ let(:repo) do
+ instance_double(Gitlab::FogbugzImport::Repository,
+ name: 'Vim',
+ safe_name: 'vim',
+ path: 'vim',
+ raw_data: '')
+ end
+
+ let(:uri) { 'https://testing.fogbugz.com' }
+ let(:token) { 'token' }
+ let(:fb_session) { { uri: uri, token: token } }
+ let(:project_creator) { described_class.new(repo, fb_session, user.namespace, user) }
+
+ subject do
+ project_creator.execute
+ end
+
+ it 'creates project with private visibility level' do
+ expect(subject.persisted?).to eq(true)
+ expect(subject.visibility_level).to eq(Gitlab::VisibilityLevel::PRIVATE)
+ end
+end
diff --git a/spec/lib/gitlab/gitaly_client_spec.rb b/spec/lib/gitlab/gitaly_client_spec.rb
index e9fb6c0125c..99d563e03ec 100644
--- a/spec/lib/gitlab/gitaly_client_spec.rb
+++ b/spec/lib/gitlab/gitaly_client_spec.rb
@@ -27,6 +27,16 @@ describe Gitlab::GitalyClient do
end
end
+ describe '.filesystem_id' do
+ it 'returns an empty string when the storage is not found in the response' do
+ response = double("response")
+ allow(response).to receive(:storage_statuses).and_return([])
+ allow_any_instance_of(Gitlab::GitalyClient::ServerService).to receive(:info).and_return(response)
+
+ expect(described_class.filesystem_id('default')).to eq(nil)
+ end
+ end
+
describe '.stub_class' do
it 'returns the gRPC health check stub' do
expect(described_class.stub_class(:health_check)).to eq(::Grpc::Health::V1::Health::Stub)
diff --git a/spec/lib/gitlab/graphql/authorize/authorize_field_service_spec.rb b/spec/lib/gitlab/graphql/authorize/authorize_field_service_spec.rb
index d60d1b7559a..7a7ae373058 100644
--- a/spec/lib/gitlab/graphql/authorize/authorize_field_service_spec.rb
+++ b/spec/lib/gitlab/graphql/authorize/authorize_field_service_spec.rb
@@ -30,7 +30,10 @@ describe Gitlab::Graphql::Authorize::AuthorizeFieldService do
describe '#authorized_resolve' do
let(:presented_object) { double('presented object') }
let(:presented_type) { double('parent type', object: presented_object) }
- subject(:resolved) { service.authorized_resolve.call(presented_type, {}, { current_user: current_user }) }
+ let(:query_type) { GraphQL::ObjectType.new }
+ let(:schema) { GraphQL::Schema.define(query: query_type, mutation: nil)}
+ let(:context) { GraphQL::Query::Context.new(query: OpenStruct.new(schema: schema), values: { current_user: current_user }, object: nil) }
+ subject(:resolved) { service.authorized_resolve.call(presented_type, {}, context) }
context 'scalar types' do
shared_examples 'checking permissions on the presented object' do
diff --git a/spec/lib/gitlab/graphql/loaders/batch_root_storage_statistics_loader_spec.rb b/spec/lib/gitlab/graphql/loaders/batch_root_storage_statistics_loader_spec.rb
new file mode 100644
index 00000000000..38931f7ab5e
--- /dev/null
+++ b/spec/lib/gitlab/graphql/loaders/batch_root_storage_statistics_loader_spec.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Gitlab::Graphql::Loaders::BatchRootStorageStatisticsLoader do
+ describe '#find' do
+ it 'only queries once for project statistics' do
+ stats = create_list(:namespace_root_storage_statistics, 2)
+ namespace1 = stats.first.namespace
+ namespace2 = stats.last.namespace
+
+ expect do
+ described_class.new(namespace1.id).find
+ described_class.new(namespace2.id).find
+ end.not_to exceed_query_limit(1)
+ end
+ end
+end
diff --git a/spec/lib/gitlab/graphql/markdown_field_spec.rb b/spec/lib/gitlab/graphql/markdown_field_spec.rb
index a8566aa8e1c..866a20801d3 100644
--- a/spec/lib/gitlab/graphql/markdown_field_spec.rb
+++ b/spec/lib/gitlab/graphql/markdown_field_spec.rb
@@ -30,17 +30,20 @@ describe Gitlab::Graphql::MarkdownField do
let(:note) { build(:note, note: '# Markdown!') }
let(:thing_with_markdown) { double('markdown thing', object: note) }
let(:expected_markdown) { '<h1 data-sourcepos="1:1-1:11" dir="auto">Markdown!</h1>' }
+ let(:query_type) { GraphQL::ObjectType.new }
+ let(:schema) { GraphQL::Schema.define(query: query_type, mutation: nil)}
+ let(:context) { GraphQL::Query::Context.new(query: OpenStruct.new(schema: schema), values: nil, object: nil) }
it 'renders markdown from the same property as the field name without the `_html` suffix' do
field = class_with_markdown_field(:note_html, null: false).fields['noteHtml']
- expect(field.to_graphql.resolve(thing_with_markdown, {}, {})).to eq(expected_markdown)
+ expect(field.to_graphql.resolve(thing_with_markdown, {}, context)).to eq(expected_markdown)
end
it 'renders markdown from a specific property when a `method` argument is passed' do
field = class_with_markdown_field(:test_html, null: false, method: :note).fields['testHtml']
- expect(field.to_graphql.resolve(thing_with_markdown, {}, {})).to eq(expected_markdown)
+ expect(field.to_graphql.resolve(thing_with_markdown, {}, context)).to eq(expected_markdown)
end
end
end
diff --git a/spec/lib/gitlab/legacy_github_import/release_formatter_spec.rb b/spec/lib/gitlab/legacy_github_import/release_formatter_spec.rb
index 534cf219520..2cf4b367c0b 100644
--- a/spec/lib/gitlab/legacy_github_import/release_formatter_spec.rb
+++ b/spec/lib/gitlab/legacy_github_import/release_formatter_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::LegacyGithubImport::ReleaseFormatter do
diff --git a/spec/lib/gitlab/legacy_github_import/user_formatter_spec.rb b/spec/lib/gitlab/legacy_github_import/user_formatter_spec.rb
index 3cd096eb0ad..919847fe061 100644
--- a/spec/lib/gitlab/legacy_github_import/user_formatter_spec.rb
+++ b/spec/lib/gitlab/legacy_github_import/user_formatter_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::LegacyGithubImport::UserFormatter do
diff --git a/spec/lib/gitlab/legacy_github_import/wiki_formatter_spec.rb b/spec/lib/gitlab/legacy_github_import/wiki_formatter_spec.rb
index 7519707293c..639fb9d80eb 100644
--- a/spec/lib/gitlab/legacy_github_import/wiki_formatter_spec.rb
+++ b/spec/lib/gitlab/legacy_github_import/wiki_formatter_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::LegacyGithubImport::WikiFormatter do
diff --git a/spec/lib/gitlab/loop_helpers_spec.rb b/spec/lib/gitlab/loop_helpers_spec.rb
index e17a0342d64..7e59b41d5b9 100644
--- a/spec/lib/gitlab/loop_helpers_spec.rb
+++ b/spec/lib/gitlab/loop_helpers_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::LoopHelpers do
diff --git a/spec/lib/gitlab/manifest_import/manifest_spec.rb b/spec/lib/gitlab/manifest_import/manifest_spec.rb
index ded93e23c08..c1135f710ea 100644
--- a/spec/lib/gitlab/manifest_import/manifest_spec.rb
+++ b/spec/lib/gitlab/manifest_import/manifest_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::ManifestImport::Manifest do
diff --git a/spec/lib/gitlab/manifest_import/project_creator_spec.rb b/spec/lib/gitlab/manifest_import/project_creator_spec.rb
index a7487972f51..a8cfcfb41d3 100644
--- a/spec/lib/gitlab/manifest_import/project_creator_spec.rb
+++ b/spec/lib/gitlab/manifest_import/project_creator_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::ManifestImport::ProjectCreator do
diff --git a/spec/lib/gitlab/markup_helper_spec.rb b/spec/lib/gitlab/markup_helper_spec.rb
index 09e518ff989..b93538cae5a 100644
--- a/spec/lib/gitlab/markup_helper_spec.rb
+++ b/spec/lib/gitlab/markup_helper_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::MarkupHelper do
diff --git a/spec/lib/gitlab/metrics/background_transaction_spec.rb b/spec/lib/gitlab/metrics/background_transaction_spec.rb
index 17445fe6de5..d87d2c839ad 100644
--- a/spec/lib/gitlab/metrics/background_transaction_spec.rb
+++ b/spec/lib/gitlab/metrics/background_transaction_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Metrics::BackgroundTransaction do
diff --git a/spec/lib/gitlab/metrics/delta_spec.rb b/spec/lib/gitlab/metrics/delta_spec.rb
index 718387cdee1..9bb011dc8fc 100644
--- a/spec/lib/gitlab/metrics/delta_spec.rb
+++ b/spec/lib/gitlab/metrics/delta_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Metrics::Delta do
diff --git a/spec/lib/gitlab/metrics/instrumentation_spec.rb b/spec/lib/gitlab/metrics/instrumentation_spec.rb
index 977bc250049..0e2f274f157 100644
--- a/spec/lib/gitlab/metrics/instrumentation_spec.rb
+++ b/spec/lib/gitlab/metrics/instrumentation_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Metrics::Instrumentation do
diff --git a/spec/lib/gitlab/metrics/method_call_spec.rb b/spec/lib/gitlab/metrics/method_call_spec.rb
index d9379cfe674..3b5e04e2df5 100644
--- a/spec/lib/gitlab/metrics/method_call_spec.rb
+++ b/spec/lib/gitlab/metrics/method_call_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Metrics::MethodCall do
diff --git a/spec/lib/gitlab/metrics/methods_spec.rb b/spec/lib/gitlab/metrics/methods_spec.rb
index 9d41ed2442b..bca94deb1d8 100644
--- a/spec/lib/gitlab/metrics/methods_spec.rb
+++ b/spec/lib/gitlab/metrics/methods_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Metrics::Methods do
diff --git a/spec/lib/gitlab/metrics/metric_spec.rb b/spec/lib/gitlab/metrics/metric_spec.rb
index d240b8a01fd..611b59231ba 100644
--- a/spec/lib/gitlab/metrics/metric_spec.rb
+++ b/spec/lib/gitlab/metrics/metric_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Metrics::Metric do
diff --git a/spec/lib/gitlab/metrics/prometheus_spec.rb b/spec/lib/gitlab/metrics/prometheus_spec.rb
index 3d4dd5fdf01..b37624982e2 100644
--- a/spec/lib/gitlab/metrics/prometheus_spec.rb
+++ b/spec/lib/gitlab/metrics/prometheus_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Metrics::Prometheus, :prometheus do
diff --git a/spec/lib/gitlab/metrics/rack_middleware_spec.rb b/spec/lib/gitlab/metrics/rack_middleware_spec.rb
index b84387204ee..1c1681cc5ab 100644
--- a/spec/lib/gitlab/metrics/rack_middleware_spec.rb
+++ b/spec/lib/gitlab/metrics/rack_middleware_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Metrics::RackMiddleware do
diff --git a/spec/lib/gitlab/metrics/requests_rack_middleware_spec.rb b/spec/lib/gitlab/metrics/requests_rack_middleware_spec.rb
index ebe66948a91..c29db3a93ec 100644
--- a/spec/lib/gitlab/metrics/requests_rack_middleware_spec.rb
+++ b/spec/lib/gitlab/metrics/requests_rack_middleware_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Metrics::RequestsRackMiddleware do
diff --git a/spec/lib/gitlab/metrics/samplers/influx_sampler_spec.rb b/spec/lib/gitlab/metrics/samplers/influx_sampler_spec.rb
index 2923048f742..2d4b27a6ac1 100644
--- a/spec/lib/gitlab/metrics/samplers/influx_sampler_spec.rb
+++ b/spec/lib/gitlab/metrics/samplers/influx_sampler_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Metrics::Samplers::InfluxSampler do
diff --git a/spec/lib/gitlab/metrics/samplers/ruby_sampler_spec.rb b/spec/lib/gitlab/metrics/samplers/ruby_sampler_spec.rb
index 5005a5d9ebc..8c4071a7ed1 100644
--- a/spec/lib/gitlab/metrics/samplers/ruby_sampler_spec.rb
+++ b/spec/lib/gitlab/metrics/samplers/ruby_sampler_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Metrics::Samplers::RubySampler do
diff --git a/spec/lib/gitlab/metrics/samplers/unicorn_sampler_spec.rb b/spec/lib/gitlab/metrics/samplers/unicorn_sampler_spec.rb
index 4b697b2ba0f..cdfd95e3885 100644
--- a/spec/lib/gitlab/metrics/samplers/unicorn_sampler_spec.rb
+++ b/spec/lib/gitlab/metrics/samplers/unicorn_sampler_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Metrics::Samplers::UnicornSampler do
diff --git a/spec/lib/gitlab/metrics/sidekiq_metrics_exporter_spec.rb b/spec/lib/gitlab/metrics/sidekiq_metrics_exporter_spec.rb
index 61eb059a731..9eea3eb79dc 100644
--- a/spec/lib/gitlab/metrics/sidekiq_metrics_exporter_spec.rb
+++ b/spec/lib/gitlab/metrics/sidekiq_metrics_exporter_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Metrics::SidekiqMetricsExporter do
diff --git a/spec/lib/gitlab/metrics/sidekiq_middleware_spec.rb b/spec/lib/gitlab/metrics/sidekiq_middleware_spec.rb
index ae1d8b47fe9..bb95d5ab2ad 100644
--- a/spec/lib/gitlab/metrics/sidekiq_middleware_spec.rb
+++ b/spec/lib/gitlab/metrics/sidekiq_middleware_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Metrics::SidekiqMiddleware do
diff --git a/spec/lib/gitlab/metrics/subscribers/action_view_spec.rb b/spec/lib/gitlab/metrics/subscribers/action_view_spec.rb
index 9f3af1acef7..25c0e7b695a 100644
--- a/spec/lib/gitlab/metrics/subscribers/action_view_spec.rb
+++ b/spec/lib/gitlab/metrics/subscribers/action_view_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Metrics::Subscribers::ActionView do
diff --git a/spec/lib/gitlab/metrics/subscribers/active_record_spec.rb b/spec/lib/gitlab/metrics/subscribers/active_record_spec.rb
index ee6d6fc961f..1624cea8bda 100644
--- a/spec/lib/gitlab/metrics/subscribers/active_record_spec.rb
+++ b/spec/lib/gitlab/metrics/subscribers/active_record_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Metrics::Subscribers::ActiveRecord do
diff --git a/spec/lib/gitlab/metrics/subscribers/rails_cache_spec.rb b/spec/lib/gitlab/metrics/subscribers/rails_cache_spec.rb
index e04056b3450..ab0d89b2683 100644
--- a/spec/lib/gitlab/metrics/subscribers/rails_cache_spec.rb
+++ b/spec/lib/gitlab/metrics/subscribers/rails_cache_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Metrics::Subscribers::RailsCache do
diff --git a/spec/lib/gitlab/metrics/system_spec.rb b/spec/lib/gitlab/metrics/system_spec.rb
index 3b434a02f63..6d2764a06f2 100644
--- a/spec/lib/gitlab/metrics/system_spec.rb
+++ b/spec/lib/gitlab/metrics/system_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Metrics::System do
diff --git a/spec/lib/gitlab/metrics/web_transaction_spec.rb b/spec/lib/gitlab/metrics/web_transaction_spec.rb
index 0b3b23e930f..2b35f07cc0d 100644
--- a/spec/lib/gitlab/metrics/web_transaction_spec.rb
+++ b/spec/lib/gitlab/metrics/web_transaction_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Metrics::WebTransaction do
diff --git a/spec/lib/gitlab/metrics_spec.rb b/spec/lib/gitlab/metrics_spec.rb
index 03c185ddc07..f0ba12c1cd0 100644
--- a/spec/lib/gitlab/metrics_spec.rb
+++ b/spec/lib/gitlab/metrics_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Metrics do
diff --git a/spec/lib/gitlab/middleware/basic_health_check_spec.rb b/spec/lib/gitlab/middleware/basic_health_check_spec.rb
index 86bdc479b66..07fda691ac8 100644
--- a/spec/lib/gitlab/middleware/basic_health_check_spec.rb
+++ b/spec/lib/gitlab/middleware/basic_health_check_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Middleware::BasicHealthCheck do
diff --git a/spec/lib/gitlab/middleware/multipart_spec.rb b/spec/lib/gitlab/middleware/multipart_spec.rb
index 3f6ada6832a..33797817578 100644
--- a/spec/lib/gitlab/middleware/multipart_spec.rb
+++ b/spec/lib/gitlab/middleware/multipart_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
require 'tempfile'
diff --git a/spec/lib/gitlab/middleware/rails_queue_duration_spec.rb b/spec/lib/gitlab/middleware/rails_queue_duration_spec.rb
index 14f2c3cb86f..31359abdce3 100644
--- a/spec/lib/gitlab/middleware/rails_queue_duration_spec.rb
+++ b/spec/lib/gitlab/middleware/rails_queue_duration_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Middleware::RailsQueueDuration do
diff --git a/spec/lib/gitlab/middleware/read_only_spec.rb b/spec/lib/gitlab/middleware/read_only_spec.rb
index 24d49a049b6..d2c8f4ab0bd 100644
--- a/spec/lib/gitlab/middleware/read_only_spec.rb
+++ b/spec/lib/gitlab/middleware/read_only_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Middleware::ReadOnly do
diff --git a/spec/lib/gitlab/middleware/release_env_spec.rb b/spec/lib/gitlab/middleware/release_env_spec.rb
index 5e3aa877409..3ca40f4ebd0 100644
--- a/spec/lib/gitlab/middleware/release_env_spec.rb
+++ b/spec/lib/gitlab/middleware/release_env_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Middleware::ReleaseEnv do
diff --git a/spec/lib/gitlab/multi_collection_paginator_spec.rb b/spec/lib/gitlab/multi_collection_paginator_spec.rb
index 28cd704b05a..f2049884b83 100644
--- a/spec/lib/gitlab/multi_collection_paginator_spec.rb
+++ b/spec/lib/gitlab/multi_collection_paginator_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::MultiCollectionPaginator do
diff --git a/spec/lib/gitlab/object_hierarchy_spec.rb b/spec/lib/gitlab/object_hierarchy_spec.rb
index bfd456cdd7e..b16eccbcb2c 100644
--- a/spec/lib/gitlab/object_hierarchy_spec.rb
+++ b/spec/lib/gitlab/object_hierarchy_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::ObjectHierarchy do
diff --git a/spec/lib/gitlab/octokit/middleware_spec.rb b/spec/lib/gitlab/octokit/middleware_spec.rb
index 43f6d13f7ba..8aa6d17ac9e 100644
--- a/spec/lib/gitlab/octokit/middleware_spec.rb
+++ b/spec/lib/gitlab/octokit/middleware_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Octokit::Middleware do
diff --git a/spec/lib/gitlab/omniauth_initializer_spec.rb b/spec/lib/gitlab/omniauth_initializer_spec.rb
index ef5c93e5c6b..99684bb2ab2 100644
--- a/spec/lib/gitlab/omniauth_initializer_spec.rb
+++ b/spec/lib/gitlab/omniauth_initializer_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::OmniauthInitializer do
diff --git a/spec/lib/gitlab/optimistic_locking_spec.rb b/spec/lib/gitlab/optimistic_locking_spec.rb
index 6fdf61ee0a7..9dfcb775dfa 100644
--- a/spec/lib/gitlab/optimistic_locking_spec.rb
+++ b/spec/lib/gitlab/optimistic_locking_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::OptimisticLocking do
diff --git a/spec/lib/gitlab/other_markup_spec.rb b/spec/lib/gitlab/other_markup_spec.rb
index e26f39e193e..b5cf5b0999d 100644
--- a/spec/lib/gitlab/other_markup_spec.rb
+++ b/spec/lib/gitlab/other_markup_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::OtherMarkup do
diff --git a/spec/lib/gitlab/otp_key_rotator_spec.rb b/spec/lib/gitlab/otp_key_rotator_spec.rb
index 6e6e9ce29ac..f5a567d5ea0 100644
--- a/spec/lib/gitlab/otp_key_rotator_spec.rb
+++ b/spec/lib/gitlab/otp_key_rotator_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::OtpKeyRotator do
diff --git a/spec/lib/gitlab/pages_client_spec.rb b/spec/lib/gitlab/pages_client_spec.rb
index da6d26f4aee..84381843221 100644
--- a/spec/lib/gitlab/pages_client_spec.rb
+++ b/spec/lib/gitlab/pages_client_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::PagesClient do
diff --git a/spec/lib/gitlab/path_regex_spec.rb b/spec/lib/gitlab/path_regex_spec.rb
index 84b2e2dc823..7dcdad7ff92 100644
--- a/spec/lib/gitlab/path_regex_spec.rb
+++ b/spec/lib/gitlab/path_regex_spec.rb
@@ -1,4 +1,6 @@
# coding: utf-8
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::PathRegex do
diff --git a/spec/lib/gitlab/performance_bar_spec.rb b/spec/lib/gitlab/performance_bar_spec.rb
index 71c109db1f1..8d8ac2aebbe 100644
--- a/spec/lib/gitlab/performance_bar_spec.rb
+++ b/spec/lib/gitlab/performance_bar_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::PerformanceBar do
diff --git a/spec/lib/gitlab/phabricator_import/importer_spec.rb b/spec/lib/gitlab/phabricator_import/importer_spec.rb
index bf14010a187..99a6e4dad6b 100644
--- a/spec/lib/gitlab/phabricator_import/importer_spec.rb
+++ b/spec/lib/gitlab/phabricator_import/importer_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::PhabricatorImport::Importer do
diff --git a/spec/lib/gitlab/phabricator_import/user_finder_spec.rb b/spec/lib/gitlab/phabricator_import/user_finder_spec.rb
index 096321cda5f..918ff28c8f5 100644
--- a/spec/lib/gitlab/phabricator_import/user_finder_spec.rb
+++ b/spec/lib/gitlab/phabricator_import/user_finder_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::PhabricatorImport::UserFinder, :clean_gitlab_redis_cache do
diff --git a/spec/lib/gitlab/phabricator_import/worker_state_spec.rb b/spec/lib/gitlab/phabricator_import/worker_state_spec.rb
index a44947445c9..b6f2524a9d0 100644
--- a/spec/lib/gitlab/phabricator_import/worker_state_spec.rb
+++ b/spec/lib/gitlab/phabricator_import/worker_state_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::PhabricatorImport::WorkerState, :clean_gitlab_redis_shared_state do
diff --git a/spec/lib/gitlab/plugin_spec.rb b/spec/lib/gitlab/plugin_spec.rb
index 33dd4f79130..a8ddd774f3f 100644
--- a/spec/lib/gitlab/plugin_spec.rb
+++ b/spec/lib/gitlab/plugin_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Plugin do
diff --git a/spec/lib/gitlab/polling_interval_spec.rb b/spec/lib/gitlab/polling_interval_spec.rb
index eb8e618156b..979164269bd 100644
--- a/spec/lib/gitlab/polling_interval_spec.rb
+++ b/spec/lib/gitlab/polling_interval_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::PollingInterval do
diff --git a/spec/lib/gitlab/popen/runner_spec.rb b/spec/lib/gitlab/popen/runner_spec.rb
index 2e2cb4ca28f..de19106eaee 100644
--- a/spec/lib/gitlab/popen/runner_spec.rb
+++ b/spec/lib/gitlab/popen/runner_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Popen::Runner do
diff --git a/spec/lib/gitlab/popen_spec.rb b/spec/lib/gitlab/popen_spec.rb
index c1b84e9f077..29afd9df74e 100644
--- a/spec/lib/gitlab/popen_spec.rb
+++ b/spec/lib/gitlab/popen_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Popen do
diff --git a/spec/lib/gitlab/profiler_spec.rb b/spec/lib/gitlab/profiler_spec.rb
index 5af52db7a1f..a19392f4bcb 100644
--- a/spec/lib/gitlab/profiler_spec.rb
+++ b/spec/lib/gitlab/profiler_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Profiler do
diff --git a/spec/lib/gitlab/project_authorizations_spec.rb b/spec/lib/gitlab/project_authorizations_spec.rb
index 75e2d5e1319..82ccb42f8a6 100644
--- a/spec/lib/gitlab/project_authorizations_spec.rb
+++ b/spec/lib/gitlab/project_authorizations_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::ProjectAuthorizations do
diff --git a/spec/lib/gitlab/project_search_results_spec.rb b/spec/lib/gitlab/project_search_results_spec.rb
index c7462500c82..0dbfcf96124 100644
--- a/spec/lib/gitlab/project_search_results_spec.rb
+++ b/spec/lib/gitlab/project_search_results_spec.rb
@@ -1,4 +1,6 @@
# coding: utf-8
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::ProjectSearchResults do
diff --git a/spec/lib/gitlab/project_template_spec.rb b/spec/lib/gitlab/project_template_spec.rb
index c7c82d07508..83acd979a80 100644
--- a/spec/lib/gitlab/project_template_spec.rb
+++ b/spec/lib/gitlab/project_template_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::ProjectTemplate do
diff --git a/spec/lib/gitlab/project_transfer_spec.rb b/spec/lib/gitlab/project_transfer_spec.rb
index 0b9b1f537b5..d54817ea02b 100644
--- a/spec/lib/gitlab/project_transfer_spec.rb
+++ b/spec/lib/gitlab/project_transfer_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::ProjectTransfer do
diff --git a/spec/lib/gitlab/prometheus/additional_metrics_parser_spec.rb b/spec/lib/gitlab/prometheus/additional_metrics_parser_spec.rb
index 1a108003bc2..3f97a69b5eb 100644
--- a/spec/lib/gitlab/prometheus/additional_metrics_parser_spec.rb
+++ b/spec/lib/gitlab/prometheus/additional_metrics_parser_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Prometheus::AdditionalMetricsParser do
diff --git a/spec/lib/gitlab/prometheus/queries/additional_metrics_deployment_query_spec.rb b/spec/lib/gitlab/prometheus/queries/additional_metrics_deployment_query_spec.rb
index c7169717fc1..4bdc57c8c04 100644
--- a/spec/lib/gitlab/prometheus/queries/additional_metrics_deployment_query_spec.rb
+++ b/spec/lib/gitlab/prometheus/queries/additional_metrics_deployment_query_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Prometheus::Queries::AdditionalMetricsDeploymentQuery do
diff --git a/spec/lib/gitlab/prometheus/queries/additional_metrics_environment_query_spec.rb b/spec/lib/gitlab/prometheus/queries/additional_metrics_environment_query_spec.rb
index a6589f0c0a3..35dbdd55cfa 100644
--- a/spec/lib/gitlab/prometheus/queries/additional_metrics_environment_query_spec.rb
+++ b/spec/lib/gitlab/prometheus/queries/additional_metrics_environment_query_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Prometheus::Queries::AdditionalMetricsEnvironmentQuery do
diff --git a/spec/lib/gitlab/prometheus/queries/deployment_query_spec.rb b/spec/lib/gitlab/prometheus/queries/deployment_query_spec.rb
index ffe3ad85baa..0ad2de218fe 100644
--- a/spec/lib/gitlab/prometheus/queries/deployment_query_spec.rb
+++ b/spec/lib/gitlab/prometheus/queries/deployment_query_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Prometheus::Queries::DeploymentQuery do
diff --git a/spec/lib/gitlab/prometheus/queries/matched_metric_query_spec.rb b/spec/lib/gitlab/prometheus/queries/matched_metric_query_spec.rb
index 936447b8474..35034d814bf 100644
--- a/spec/lib/gitlab/prometheus/queries/matched_metric_query_spec.rb
+++ b/spec/lib/gitlab/prometheus/queries/matched_metric_query_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Prometheus::Queries::MatchedMetricQuery do
diff --git a/spec/lib/gitlab/prometheus_client_spec.rb b/spec/lib/gitlab/prometheus_client_spec.rb
index 0a4e8dbced5..86a1c14ed3f 100644
--- a/spec/lib/gitlab/prometheus_client_spec.rb
+++ b/spec/lib/gitlab/prometheus_client_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::PrometheusClient do
diff --git a/spec/lib/gitlab/query_limiting/active_support_subscriber_spec.rb b/spec/lib/gitlab/query_limiting/active_support_subscriber_spec.rb
index f8faeffb935..2db6d2fb60f 100644
--- a/spec/lib/gitlab/query_limiting/active_support_subscriber_spec.rb
+++ b/spec/lib/gitlab/query_limiting/active_support_subscriber_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::QueryLimiting::ActiveSupportSubscriber do
diff --git a/spec/lib/gitlab/query_limiting/middleware_spec.rb b/spec/lib/gitlab/query_limiting/middleware_spec.rb
index a04bcdecb4b..fb1c30118c2 100644
--- a/spec/lib/gitlab/query_limiting/middleware_spec.rb
+++ b/spec/lib/gitlab/query_limiting/middleware_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::QueryLimiting::Middleware do
diff --git a/spec/lib/gitlab/query_limiting/transaction_spec.rb b/spec/lib/gitlab/query_limiting/transaction_spec.rb
index b72b8574174..39d5a575efc 100644
--- a/spec/lib/gitlab/query_limiting/transaction_spec.rb
+++ b/spec/lib/gitlab/query_limiting/transaction_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::QueryLimiting::Transaction do
diff --git a/spec/lib/gitlab/query_limiting_spec.rb b/spec/lib/gitlab/query_limiting_spec.rb
index 42877b1e2dd..f0d0340cd6e 100644
--- a/spec/lib/gitlab/query_limiting_spec.rb
+++ b/spec/lib/gitlab/query_limiting_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::QueryLimiting do
diff --git a/spec/lib/gitlab/quick_actions/command_definition_spec.rb b/spec/lib/gitlab/quick_actions/command_definition_spec.rb
index 21f2c87a755..45b710adf07 100644
--- a/spec/lib/gitlab/quick_actions/command_definition_spec.rb
+++ b/spec/lib/gitlab/quick_actions/command_definition_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::QuickActions::CommandDefinition do
diff --git a/spec/lib/gitlab/quick_actions/dsl_spec.rb b/spec/lib/gitlab/quick_actions/dsl_spec.rb
index 78b9b3804c3..c98c36622f5 100644
--- a/spec/lib/gitlab/quick_actions/dsl_spec.rb
+++ b/spec/lib/gitlab/quick_actions/dsl_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::QuickActions::Dsl do
diff --git a/spec/lib/gitlab/quick_actions/extractor_spec.rb b/spec/lib/gitlab/quick_actions/extractor_spec.rb
index 873bb359d6e..f1acb5b7049 100644
--- a/spec/lib/gitlab/quick_actions/extractor_spec.rb
+++ b/spec/lib/gitlab/quick_actions/extractor_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::QuickActions::Extractor do
diff --git a/spec/lib/gitlab/quick_actions/spend_time_and_date_separator_spec.rb b/spec/lib/gitlab/quick_actions/spend_time_and_date_separator_spec.rb
index 8b58f0b3725..fd149cd1114 100644
--- a/spec/lib/gitlab/quick_actions/spend_time_and_date_separator_spec.rb
+++ b/spec/lib/gitlab/quick_actions/spend_time_and_date_separator_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::QuickActions::SpendTimeAndDateSeparator do
diff --git a/spec/lib/gitlab/quick_actions/substitution_definition_spec.rb b/spec/lib/gitlab/quick_actions/substitution_definition_spec.rb
index 1bb8bc51c96..e4f25bc35a9 100644
--- a/spec/lib/gitlab/quick_actions/substitution_definition_spec.rb
+++ b/spec/lib/gitlab/quick_actions/substitution_definition_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::QuickActions::SubstitutionDefinition do
diff --git a/spec/lib/gitlab/redis/cache_spec.rb b/spec/lib/gitlab/redis/cache_spec.rb
index 5a4f17cfcf6..0718998f981 100644
--- a/spec/lib/gitlab/redis/cache_spec.rb
+++ b/spec/lib/gitlab/redis/cache_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Redis::Cache do
diff --git a/spec/lib/gitlab/redis/queues_spec.rb b/spec/lib/gitlab/redis/queues_spec.rb
index 01ca25635a9..93207b6f469 100644
--- a/spec/lib/gitlab/redis/queues_spec.rb
+++ b/spec/lib/gitlab/redis/queues_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Redis::Queues do
diff --git a/spec/lib/gitlab/redis/shared_state_spec.rb b/spec/lib/gitlab/redis/shared_state_spec.rb
index 24b73745dc5..aa61fd99eb5 100644
--- a/spec/lib/gitlab/redis/shared_state_spec.rb
+++ b/spec/lib/gitlab/redis/shared_state_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Redis::SharedState do
diff --git a/spec/lib/gitlab/redis/wrapper_spec.rb b/spec/lib/gitlab/redis/wrapper_spec.rb
index 0c22a0d62cc..e4cc42130db 100644
--- a/spec/lib/gitlab/redis/wrapper_spec.rb
+++ b/spec/lib/gitlab/redis/wrapper_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Redis::Wrapper do
diff --git a/spec/lib/gitlab/reference_counter_spec.rb b/spec/lib/gitlab/reference_counter_spec.rb
index b2344d1870a..f9361d08faf 100644
--- a/spec/lib/gitlab/reference_counter_spec.rb
+++ b/spec/lib/gitlab/reference_counter_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::ReferenceCounter do
diff --git a/spec/lib/gitlab/regex_spec.rb b/spec/lib/gitlab/regex_spec.rb
index ba295386a55..e19210d8fbf 100644
--- a/spec/lib/gitlab/regex_spec.rb
+++ b/spec/lib/gitlab/regex_spec.rb
@@ -1,4 +1,6 @@
# coding: utf-8
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Regex do
diff --git a/spec/lib/gitlab/repo_path_spec.rb b/spec/lib/gitlab/repo_path_spec.rb
index 8fbda929064..cffd7cc89e7 100644
--- a/spec/lib/gitlab/repo_path_spec.rb
+++ b/spec/lib/gitlab/repo_path_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe ::Gitlab::RepoPath do
diff --git a/spec/lib/gitlab/repository_cache_adapter_spec.rb b/spec/lib/gitlab/repository_cache_adapter_spec.rb
index 04fc24b6205..fd1338b55a6 100644
--- a/spec/lib/gitlab/repository_cache_adapter_spec.rb
+++ b/spec/lib/gitlab/repository_cache_adapter_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::RepositoryCacheAdapter do
diff --git a/spec/lib/gitlab/repository_cache_spec.rb b/spec/lib/gitlab/repository_cache_spec.rb
index 741ee12633f..6a684595eb8 100644
--- a/spec/lib/gitlab/repository_cache_spec.rb
+++ b/spec/lib/gitlab/repository_cache_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::RepositoryCache do
diff --git a/spec/lib/gitlab/repository_set_cache_spec.rb b/spec/lib/gitlab/repository_set_cache_spec.rb
index 9695e13d842..87e51f801e5 100644
--- a/spec/lib/gitlab/repository_set_cache_spec.rb
+++ b/spec/lib/gitlab/repository_set_cache_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::RepositorySetCache, :clean_gitlab_redis_cache do
diff --git a/spec/lib/gitlab/request_context_spec.rb b/spec/lib/gitlab/request_context_spec.rb
index 23e45aff1c5..a744f48da1f 100644
--- a/spec/lib/gitlab/request_context_spec.rb
+++ b/spec/lib/gitlab/request_context_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::RequestContext do
diff --git a/spec/lib/gitlab/request_forgery_protection_spec.rb b/spec/lib/gitlab/request_forgery_protection_spec.rb
index 305de613866..b7a3dc16eff 100644
--- a/spec/lib/gitlab/request_forgery_protection_spec.rb
+++ b/spec/lib/gitlab/request_forgery_protection_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::RequestForgeryProtection, :allow_forgery_protection do
diff --git a/spec/lib/gitlab/request_profiler/profile_spec.rb b/spec/lib/gitlab/request_profiler/profile_spec.rb
index b37ee558e1a..a75f3c66156 100644
--- a/spec/lib/gitlab/request_profiler/profile_spec.rb
+++ b/spec/lib/gitlab/request_profiler/profile_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'fast_spec_helper'
describe Gitlab::RequestProfiler::Profile do
diff --git a/spec/lib/gitlab/request_profiler_spec.rb b/spec/lib/gitlab/request_profiler_spec.rb
index 498c045b6cd..f157189a72d 100644
--- a/spec/lib/gitlab/request_profiler_spec.rb
+++ b/spec/lib/gitlab/request_profiler_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::RequestProfiler do
diff --git a/spec/lib/gitlab/route_map_spec.rb b/spec/lib/gitlab/route_map_spec.rb
index a39c774429e..d5e70b91fb4 100644
--- a/spec/lib/gitlab/route_map_spec.rb
+++ b/spec/lib/gitlab/route_map_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::RouteMap do
diff --git a/spec/lib/gitlab/routing_spec.rb b/spec/lib/gitlab/routing_spec.rb
index 01d5acfc15b..965564cb83b 100644
--- a/spec/lib/gitlab/routing_spec.rb
+++ b/spec/lib/gitlab/routing_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Routing do
diff --git a/spec/lib/gitlab/sanitizers/exif_spec.rb b/spec/lib/gitlab/sanitizers/exif_spec.rb
index bd5f330c7a1..22c5f27dc6d 100644
--- a/spec/lib/gitlab/sanitizers/exif_spec.rb
+++ b/spec/lib/gitlab/sanitizers/exif_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Sanitizers::Exif do
diff --git a/spec/lib/gitlab/sanitizers/svg_spec.rb b/spec/lib/gitlab/sanitizers/svg_spec.rb
index df46a874528..a8c7495376d 100644
--- a/spec/lib/gitlab/sanitizers/svg_spec.rb
+++ b/spec/lib/gitlab/sanitizers/svg_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Sanitizers::SVG do
diff --git a/spec/lib/gitlab/search/found_blob_spec.rb b/spec/lib/gitlab/search/found_blob_spec.rb
index da263bc7523..3496fb29836 100644
--- a/spec/lib/gitlab/search/found_blob_spec.rb
+++ b/spec/lib/gitlab/search/found_blob_spec.rb
@@ -1,4 +1,5 @@
# coding: utf-8
+# frozen_string_literal: true
require 'spec_helper'
@@ -108,7 +109,7 @@ describe Gitlab::Search::FoundBlob do
end
context 'with ISO-8859-1' do
- let(:search_result) { "master:encoding/iso8859.txt\x001\x00\xC4\xFC\nmaster:encoding/iso8859.txt\x002\x00\nmaster:encoding/iso8859.txt\x003\x00foo\n".force_encoding(Encoding::ASCII_8BIT) }
+ let(:search_result) { (+"master:encoding/iso8859.txt\x001\x00\xC4\xFC\nmaster:encoding/iso8859.txt\x002\x00\nmaster:encoding/iso8859.txt\x003\x00foo\n").force_encoding(Encoding::ASCII_8BIT) }
it 'returns results as UTF-8' do
expect(subject.filename).to eq('encoding/iso8859.txt')
diff --git a/spec/lib/gitlab/search/query_spec.rb b/spec/lib/gitlab/search/query_spec.rb
index 2d00428fffa..112e9a59f04 100644
--- a/spec/lib/gitlab/search/query_spec.rb
+++ b/spec/lib/gitlab/search/query_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Search::Query do
diff --git a/spec/lib/gitlab/search_results_spec.rb b/spec/lib/gitlab/search_results_spec.rb
index c287da19343..5621c686b8a 100644
--- a/spec/lib/gitlab/search_results_spec.rb
+++ b/spec/lib/gitlab/search_results_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::SearchResults do
diff --git a/spec/lib/gitlab/sentry_spec.rb b/spec/lib/gitlab/sentry_spec.rb
index a48cc0d128a..9c4f3b8f42e 100644
--- a/spec/lib/gitlab/sentry_spec.rb
+++ b/spec/lib/gitlab/sentry_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Sentry do
diff --git a/spec/lib/gitlab/serializer/ci/variables_spec.rb b/spec/lib/gitlab/serializer/ci/variables_spec.rb
index 1d1fd5b0763..900508420c9 100644
--- a/spec/lib/gitlab/serializer/ci/variables_spec.rb
+++ b/spec/lib/gitlab/serializer/ci/variables_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'fast_spec_helper'
describe Gitlab::Serializer::Ci::Variables do
diff --git a/spec/lib/gitlab/serializer/pagination_spec.rb b/spec/lib/gitlab/serializer/pagination_spec.rb
index c54be78f050..1e7f441f258 100644
--- a/spec/lib/gitlab/serializer/pagination_spec.rb
+++ b/spec/lib/gitlab/serializer/pagination_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Serializer::Pagination do
diff --git a/spec/lib/gitlab/shard_health_cache_spec.rb b/spec/lib/gitlab/shard_health_cache_spec.rb
index e1a69261939..f747849b5e9 100644
--- a/spec/lib/gitlab/shard_health_cache_spec.rb
+++ b/spec/lib/gitlab/shard_health_cache_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::ShardHealthCache, :clean_gitlab_redis_cache do
diff --git a/spec/lib/gitlab/shell_spec.rb b/spec/lib/gitlab/shell_spec.rb
index bce2e754176..0ba16b93ee7 100644
--- a/spec/lib/gitlab/shell_spec.rb
+++ b/spec/lib/gitlab/shell_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
require 'stringio'
diff --git a/spec/lib/gitlab/sherlock/collection_spec.rb b/spec/lib/gitlab/sherlock/collection_spec.rb
index 873ed14f804..bdc89c3d3cf 100644
--- a/spec/lib/gitlab/sherlock/collection_spec.rb
+++ b/spec/lib/gitlab/sherlock/collection_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Sherlock::Collection do
diff --git a/spec/lib/gitlab/sherlock/file_sample_spec.rb b/spec/lib/gitlab/sherlock/file_sample_spec.rb
index 394421504e0..b09ba5c62dc 100644
--- a/spec/lib/gitlab/sherlock/file_sample_spec.rb
+++ b/spec/lib/gitlab/sherlock/file_sample_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Sherlock::FileSample do
diff --git a/spec/lib/gitlab/sherlock/line_profiler_spec.rb b/spec/lib/gitlab/sherlock/line_profiler_spec.rb
index f2f8040fa0b..c1997606839 100644
--- a/spec/lib/gitlab/sherlock/line_profiler_spec.rb
+++ b/spec/lib/gitlab/sherlock/line_profiler_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Sherlock::LineProfiler do
diff --git a/spec/lib/gitlab/sherlock/line_sample_spec.rb b/spec/lib/gitlab/sherlock/line_sample_spec.rb
index 5f02f6a3213..b68e8cc0266 100644
--- a/spec/lib/gitlab/sherlock/line_sample_spec.rb
+++ b/spec/lib/gitlab/sherlock/line_sample_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Sherlock::LineSample do
diff --git a/spec/lib/gitlab/sherlock/location_spec.rb b/spec/lib/gitlab/sherlock/location_spec.rb
index b295a624b35..7b40c84c2d1 100644
--- a/spec/lib/gitlab/sherlock/location_spec.rb
+++ b/spec/lib/gitlab/sherlock/location_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Sherlock::Location do
diff --git a/spec/lib/gitlab/sherlock/middleware_spec.rb b/spec/lib/gitlab/sherlock/middleware_spec.rb
index 2016023df06..8d6e362f622 100644
--- a/spec/lib/gitlab/sherlock/middleware_spec.rb
+++ b/spec/lib/gitlab/sherlock/middleware_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Sherlock::Middleware do
diff --git a/spec/lib/gitlab/sherlock/query_spec.rb b/spec/lib/gitlab/sherlock/query_spec.rb
index 426071c7f92..13c7e6f8f8b 100644
--- a/spec/lib/gitlab/sherlock/query_spec.rb
+++ b/spec/lib/gitlab/sherlock/query_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Sherlock::Query do
diff --git a/spec/lib/gitlab/sherlock/transaction_spec.rb b/spec/lib/gitlab/sherlock/transaction_spec.rb
index 4a14dfbec56..2245c3ee8e2 100644
--- a/spec/lib/gitlab/sherlock/transaction_spec.rb
+++ b/spec/lib/gitlab/sherlock/transaction_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Sherlock::Transaction do
diff --git a/spec/lib/gitlab/sidekiq_config_spec.rb b/spec/lib/gitlab/sidekiq_config_spec.rb
index 0c66d764851..1e8ccb447b1 100644
--- a/spec/lib/gitlab/sidekiq_config_spec.rb
+++ b/spec/lib/gitlab/sidekiq_config_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'rails_helper'
describe Gitlab::SidekiqConfig do
diff --git a/spec/lib/gitlab/sidekiq_logging/json_formatter_spec.rb b/spec/lib/gitlab/sidekiq_logging/json_formatter_spec.rb
index fed9aeba30c..a2cb38ec5b1 100644
--- a/spec/lib/gitlab/sidekiq_logging/json_formatter_spec.rb
+++ b/spec/lib/gitlab/sidekiq_logging/json_formatter_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::SidekiqLogging::JSONFormatter do
diff --git a/spec/lib/gitlab/sidekiq_logging/structured_logger_spec.rb b/spec/lib/gitlab/sidekiq_logging/structured_logger_spec.rb
index c09db4af8d8..1b89c094a6b 100644
--- a/spec/lib/gitlab/sidekiq_logging/structured_logger_spec.rb
+++ b/spec/lib/gitlab/sidekiq_logging/structured_logger_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::SidekiqLogging::StructuredLogger do
diff --git a/spec/lib/gitlab/sidekiq_middleware/memory_killer_spec.rb b/spec/lib/gitlab/sidekiq_middleware/memory_killer_spec.rb
index 1de9a644610..bf3bc8e1add 100644
--- a/spec/lib/gitlab/sidekiq_middleware/memory_killer_spec.rb
+++ b/spec/lib/gitlab/sidekiq_middleware/memory_killer_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::SidekiqMiddleware::MemoryKiller do
diff --git a/spec/lib/gitlab/sidekiq_signals_spec.rb b/spec/lib/gitlab/sidekiq_signals_spec.rb
index 77ecd1840d2..10f1bad32cd 100644
--- a/spec/lib/gitlab/sidekiq_signals_spec.rb
+++ b/spec/lib/gitlab/sidekiq_signals_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::SidekiqSignals do
diff --git a/spec/lib/gitlab/sidekiq_status/client_middleware_spec.rb b/spec/lib/gitlab/sidekiq_status/client_middleware_spec.rb
index 37d9e1d3e6b..1ca8cea66fc 100644
--- a/spec/lib/gitlab/sidekiq_status/client_middleware_spec.rb
+++ b/spec/lib/gitlab/sidekiq_status/client_middleware_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::SidekiqStatus::ClientMiddleware do
diff --git a/spec/lib/gitlab/sidekiq_status/server_middleware_spec.rb b/spec/lib/gitlab/sidekiq_status/server_middleware_spec.rb
index 04e09d3dec8..40bcb49d1d3 100644
--- a/spec/lib/gitlab/sidekiq_status/server_middleware_spec.rb
+++ b/spec/lib/gitlab/sidekiq_status/server_middleware_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::SidekiqStatus::ServerMiddleware do
diff --git a/spec/lib/gitlab/sidekiq_status_spec.rb b/spec/lib/gitlab/sidekiq_status_spec.rb
index 884f27b212c..7b5c75b2f3b 100644
--- a/spec/lib/gitlab/sidekiq_status_spec.rb
+++ b/spec/lib/gitlab/sidekiq_status_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::SidekiqStatus do
diff --git a/spec/lib/gitlab/sidekiq_versioning/manager_spec.rb b/spec/lib/gitlab/sidekiq_versioning/manager_spec.rb
index 7debf70a16f..2aa7d1fd6d8 100644
--- a/spec/lib/gitlab/sidekiq_versioning/manager_spec.rb
+++ b/spec/lib/gitlab/sidekiq_versioning/manager_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::SidekiqVersioning::Manager do
diff --git a/spec/lib/gitlab/sidekiq_versioning_spec.rb b/spec/lib/gitlab/sidekiq_versioning_spec.rb
index fa6d42e730d..dade5961775 100644
--- a/spec/lib/gitlab/sidekiq_versioning_spec.rb
+++ b/spec/lib/gitlab/sidekiq_versioning_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::SidekiqVersioning, :sidekiq, :redis do
diff --git a/spec/lib/gitlab/slash_commands/command_spec.rb b/spec/lib/gitlab/slash_commands/command_spec.rb
index eceacac58af..c4ea8cbf2b1 100644
--- a/spec/lib/gitlab/slash_commands/command_spec.rb
+++ b/spec/lib/gitlab/slash_commands/command_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::SlashCommands::Command do
diff --git a/spec/lib/gitlab/slash_commands/deploy_spec.rb b/spec/lib/gitlab/slash_commands/deploy_spec.rb
index 25f3e8a0409..93a724d8e12 100644
--- a/spec/lib/gitlab/slash_commands/deploy_spec.rb
+++ b/spec/lib/gitlab/slash_commands/deploy_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::SlashCommands::Deploy do
diff --git a/spec/lib/gitlab/slash_commands/issue_move_spec.rb b/spec/lib/gitlab/slash_commands/issue_move_spec.rb
index 9a990e1fad7..962ac3668bc 100644
--- a/spec/lib/gitlab/slash_commands/issue_move_spec.rb
+++ b/spec/lib/gitlab/slash_commands/issue_move_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::SlashCommands::IssueMove, service: true do
diff --git a/spec/lib/gitlab/slash_commands/issue_new_spec.rb b/spec/lib/gitlab/slash_commands/issue_new_spec.rb
index 59de11766d8..90f0518a63e 100644
--- a/spec/lib/gitlab/slash_commands/issue_new_spec.rb
+++ b/spec/lib/gitlab/slash_commands/issue_new_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::SlashCommands::IssueNew do
diff --git a/spec/lib/gitlab/slash_commands/issue_search_spec.rb b/spec/lib/gitlab/slash_commands/issue_search_spec.rb
index 47787307990..b766a9a1361 100644
--- a/spec/lib/gitlab/slash_commands/issue_search_spec.rb
+++ b/spec/lib/gitlab/slash_commands/issue_search_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::SlashCommands::IssueSearch do
diff --git a/spec/lib/gitlab/slash_commands/issue_show_spec.rb b/spec/lib/gitlab/slash_commands/issue_show_spec.rb
index 5c4ba2736ba..e53f79dcd86 100644
--- a/spec/lib/gitlab/slash_commands/issue_show_spec.rb
+++ b/spec/lib/gitlab/slash_commands/issue_show_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::SlashCommands::IssueShow do
diff --git a/spec/lib/gitlab/slash_commands/presenters/access_spec.rb b/spec/lib/gitlab/slash_commands/presenters/access_spec.rb
index ef3d217f7be..286fec892e6 100644
--- a/spec/lib/gitlab/slash_commands/presenters/access_spec.rb
+++ b/spec/lib/gitlab/slash_commands/presenters/access_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::SlashCommands::Presenters::Access do
diff --git a/spec/lib/gitlab/slash_commands/presenters/deploy_spec.rb b/spec/lib/gitlab/slash_commands/presenters/deploy_spec.rb
index d16d122c64e..9c2e9ab982f 100644
--- a/spec/lib/gitlab/slash_commands/presenters/deploy_spec.rb
+++ b/spec/lib/gitlab/slash_commands/presenters/deploy_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::SlashCommands::Presenters::Deploy do
diff --git a/spec/lib/gitlab/slash_commands/presenters/issue_move_spec.rb b/spec/lib/gitlab/slash_commands/presenters/issue_move_spec.rb
index 58c341a284e..56b64d32192 100644
--- a/spec/lib/gitlab/slash_commands/presenters/issue_move_spec.rb
+++ b/spec/lib/gitlab/slash_commands/presenters/issue_move_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::SlashCommands::Presenters::IssueMove do
diff --git a/spec/lib/gitlab/slash_commands/presenters/issue_new_spec.rb b/spec/lib/gitlab/slash_commands/presenters/issue_new_spec.rb
index 76e4bad88fd..f926783fbea 100644
--- a/spec/lib/gitlab/slash_commands/presenters/issue_new_spec.rb
+++ b/spec/lib/gitlab/slash_commands/presenters/issue_new_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::SlashCommands::Presenters::IssueNew do
diff --git a/spec/lib/gitlab/slash_commands/presenters/issue_search_spec.rb b/spec/lib/gitlab/slash_commands/presenters/issue_search_spec.rb
index 5a7ec0685fe..e1c011133c4 100644
--- a/spec/lib/gitlab/slash_commands/presenters/issue_search_spec.rb
+++ b/spec/lib/gitlab/slash_commands/presenters/issue_search_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::SlashCommands::Presenters::IssueSearch do
diff --git a/spec/lib/gitlab/slash_commands/presenters/issue_show_spec.rb b/spec/lib/gitlab/slash_commands/presenters/issue_show_spec.rb
index 8f607d7a9c9..56d6bf1c788 100644
--- a/spec/lib/gitlab/slash_commands/presenters/issue_show_spec.rb
+++ b/spec/lib/gitlab/slash_commands/presenters/issue_show_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::SlashCommands::Presenters::IssueShow do
diff --git a/spec/lib/gitlab/snippet_search_results_spec.rb b/spec/lib/gitlab/snippet_search_results_spec.rb
index 35df38f052b..89d290aaa81 100644
--- a/spec/lib/gitlab/snippet_search_results_spec.rb
+++ b/spec/lib/gitlab/snippet_search_results_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::SnippetSearchResults do
diff --git a/spec/lib/gitlab/sql/cte_spec.rb b/spec/lib/gitlab/sql/cte_spec.rb
index 5d2164491b5..e6194924f5a 100644
--- a/spec/lib/gitlab/sql/cte_spec.rb
+++ b/spec/lib/gitlab/sql/cte_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::SQL::CTE do
diff --git a/spec/lib/gitlab/sql/glob_spec.rb b/spec/lib/gitlab/sql/glob_spec.rb
index 3147b52dcc5..83eed309ecc 100644
--- a/spec/lib/gitlab/sql/glob_spec.rb
+++ b/spec/lib/gitlab/sql/glob_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::SQL::Glob do
diff --git a/spec/lib/gitlab/sql/pattern_spec.rb b/spec/lib/gitlab/sql/pattern_spec.rb
index 98838712eae..31944d51b3c 100644
--- a/spec/lib/gitlab/sql/pattern_spec.rb
+++ b/spec/lib/gitlab/sql/pattern_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::SQL::Pattern do
diff --git a/spec/lib/gitlab/sql/recursive_cte_spec.rb b/spec/lib/gitlab/sql/recursive_cte_spec.rb
index 407a4d8a247..20e36c224b0 100644
--- a/spec/lib/gitlab/sql/recursive_cte_spec.rb
+++ b/spec/lib/gitlab/sql/recursive_cte_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::SQL::RecursiveCTE do
diff --git a/spec/lib/gitlab/sql/union_spec.rb b/spec/lib/gitlab/sql/union_spec.rb
index fe6422c32b6..f8f6da19fa5 100644
--- a/spec/lib/gitlab/sql/union_spec.rb
+++ b/spec/lib/gitlab/sql/union_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::SQL::Union do
diff --git a/spec/lib/gitlab/ssh_public_key_spec.rb b/spec/lib/gitlab/ssh_public_key_spec.rb
index a6ea07e8b6d..f8becb0c796 100644
--- a/spec/lib/gitlab/ssh_public_key_spec.rb
+++ b/spec/lib/gitlab/ssh_public_key_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::SSHPublicKey, lib: true do
diff --git a/spec/lib/gitlab/string_placeholder_replacer_spec.rb b/spec/lib/gitlab/string_placeholder_replacer_spec.rb
index 7a03ea4154c..0295bf1265f 100644
--- a/spec/lib/gitlab/string_placeholder_replacer_spec.rb
+++ b/spec/lib/gitlab/string_placeholder_replacer_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::StringPlaceholderReplacer do
diff --git a/spec/lib/gitlab/string_range_marker_spec.rb b/spec/lib/gitlab/string_range_marker_spec.rb
index 6bc02459dbd..7ed43db3d10 100644
--- a/spec/lib/gitlab/string_range_marker_spec.rb
+++ b/spec/lib/gitlab/string_range_marker_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::StringRangeMarker do
diff --git a/spec/lib/gitlab/string_regex_marker_spec.rb b/spec/lib/gitlab/string_regex_marker_spec.rb
index 37b1298b962..2b19edbe7f9 100644
--- a/spec/lib/gitlab/string_regex_marker_spec.rb
+++ b/spec/lib/gitlab/string_regex_marker_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::StringRegexMarker do
diff --git a/spec/lib/gitlab/tcp_checker_spec.rb b/spec/lib/gitlab/tcp_checker_spec.rb
index 4acf0334496..49f04f269ae 100644
--- a/spec/lib/gitlab/tcp_checker_spec.rb
+++ b/spec/lib/gitlab/tcp_checker_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::TcpChecker do
diff --git a/spec/lib/gitlab/template/finders/global_template_finder_spec.rb b/spec/lib/gitlab/template/finders/global_template_finder_spec.rb
index c7f58fbd2a5..082ffa855b7 100644
--- a/spec/lib/gitlab/template/finders/global_template_finder_spec.rb
+++ b/spec/lib/gitlab/template/finders/global_template_finder_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Template::Finders::GlobalTemplateFinder do
diff --git a/spec/lib/gitlab/template/finders/repo_template_finders_spec.rb b/spec/lib/gitlab/template/finders/repo_template_finders_spec.rb
index e329d55d837..c8f2a37c5d6 100644
--- a/spec/lib/gitlab/template/finders/repo_template_finders_spec.rb
+++ b/spec/lib/gitlab/template/finders/repo_template_finders_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Template::Finders::RepoTemplateFinder do
diff --git a/spec/lib/gitlab/template/gitignore_template_spec.rb b/spec/lib/gitlab/template/gitignore_template_spec.rb
index 97797f42aaa..e8f632889ad 100644
--- a/spec/lib/gitlab/template/gitignore_template_spec.rb
+++ b/spec/lib/gitlab/template/gitignore_template_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Template::GitignoreTemplate do
diff --git a/spec/lib/gitlab/template/gitlab_ci_yml_template_spec.rb b/spec/lib/gitlab/template/gitlab_ci_yml_template_spec.rb
index 5f0a7e925ca..52e100768a7 100644
--- a/spec/lib/gitlab/template/gitlab_ci_yml_template_spec.rb
+++ b/spec/lib/gitlab/template/gitlab_ci_yml_template_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Template::GitlabCiYmlTemplate do
diff --git a/spec/lib/gitlab/template/issue_template_spec.rb b/spec/lib/gitlab/template/issue_template_spec.rb
index 7098499f996..54e46d3a9ec 100644
--- a/spec/lib/gitlab/template/issue_template_spec.rb
+++ b/spec/lib/gitlab/template/issue_template_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Template::IssueTemplate do
diff --git a/spec/lib/gitlab/template/merge_request_template_spec.rb b/spec/lib/gitlab/template/merge_request_template_spec.rb
index bd7ff64aa8a..bbc184d4dfc 100644
--- a/spec/lib/gitlab/template/merge_request_template_spec.rb
+++ b/spec/lib/gitlab/template/merge_request_template_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Template::MergeRequestTemplate do
diff --git a/spec/lib/gitlab/themes_spec.rb b/spec/lib/gitlab/themes_spec.rb
index a8213988f70..e0278eb9c7f 100644
--- a/spec/lib/gitlab/themes_spec.rb
+++ b/spec/lib/gitlab/themes_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Themes, lib: true do
diff --git a/spec/lib/gitlab/tree_summary_spec.rb b/spec/lib/gitlab/tree_summary_spec.rb
index e22f898dc4c..e15463ed0eb 100644
--- a/spec/lib/gitlab/tree_summary_spec.rb
+++ b/spec/lib/gitlab/tree_summary_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::TreeSummary do
diff --git a/spec/lib/gitlab/untrusted_regexp/ruby_syntax_spec.rb b/spec/lib/gitlab/untrusted_regexp/ruby_syntax_spec.rb
index f1882e03581..68402e64012 100644
--- a/spec/lib/gitlab/untrusted_regexp/ruby_syntax_spec.rb
+++ b/spec/lib/gitlab/untrusted_regexp/ruby_syntax_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'fast_spec_helper'
require 'support/shared_examples/malicious_regexp_shared_examples'
require 'support/helpers/stub_feature_flags'
diff --git a/spec/lib/gitlab/untrusted_regexp_spec.rb b/spec/lib/gitlab/untrusted_regexp_spec.rb
index 9d483f13a5e..4cc21e94a83 100644
--- a/spec/lib/gitlab/untrusted_regexp_spec.rb
+++ b/spec/lib/gitlab/untrusted_regexp_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'fast_spec_helper'
require 'support/shared_examples/malicious_regexp_shared_examples'
diff --git a/spec/lib/gitlab/uploads_transfer_spec.rb b/spec/lib/gitlab/uploads_transfer_spec.rb
index 4275e7b015b..16560fc8f12 100644
--- a/spec/lib/gitlab/uploads_transfer_spec.rb
+++ b/spec/lib/gitlab/uploads_transfer_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::UploadsTransfer do
diff --git a/spec/lib/gitlab/url_blocker_spec.rb b/spec/lib/gitlab/url_blocker_spec.rb
index 45d9022abeb..df8a1f82f81 100644
--- a/spec/lib/gitlab/url_blocker_spec.rb
+++ b/spec/lib/gitlab/url_blocker_spec.rb
@@ -1,4 +1,6 @@
# coding: utf-8
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::UrlBlocker do
diff --git a/spec/lib/gitlab/url_builder_spec.rb b/spec/lib/gitlab/url_builder_spec.rb
index bbcb92608d8..08d3c638f9e 100644
--- a/spec/lib/gitlab/url_builder_spec.rb
+++ b/spec/lib/gitlab/url_builder_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::UrlBuilder do
diff --git a/spec/lib/gitlab/url_sanitizer_spec.rb b/spec/lib/gitlab/url_sanitizer_spec.rb
index 7242255d535..b39609c594b 100644
--- a/spec/lib/gitlab/url_sanitizer_spec.rb
+++ b/spec/lib/gitlab/url_sanitizer_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::UrlSanitizer do
diff --git a/spec/lib/gitlab/usage_data_counters/merge_request_counter_spec.rb b/spec/lib/gitlab/usage_data_counters/merge_request_counter_spec.rb
new file mode 100644
index 00000000000..4be4a661260
--- /dev/null
+++ b/spec/lib/gitlab/usage_data_counters/merge_request_counter_spec.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Gitlab::UsageDataCounters::MergeRequestCounter do
+ it_behaves_like 'a redis usage counter', 'Merge Request', :create
+
+ it_behaves_like 'a redis usage counter with totals', :merge_request, create: 5
+end
diff --git a/spec/lib/gitlab/usage_data_spec.rb b/spec/lib/gitlab/usage_data_spec.rb
index dda119e09b1..b3a179e276b 100644
--- a/spec/lib/gitlab/usage_data_spec.rb
+++ b/spec/lib/gitlab/usage_data_spec.rb
@@ -69,6 +69,7 @@ describe Gitlab::UsageData do
snippet_update: a_kind_of(Integer),
snippet_comment: a_kind_of(Integer),
merge_request_comment: a_kind_of(Integer),
+ merge_request_create: a_kind_of(Integer),
commit_comment: a_kind_of(Integer),
wiki_pages_create: a_kind_of(Integer),
wiki_pages_update: a_kind_of(Integer),
diff --git a/spec/lib/gitlab/user_access_spec.rb b/spec/lib/gitlab/user_access_spec.rb
index 9da06bb40f4..c25bd14fcba 100644
--- a/spec/lib/gitlab/user_access_spec.rb
+++ b/spec/lib/gitlab/user_access_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::UserAccess do
diff --git a/spec/lib/gitlab/utils/deep_size_spec.rb b/spec/lib/gitlab/utils/deep_size_spec.rb
index 1e619a15980..47dfc04f46f 100644
--- a/spec/lib/gitlab/utils/deep_size_spec.rb
+++ b/spec/lib/gitlab/utils/deep_size_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Utils::DeepSize do
diff --git a/spec/lib/gitlab/utils/merge_hash_spec.rb b/spec/lib/gitlab/utils/merge_hash_spec.rb
index 4fa7bb31301..72620e549a9 100644
--- a/spec/lib/gitlab/utils/merge_hash_spec.rb
+++ b/spec/lib/gitlab/utils/merge_hash_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Utils::MergeHash do
describe '.crush' do
diff --git a/spec/lib/gitlab/utils/override_spec.rb b/spec/lib/gitlab/utils/override_spec.rb
index 9e7c97f8095..5855c4374a9 100644
--- a/spec/lib/gitlab/utils/override_spec.rb
+++ b/spec/lib/gitlab/utils/override_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'fast_spec_helper'
describe Gitlab::Utils::Override do
diff --git a/spec/lib/gitlab/utils/sanitize_node_link_spec.rb b/spec/lib/gitlab/utils/sanitize_node_link_spec.rb
index 064c2707d06..80b0935a7ed 100644
--- a/spec/lib/gitlab/utils/sanitize_node_link_spec.rb
+++ b/spec/lib/gitlab/utils/sanitize_node_link_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Utils::SanitizeNodeLink do
diff --git a/spec/lib/gitlab/utils/strong_memoize_spec.rb b/spec/lib/gitlab/utils/strong_memoize_spec.rb
index 473f8100771..26baaf873a8 100644
--- a/spec/lib/gitlab/utils/strong_memoize_spec.rb
+++ b/spec/lib/gitlab/utils/strong_memoize_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Utils::StrongMemoize do
diff --git a/spec/lib/gitlab/utils_spec.rb b/spec/lib/gitlab/utils_spec.rb
index 0c20b3aa4c8..890918d4a7c 100644
--- a/spec/lib/gitlab/utils_spec.rb
+++ b/spec/lib/gitlab/utils_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Utils do
diff --git a/spec/lib/gitlab/verify/job_artifacts_spec.rb b/spec/lib/gitlab/verify/job_artifacts_spec.rb
index 6e916a56564..b50ec1528d4 100644
--- a/spec/lib/gitlab/verify/job_artifacts_spec.rb
+++ b/spec/lib/gitlab/verify/job_artifacts_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Verify::JobArtifacts do
diff --git a/spec/lib/gitlab/verify/lfs_objects_spec.rb b/spec/lib/gitlab/verify/lfs_objects_spec.rb
index 2feaedd6f14..c27c9b6efa1 100644
--- a/spec/lib/gitlab/verify/lfs_objects_spec.rb
+++ b/spec/lib/gitlab/verify/lfs_objects_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Verify::LfsObjects do
diff --git a/spec/lib/gitlab/verify/uploads_spec.rb b/spec/lib/gitlab/verify/uploads_spec.rb
index 38c30fab1ba..a3d3f5d46f3 100644
--- a/spec/lib/gitlab/verify/uploads_spec.rb
+++ b/spec/lib/gitlab/verify/uploads_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Verify::Uploads do
diff --git a/spec/lib/gitlab/version_info_spec.rb b/spec/lib/gitlab/version_info_spec.rb
index 30035c79e58..8c14b187410 100644
--- a/spec/lib/gitlab/version_info_spec.rb
+++ b/spec/lib/gitlab/version_info_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe 'Gitlab::VersionInfo' do
diff --git a/spec/lib/gitlab/view/presenter/base_spec.rb b/spec/lib/gitlab/view/presenter/base_spec.rb
index 02c2fd47197..e196ab23482 100644
--- a/spec/lib/gitlab/view/presenter/base_spec.rb
+++ b/spec/lib/gitlab/view/presenter/base_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::View::Presenter::Base do
diff --git a/spec/lib/gitlab/view/presenter/delegated_spec.rb b/spec/lib/gitlab/view/presenter/delegated_spec.rb
index 940a2ce6ebd..0a21cd1358e 100644
--- a/spec/lib/gitlab/view/presenter/delegated_spec.rb
+++ b/spec/lib/gitlab/view/presenter/delegated_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::View::Presenter::Delegated do
diff --git a/spec/lib/gitlab/view/presenter/factory_spec.rb b/spec/lib/gitlab/view/presenter/factory_spec.rb
index 6120bafb2e3..515a1b0a8e4 100644
--- a/spec/lib/gitlab/view/presenter/factory_spec.rb
+++ b/spec/lib/gitlab/view/presenter/factory_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::View::Presenter::Factory do
diff --git a/spec/lib/gitlab/view/presenter/simple_spec.rb b/spec/lib/gitlab/view/presenter/simple_spec.rb
index 1795ed2405b..70e2b170a36 100644
--- a/spec/lib/gitlab/view/presenter/simple_spec.rb
+++ b/spec/lib/gitlab/view/presenter/simple_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::View::Presenter::Simple do
diff --git a/spec/lib/gitlab/visibility_level_spec.rb b/spec/lib/gitlab/visibility_level_spec.rb
index 0a170a157fe..75dc7d8e6d1 100644
--- a/spec/lib/gitlab/visibility_level_spec.rb
+++ b/spec/lib/gitlab/visibility_level_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::VisibilityLevel do
diff --git a/spec/lib/gitlab/wiki_file_finder_spec.rb b/spec/lib/gitlab/wiki_file_finder_spec.rb
index 025d1203dc5..fdd95d5e6e6 100644
--- a/spec/lib/gitlab/wiki_file_finder_spec.rb
+++ b/spec/lib/gitlab/wiki_file_finder_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::WikiFileFinder do
diff --git a/spec/lib/gitlab/workhorse_spec.rb b/spec/lib/gitlab/workhorse_spec.rb
index 451e18ed91b..5c5ff46112f 100644
--- a/spec/lib/gitlab/workhorse_spec.rb
+++ b/spec/lib/gitlab/workhorse_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Workhorse do
diff --git a/spec/lib/gitlab_spec.rb b/spec/lib/gitlab_spec.rb
index c293f58c9cb..1fc363460ae 100644
--- a/spec/lib/gitlab_spec.rb
+++ b/spec/lib/gitlab_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'fast_spec_helper'
require_dependency 'gitlab'
@@ -96,6 +98,33 @@ describe Gitlab do
end
end
+ describe '.dev_env_org_or_com?' do
+ it 'is true when on .com' do
+ allow(described_class).to receive_messages(com?: true, org?: false)
+
+ expect(described_class.dev_env_org_or_com?).to eq true
+ end
+
+ it 'is true when org' do
+ allow(described_class).to receive_messages(com?: false, org?: true)
+
+ expect(described_class.dev_env_org_or_com?).to eq true
+ end
+
+ it 'is true when dev env' do
+ allow(described_class).to receive_messages(com?: false, org?: false)
+ allow(Rails).to receive(:env).and_return(ActiveSupport::StringInquirer.new('development'))
+
+ expect(described_class.dev_env_org_or_com?).to eq true
+ end
+
+ it 'is false when not dev, org or com' do
+ allow(described_class).to receive_messages(com?: false, org?: false)
+
+ expect(described_class.dev_env_org_or_com?).to eq false
+ end
+ end
+
describe '.ee?' do
before do
described_class.instance_variable_set(:@is_ee, nil)
diff --git a/spec/lib/google_api/auth_spec.rb b/spec/lib/google_api/auth_spec.rb
index 87a3f43274f..a25004ac385 100644
--- a/spec/lib/google_api/auth_spec.rb
+++ b/spec/lib/google_api/auth_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe GoogleApi::Auth do
diff --git a/spec/lib/google_api/cloud_platform/client_spec.rb b/spec/lib/google_api/cloud_platform/client_spec.rb
index 1fefc947636..c24998d32f8 100644
--- a/spec/lib/google_api/cloud_platform/client_spec.rb
+++ b/spec/lib/google_api/cloud_platform/client_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe GoogleApi::CloudPlatform::Client do
diff --git a/spec/lib/json_web_token/rsa_token_spec.rb b/spec/lib/json_web_token/rsa_token_spec.rb
index a3c54651e80..a127c787e28 100644
--- a/spec/lib/json_web_token/rsa_token_spec.rb
+++ b/spec/lib/json_web_token/rsa_token_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
describe JSONWebToken::RSAToken do
let(:rsa_key) do
OpenSSL::PKey::RSA.new <<-eos.strip_heredoc
diff --git a/spec/lib/json_web_token/token_spec.rb b/spec/lib/json_web_token/token_spec.rb
index d7e7560d962..916d11ce0ed 100644
--- a/spec/lib/json_web_token/token_spec.rb
+++ b/spec/lib/json_web_token/token_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
describe JSONWebToken::Token do
let(:token) { described_class.new }
diff --git a/spec/lib/mattermost/client_spec.rb b/spec/lib/mattermost/client_spec.rb
index dc11a414717..5fe35eb5f93 100644
--- a/spec/lib/mattermost/client_spec.rb
+++ b/spec/lib/mattermost/client_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Mattermost::Client do
diff --git a/spec/lib/mattermost/command_spec.rb b/spec/lib/mattermost/command_spec.rb
index 7c194749dfb..f8c451a1522 100644
--- a/spec/lib/mattermost/command_spec.rb
+++ b/spec/lib/mattermost/command_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Mattermost::Command do
diff --git a/spec/lib/mattermost/session_spec.rb b/spec/lib/mattermost/session_spec.rb
index 346455067a7..ea12bd76c8d 100644
--- a/spec/lib/mattermost/session_spec.rb
+++ b/spec/lib/mattermost/session_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Mattermost::Session, type: :request do
diff --git a/spec/lib/mattermost/team_spec.rb b/spec/lib/mattermost/team_spec.rb
index 030aa5d06a8..2823dab67c9 100644
--- a/spec/lib/mattermost/team_spec.rb
+++ b/spec/lib/mattermost/team_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Mattermost::Team do
diff --git a/spec/lib/microsoft_teams/activity_spec.rb b/spec/lib/microsoft_teams/activity_spec.rb
index 7890ae2e7b0..3fad2437f3e 100644
--- a/spec/lib/microsoft_teams/activity_spec.rb
+++ b/spec/lib/microsoft_teams/activity_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe MicrosoftTeams::Activity do
diff --git a/spec/lib/microsoft_teams/notifier_spec.rb b/spec/lib/microsoft_teams/notifier_spec.rb
index 2aaa7c24ad8..64ab8d85807 100644
--- a/spec/lib/microsoft_teams/notifier_spec.rb
+++ b/spec/lib/microsoft_teams/notifier_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe MicrosoftTeams::Notifier do
diff --git a/spec/lib/milestone_array_spec.rb b/spec/lib/milestone_array_spec.rb
index df91677b925..375cb87dde6 100644
--- a/spec/lib/milestone_array_spec.rb
+++ b/spec/lib/milestone_array_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe MilestoneArray do
diff --git a/spec/lib/object_storage/direct_upload_spec.rb b/spec/lib/object_storage/direct_upload_spec.rb
index 8ccbd90ddb8..fae0c636bdc 100644
--- a/spec/lib/object_storage/direct_upload_spec.rb
+++ b/spec/lib/object_storage/direct_upload_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe ObjectStorage::DirectUpload do
diff --git a/spec/lib/omni_auth/strategies/jwt_spec.rb b/spec/lib/omni_auth/strategies/jwt_spec.rb
index c1eaf0bb0bf..bdf3ea6be98 100644
--- a/spec/lib/omni_auth/strategies/jwt_spec.rb
+++ b/spec/lib/omni_auth/strategies/jwt_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe OmniAuth::Strategies::Jwt do
diff --git a/spec/lib/rspec_flaky/config_spec.rb b/spec/lib/rspec_flaky/config_spec.rb
index 4a71b1feebd..13b2219267b 100644
--- a/spec/lib/rspec_flaky/config_spec.rb
+++ b/spec/lib/rspec_flaky/config_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe RspecFlaky::Config, :aggregate_failures do
diff --git a/spec/lib/rspec_flaky/example_spec.rb b/spec/lib/rspec_flaky/example_spec.rb
index 5b4fd5ddf3e..4679dd818db 100644
--- a/spec/lib/rspec_flaky/example_spec.rb
+++ b/spec/lib/rspec_flaky/example_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe RspecFlaky::Example do
diff --git a/spec/lib/rspec_flaky/flaky_example_spec.rb b/spec/lib/rspec_flaky/flaky_example_spec.rb
index d19c34bebb3..092bbc781a5 100644
--- a/spec/lib/rspec_flaky/flaky_example_spec.rb
+++ b/spec/lib/rspec_flaky/flaky_example_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe RspecFlaky::FlakyExample, :aggregate_failures do
diff --git a/spec/lib/rspec_flaky/flaky_examples_collection_spec.rb b/spec/lib/rspec_flaky/flaky_examples_collection_spec.rb
index 6731a27ed17..2e224cda61b 100644
--- a/spec/lib/rspec_flaky/flaky_examples_collection_spec.rb
+++ b/spec/lib/rspec_flaky/flaky_examples_collection_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe RspecFlaky::FlakyExamplesCollection, :aggregate_failures do
diff --git a/spec/lib/rspec_flaky/listener_spec.rb b/spec/lib/rspec_flaky/listener_spec.rb
index ef085445081..44b8d99b74f 100644
--- a/spec/lib/rspec_flaky/listener_spec.rb
+++ b/spec/lib/rspec_flaky/listener_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe RspecFlaky::Listener, :aggregate_failures do
diff --git a/spec/lib/rspec_flaky/report_spec.rb b/spec/lib/rspec_flaky/report_spec.rb
index 7d57d99f7e5..6a98a7a4e6b 100644
--- a/spec/lib/rspec_flaky/report_spec.rb
+++ b/spec/lib/rspec_flaky/report_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe RspecFlaky::Report, :aggregate_failures do
diff --git a/spec/lib/safe_zip/entry_spec.rb b/spec/lib/safe_zip/entry_spec.rb
index 115e28c5994..0974f732188 100644
--- a/spec/lib/safe_zip/entry_spec.rb
+++ b/spec/lib/safe_zip/entry_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe SafeZip::Entry do
diff --git a/spec/lib/safe_zip/extract_params_spec.rb b/spec/lib/safe_zip/extract_params_spec.rb
index 85e22cfa495..f66d3de89ee 100644
--- a/spec/lib/safe_zip/extract_params_spec.rb
+++ b/spec/lib/safe_zip/extract_params_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe SafeZip::ExtractParams do
diff --git a/spec/lib/safe_zip/extract_spec.rb b/spec/lib/safe_zip/extract_spec.rb
index b75a8fede00..3b8c64c1c9f 100644
--- a/spec/lib/safe_zip/extract_spec.rb
+++ b/spec/lib/safe_zip/extract_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe SafeZip::Extract do
diff --git a/spec/lib/serializers/json_spec.rb b/spec/lib/serializers/json_spec.rb
index 847a01d186c..a8d82d70e89 100644
--- a/spec/lib/serializers/json_spec.rb
+++ b/spec/lib/serializers/json_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'fast_spec_helper'
describe Serializers::JSON do
diff --git a/spec/lib/system_check/app/git_user_default_ssh_config_check_spec.rb b/spec/lib/system_check/app/git_user_default_ssh_config_check_spec.rb
index a0fb86345f3..f132f608ab6 100644
--- a/spec/lib/system_check/app/git_user_default_ssh_config_check_spec.rb
+++ b/spec/lib/system_check/app/git_user_default_ssh_config_check_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe SystemCheck::App::GitUserDefaultSSHConfigCheck do
diff --git a/spec/lib/system_check/base_check_spec.rb b/spec/lib/system_check/base_check_spec.rb
index faf8c99e772..ccb7b483bdc 100644
--- a/spec/lib/system_check/base_check_spec.rb
+++ b/spec/lib/system_check/base_check_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe SystemCheck::BaseCheck do
diff --git a/spec/lib/system_check/orphans/namespace_check_spec.rb b/spec/lib/system_check/orphans/namespace_check_spec.rb
index 2a61ff3ad65..f7491e40438 100644
--- a/spec/lib/system_check/orphans/namespace_check_spec.rb
+++ b/spec/lib/system_check/orphans/namespace_check_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
require 'rake_helper'
diff --git a/spec/lib/system_check/orphans/repository_check_spec.rb b/spec/lib/system_check/orphans/repository_check_spec.rb
index b0c2267d177..a5e06f30e75 100644
--- a/spec/lib/system_check/orphans/repository_check_spec.rb
+++ b/spec/lib/system_check/orphans/repository_check_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
require 'rake_helper'
diff --git a/spec/lib/system_check/simple_executor_spec.rb b/spec/lib/system_check/simple_executor_spec.rb
index e71e9da369d..94094343ec6 100644
--- a/spec/lib/system_check/simple_executor_spec.rb
+++ b/spec/lib/system_check/simple_executor_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
require 'rake_helper'
diff --git a/spec/lib/system_check_spec.rb b/spec/lib/system_check_spec.rb
index 4d9e17fa6ec..f3ed6ca31c9 100644
--- a/spec/lib/system_check_spec.rb
+++ b/spec/lib/system_check_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
require 'rake_helper'
diff --git a/spec/lib/uploaded_file_spec.rb b/spec/lib/uploaded_file_spec.rb
index a2f5c2e7121..2cb4727bd4b 100644
--- a/spec/lib/uploaded_file_spec.rb
+++ b/spec/lib/uploaded_file_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe UploadedFile do
diff --git a/spec/migrations/add_gitlab_instance_administration_project_spec.rb b/spec/migrations/add_gitlab_instance_administration_project_spec.rb
new file mode 100644
index 00000000000..08e20a4e8ff
--- /dev/null
+++ b/spec/migrations/add_gitlab_instance_administration_project_spec.rb
@@ -0,0 +1,252 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require Rails.root.join('db', 'post_migrate', '20190801072937_add_gitlab_instance_administration_project.rb')
+
+describe AddGitlabInstanceAdministrationProject, :migration do
+ let(:application_settings) { table(:application_settings) }
+ let(:users) { table(:users) }
+ let(:projects) { table(:projects) }
+ let(:namespaces) { table(:namespaces) }
+ let(:members) { table(:members) }
+
+ let(:service_class) do
+ Gitlab::DatabaseImporters::SelfMonitoring::Project::CreateService
+ end
+
+ let(:prometheus_settings) do
+ {
+ enable: true,
+ listen_address: 'localhost:9090'
+ }
+ end
+
+ before do
+ stub_env('IN_MEMORY_APPLICATION_SETTINGS', 'false')
+
+ stub_config(prometheus: prometheus_settings)
+ end
+
+ describe 'down' do
+ let!(:application_setting) { application_settings.create! }
+ let!(:user) { users.create!(admin: true, email: 'admin1@example.com', projects_limit: 10, state: :active) }
+
+ it 'deletes group and project' do
+ migrate!
+
+ expect(Project.count).to eq(1)
+ expect(Group.count).to eq(1)
+
+ schema_migrate_down!
+
+ expect(Project.count).to eq(0)
+ expect(Group.count).to eq(0)
+ end
+ end
+
+ describe 'up' do
+ context 'without application_settings' do
+ it 'does not fail' do
+ migrate!
+
+ expect(Project.count).to eq(0)
+ end
+ end
+
+ context 'without admin users' do
+ let!(:application_setting) { application_settings.create! }
+
+ it 'does not fail' do
+ migrate!
+
+ expect(Project.count).to eq(0)
+ end
+ end
+
+ context 'with admin users' do
+ let(:project) { Project.last }
+ let(:group) { Group.last }
+ let!(:application_setting) { application_settings.create! }
+ let!(:user) { users.create!(admin: true, email: 'admin1@example.com', projects_limit: 10, state: :active) }
+
+ before do
+ stub_application_setting(allow_local_requests_from_web_hooks_and_services: true)
+ end
+
+ shared_examples 'has prometheus service' do |listen_address|
+ it do
+ migrate!
+
+ prometheus = project.prometheus_service
+ expect(prometheus).to be_persisted
+ expect(prometheus).not_to eq(nil)
+ expect(prometheus.api_url).to eq(listen_address)
+ expect(prometheus.active).to eq(true)
+ expect(prometheus.manual_configuration).to eq(true)
+ end
+ end
+
+ it_behaves_like 'has prometheus service', 'http://localhost:9090'
+
+ it 'creates GitLab Instance Administrator group' do
+ migrate!
+
+ expect(group).to be_persisted
+ expect(group.name).to eq('GitLab Instance Administrators')
+ expect(group.path).to start_with('gitlab-instance-administrators')
+ expect(group.path.split('-').last.length).to eq(8)
+ expect(group.visibility_level).to eq(service_class::VISIBILITY_LEVEL)
+ end
+
+ it 'creates project with internal visibility' do
+ migrate!
+
+ expect(project.visibility_level).to eq(Gitlab::VisibilityLevel::INTERNAL)
+ expect(project).to be_persisted
+ end
+
+ it 'creates project with correct name and description' do
+ migrate!
+
+ path = 'administration/monitoring/gitlab_instance_administration_project/index'
+ docs_path = Rails.application.routes.url_helpers.help_page_path(path)
+
+ expect(project.name).to eq(service_class::PROJECT_NAME)
+ expect(project.description).to eq(
+ 'This project is automatically generated and will be used to help monitor this GitLab instance. ' \
+ "[More information](#{docs_path})"
+ )
+ expect(File).to exist("doc/#{path}.md")
+ end
+
+ it 'adds all admins as maintainers' do
+ admin1 = users.create!(admin: true, email: 'admin2@example.com', projects_limit: 10, state: :active)
+ admin2 = users.create!(admin: true, email: 'admin3@example.com', projects_limit: 10, state: :active)
+ users.create!(email: 'nonadmin1@example.com', projects_limit: 10, state: :active)
+
+ migrate!
+
+ expect(project.owner).to eq(group)
+ expect(group.members.collect(&:user).collect(&:id)).to contain_exactly(user.id, admin1.id, admin2.id)
+ expect(group.members.collect(&:access_level)).to contain_exactly(
+ Gitlab::Access::OWNER,
+ Gitlab::Access::MAINTAINER,
+ Gitlab::Access::MAINTAINER
+ )
+ end
+
+ it 'saves the project id' do
+ migrate!
+
+ application_setting.reload
+ expect(application_setting.instance_administration_project_id).to eq(project.id)
+ end
+
+ it 'does not fail when a project already exists' do
+ group = namespaces.create!(
+ path: 'gitlab-instance-administrators',
+ name: 'GitLab Instance Administrators',
+ type: 'Group'
+ )
+ project = projects.create!(
+ namespace_id: group.id,
+ name: 'GitLab Instance Administration'
+ )
+
+ admin1 = users.create!(admin: true, email: 'admin4@example.com', projects_limit: 10, state: :active)
+ admin2 = users.create!(admin: true, email: 'admin5@example.com', projects_limit: 10, state: :active)
+
+ members.create!(
+ user_id: admin1.id,
+ source_id: group.id,
+ source_type: 'Namespace',
+ type: 'GroupMember',
+ access_level: GroupMember::MAINTAINER,
+ notification_level: NotificationSetting.levels[:global]
+ )
+ members.create!(
+ user_id: admin2.id,
+ source_id: group.id,
+ source_type: 'Namespace',
+ type: 'GroupMember',
+ access_level: GroupMember::MAINTAINER,
+ notification_level: NotificationSetting.levels[:global]
+ )
+
+ stub_application_setting(instance_administration_project: project)
+
+ migrate!
+
+ expect(Project.last.id).to eq(project.id)
+ expect(Group.last.id).to eq(group.id)
+ end
+
+ context 'when local requests from hooks and services are not allowed' do
+ before do
+ stub_application_setting(allow_local_requests_from_web_hooks_and_services: false)
+ end
+
+ it_behaves_like 'has prometheus service', 'http://localhost:9090'
+
+ it 'does not overwrite the existing whitelist' do
+ application_setting.update!(outbound_local_requests_whitelist: ['example.com'])
+
+ migrate!
+
+ application_setting.reload
+ expect(application_setting.outbound_local_requests_whitelist).to contain_exactly(
+ 'example.com', 'localhost'
+ )
+ end
+ end
+
+ context 'with non default prometheus address' do
+ let(:prometheus_settings) do
+ {
+ enable: true,
+ listen_address: 'https://localhost:9090'
+ }
+ end
+
+ it_behaves_like 'has prometheus service', 'https://localhost:9090'
+ end
+
+ context 'when prometheus setting is not present in gitlab.yml' do
+ before do
+ allow(Gitlab.config).to receive(:prometheus).and_raise(Settingslogic::MissingSetting)
+ end
+
+ it 'does not fail' do
+ migrate!
+
+ expect(project.prometheus_service).to be_nil
+ end
+ end
+
+ context 'when prometheus setting is disabled in gitlab.yml' do
+ let(:prometheus_settings) do
+ {
+ enable: false,
+ listen_address: 'localhost:9090'
+ }
+ end
+
+ it 'does not configure prometheus' do
+ migrate!
+
+ expect(project.prometheus_service).to be_nil
+ end
+ end
+
+ context 'when prometheus listen address is blank in gitlab.yml' do
+ let(:prometheus_settings) { { enable: true, listen_address: '' } }
+
+ it 'does not configure prometheus' do
+ migrate!
+
+ expect(project.prometheus_service).to be_nil
+ end
+ end
+ end
+ end
+end
diff --git a/spec/migrations/encrypt_deploy_tokens_tokens_spec.rb b/spec/migrations/encrypt_deploy_tokens_tokens_spec.rb
new file mode 100644
index 00000000000..a398e079731
--- /dev/null
+++ b/spec/migrations/encrypt_deploy_tokens_tokens_spec.rb
@@ -0,0 +1,47 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+require Rails.root.join('db', 'post_migrate', '20190711201818_encrypt_deploy_tokens_tokens.rb')
+
+describe EncryptDeployTokensTokens, :migration do
+ let(:migration) { described_class.new }
+ let(:deployment_tokens) { table(:deploy_tokens) }
+ let(:plaintext) { "secret-token" }
+ let(:expires_at) { DateTime.now + 1.year }
+ let(:ciphertext) { Gitlab::CryptoHelper.aes256_gcm_encrypt(plaintext) }
+
+ describe '#up' do
+ it 'keeps plaintext token the same and populates token_encrypted if not present' do
+ deploy_token = deployment_tokens.create!(
+ name: 'test_token',
+ read_repository: true,
+ expires_at: expires_at,
+ username: 'gitlab-token-1',
+ token: plaintext
+ )
+
+ migration.up
+
+ expect(deploy_token.reload.token).to eq(plaintext)
+ expect(deploy_token.reload.token_encrypted).to eq(ciphertext)
+ end
+ end
+
+ describe '#down' do
+ it 'decrypts encrypted token and saves it' do
+ deploy_token = deployment_tokens.create!(
+ name: 'test_token',
+ read_repository: true,
+ expires_at: expires_at,
+ username: 'gitlab-token-1',
+ token_encrypted: ciphertext
+ )
+
+ migration.down
+
+ expect(deploy_token.reload.token).to eq(plaintext)
+ expect(deploy_token.reload.token_encrypted).to eq(ciphertext)
+ end
+ end
+end
diff --git a/spec/models/analytics/cycle_analytics/project_stage_spec.rb b/spec/models/analytics/cycle_analytics/project_stage_spec.rb
index 4e3923e82b1..83d6ff754c5 100644
--- a/spec/models/analytics/cycle_analytics/project_stage_spec.rb
+++ b/spec/models/analytics/cycle_analytics/project_stage_spec.rb
@@ -6,4 +6,18 @@ describe Analytics::CycleAnalytics::ProjectStage do
describe 'associations' do
it { is_expected.to belong_to(:project) }
end
+
+ it 'default stages must be valid' do
+ project = create(:project)
+
+ Gitlab::Analytics::CycleAnalytics::DefaultStages.all.each do |params|
+ stage = described_class.new(params.merge(project: project))
+ expect(stage).to be_valid
+ end
+ end
+
+ it_behaves_like "cycle analytics stage" do
+ let(:parent) { create(:project) }
+ let(:parent_name) { :project }
+ end
end
diff --git a/spec/models/ci/pipeline_spec.rb b/spec/models/ci/pipeline_spec.rb
index 78be4a8131a..7d84d094bdf 100644
--- a/spec/models/ci/pipeline_spec.rb
+++ b/spec/models/ci/pipeline_spec.rb
@@ -4,6 +4,7 @@ require 'spec_helper'
describe Ci::Pipeline, :mailer do
include ProjectForksHelper
+ include StubRequests
let(:user) { create(:user) }
set(:project) { create(:project) }
@@ -2504,7 +2505,7 @@ describe Ci::Pipeline, :mailer do
let(:enabled) { true }
before do
- WebMock.stub_request(:post, hook.url)
+ stub_full_request(hook.url, method: :post)
end
context 'with multiple builds' do
@@ -2558,7 +2559,7 @@ describe Ci::Pipeline, :mailer do
end
def have_requested_pipeline_hook(status)
- have_requested(:post, hook.url).with do |req|
+ have_requested(:post, stubbed_hostname(hook.url)).with do |req|
json_body = JSON.parse(req.body)
json_body['object_attributes']['status'] == status &&
json_body['builds'].length == 2
diff --git a/spec/models/ci/runner_spec.rb b/spec/models/ci/runner_spec.rb
index 78b151631c1..70ff3cf5dc4 100644
--- a/spec/models/ci/runner_spec.rb
+++ b/spec/models/ci/runner_spec.rb
@@ -80,6 +80,13 @@ describe Ci::Runner do
end
end
+ describe 'constraints' do
+ it '.UPDATE_CONTACT_COLUMN_EVERY' do
+ expect(described_class::UPDATE_CONTACT_COLUMN_EVERY.max)
+ .to be <= described_class::ONLINE_CONTACT_TIMEOUT
+ end
+ end
+
describe '#access_level' do
context 'when creating new runner and access_level is nil' do
let(:runner) do
diff --git a/spec/models/deployment_spec.rb b/spec/models/deployment_spec.rb
index d4e631f109b..51ed8e9421b 100644
--- a/spec/models/deployment_spec.rb
+++ b/spec/models/deployment_spec.rb
@@ -322,4 +322,30 @@ describe Deployment do
end
end
end
+
+ describe '#deployed_by' do
+ it 'returns the deployment user if there is no deployable' do
+ deployment_user = create(:user)
+ deployment = create(:deployment, deployable: nil, user: deployment_user)
+
+ expect(deployment.deployed_by).to eq(deployment_user)
+ end
+
+ it 'returns the deployment user if the deployable have no user' do
+ deployment_user = create(:user)
+ build = create(:ci_build, user: nil)
+ deployment = create(:deployment, deployable: build, user: deployment_user)
+
+ expect(deployment.deployed_by).to eq(deployment_user)
+ end
+
+ it 'returns the deployable user if there is one' do
+ build_user = create(:user)
+ deployment_user = create(:user)
+ build = create(:ci_build, user: build_user)
+ deployment = create(:deployment, deployable: build, user: deployment_user)
+
+ expect(deployment.deployed_by).to eq(build_user)
+ end
+ end
end
diff --git a/spec/models/namespace/root_storage_statistics_spec.rb b/spec/models/namespace/root_storage_statistics_spec.rb
index 5341278db7c..9e12831a704 100644
--- a/spec/models/namespace/root_storage_statistics_spec.rb
+++ b/spec/models/namespace/root_storage_statistics_spec.rb
@@ -8,6 +8,19 @@ RSpec.describe Namespace::RootStorageStatistics, type: :model do
it { is_expected.to delegate_method(:all_projects).to(:namespace) }
+ context 'scopes' do
+ describe '.for_namespace_ids' do
+ it 'returns only requested namespaces' do
+ stats = create_list(:namespace_root_storage_statistics, 3)
+ namespace_ids = stats[0..1].map { |s| s.namespace_id }
+
+ requested_stats = described_class.for_namespace_ids(namespace_ids).pluck(:namespace_id)
+
+ expect(requested_stats).to eq(namespace_ids)
+ end
+ end
+ end
+
describe '#recalculate!' do
let(:namespace) { create(:group) }
let(:root_storage_statistics) { create(:namespace_root_storage_statistics, namespace: namespace) }
diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb
index ff9e94afc12..bd352db2236 100644
--- a/spec/models/project_spec.rb
+++ b/spec/models/project_spec.rb
@@ -4877,35 +4877,22 @@ describe Project do
describe '#git_objects_poolable?' do
subject { project }
-
- context 'when the feature flag is turned off' do
- before do
- stub_feature_flags(object_pools: false)
- end
-
- let(:project) { create(:project, :repository, :public) }
+ context 'when not using hashed storage' do
+ let(:project) { create(:project, :legacy_storage, :public, :repository) }
it { is_expected.not_to be_git_objects_poolable }
end
- context 'when the feature flag is enabled' do
- context 'when not using hashed storage' do
- let(:project) { create(:project, :legacy_storage, :public, :repository) }
-
- it { is_expected.not_to be_git_objects_poolable }
- end
+ context 'when the project is not public' do
+ let(:project) { create(:project, :private) }
- context 'when the project is not public' do
- let(:project) { create(:project, :private) }
-
- it { is_expected.not_to be_git_objects_poolable }
- end
+ it { is_expected.not_to be_git_objects_poolable }
+ end
- context 'when objects are poolable' do
- let(:project) { create(:project, :repository, :public) }
+ context 'when objects are poolable' do
+ let(:project) { create(:project, :repository, :public) }
- it { is_expected.to be_git_objects_poolable }
- end
+ it { is_expected.to be_git_objects_poolable }
end
end
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
index 46b86e8393d..8338d2b5b39 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -103,6 +103,14 @@ describe User do
it { is_expected.to validate_length_of(:name).is_at_most(128) }
end
+ describe 'first name' do
+ it { is_expected.to validate_length_of(:first_name).is_at_most(255) }
+ end
+
+ describe 'last name' do
+ it { is_expected.to validate_length_of(:last_name).is_at_most(255) }
+ end
+
describe 'username' do
it 'validates presence' do
expect(subject).to validate_presence_of(:username)
@@ -678,6 +686,18 @@ describe User do
end
end
+ describe 'name getters' do
+ let(:user) { create(:user, name: 'Kane Martin William') }
+
+ it 'derives first name from full name, if not present' do
+ expect(user.first_name).to eq('Kane')
+ end
+
+ it 'derives last name from full name, if not present' do
+ expect(user.last_name).to eq('Martin William')
+ end
+ end
+
describe '#highest_role' do
let(:user) { create(:user) }
diff --git a/spec/policies/namespace/root_storage_statistics_policy_spec.rb b/spec/policies/namespace/root_storage_statistics_policy_spec.rb
new file mode 100644
index 00000000000..8d53050fffb
--- /dev/null
+++ b/spec/policies/namespace/root_storage_statistics_policy_spec.rb
@@ -0,0 +1,80 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Namespace::RootStorageStatisticsPolicy do
+ using RSpec::Parameterized::TableSyntax
+
+ describe '#rules' do
+ let(:statistics) { create(:namespace_root_storage_statistics, namespace: namespace) }
+ let(:user) { create(:user) }
+
+ subject { Ability.allowed?(user, :read_statistics, statistics) }
+
+ shared_examples 'deny anonymous users' do
+ context 'when the users is anonymous' do
+ let(:user) { nil }
+
+ it { is_expected.to be_falsey }
+ end
+ end
+
+ context 'when the namespace is a personal namespace' do
+ let(:owner) { create(:user) }
+ let(:namespace) { owner.namespace }
+
+ include_examples 'deny anonymous users'
+
+ context 'when the user is not the owner' do
+ it { is_expected.to be_falsey }
+ end
+
+ context 'when the user is the owner' do
+ let(:user) { owner }
+
+ it { is_expected.to be_truthy }
+ end
+ end
+
+ context 'when the namespace is a group' do
+ let(:user) { create(:user) }
+ let(:external) { create(:user, :external) }
+
+ shared_examples 'allows only owners' do |group_type|
+ let(:group) { create(:group, visibility_level: Gitlab::VisibilityLevel.level_value(group_type.to_s)) }
+ let(:namespace) { group }
+
+ include_examples 'deny anonymous users'
+
+ where(:user_type, :outcome) do
+ [
+ [:non_member, false],
+ [:guest, false],
+ [:reporter, false],
+ [:developer, false],
+ [:maintainer, false],
+ [:owner, true]
+ ]
+ end
+
+ with_them do
+ before do
+ group.add_user(user, user_type) unless user_type == :non_member
+ end
+
+ it { is_expected.to eq(outcome) }
+
+ context 'when the user is external' do
+ let(:user) { external }
+
+ it { is_expected.to eq(outcome) }
+ end
+ end
+ end
+
+ include_examples 'allows only owners', :public
+ include_examples 'allows only owners', :private
+ include_examples 'allows only owners', :internal
+ end
+ end
+end
diff --git a/spec/policies/namespace_policy_spec.rb b/spec/policies/namespace_policy_spec.rb
index 99fa8b1fe44..216aaae70ee 100644
--- a/spec/policies/namespace_policy_spec.rb
+++ b/spec/policies/namespace_policy_spec.rb
@@ -6,7 +6,7 @@ describe NamespacePolicy do
let(:admin) { create(:admin) }
let(:namespace) { create(:namespace, owner: owner) }
- let(:owner_permissions) { [:create_projects, :admin_namespace, :read_namespace] }
+ let(:owner_permissions) { [:create_projects, :admin_namespace, :read_namespace, :read_statistics] }
subject { described_class.new(current_user, namespace) }
diff --git a/spec/policies/project_policy_spec.rb b/spec/policies/project_policy_spec.rb
index 8fd54e0bf1d..71ba73d5661 100644
--- a/spec/policies/project_policy_spec.rb
+++ b/spec/policies/project_policy_spec.rb
@@ -94,6 +94,19 @@ describe ProjectPolicy do
permissions.each { |p| is_expected.not_to be_allowed(p) }
end
+ context 'with no project feature' do
+ subject { described_class.new(owner, project) }
+
+ before do
+ project.project_feature.destroy
+ project.reload
+ end
+
+ it 'returns false' do
+ is_expected.to be_disallowed(:read_build)
+ end
+ end
+
it 'does not include the read_issue permission when the issue author is not a member of the private project' do
project = create(:project, :private)
issue = create(:issue, project: project, author: create(:user))
diff --git a/spec/requests/api/discussions_spec.rb b/spec/requests/api/discussions_spec.rb
index ef09c6effbb..0420201efe3 100644
--- a/spec/requests/api/discussions_spec.rb
+++ b/spec/requests/api/discussions_spec.rb
@@ -9,59 +9,11 @@ describe API::Discussions do
project.add_developer(user)
end
- context 'with cross-reference system notes', :request_store do
- let(:merge_request) { create(:merge_request) }
- let(:project) { merge_request.project }
- let(:new_merge_request) { create(:merge_request) }
- let(:commit) { new_merge_request.project.commit }
- let!(:note) { create(:system_note, noteable: merge_request, project: project, note: cross_reference) }
- let!(:note_metadata) { create(:system_note_metadata, note: note, action: 'cross_reference') }
- let(:cross_reference) { "test commit #{commit.to_reference(project)}" }
- let(:pat) { create(:personal_access_token, user: user) }
-
+ context 'when discussions have cross-reference system notes' do
let(:url) { "/projects/#{project.id}/merge_requests/#{merge_request.iid}/discussions" }
+ let(:notes_in_response) { json_response.first['notes'] }
- before do
- project.add_developer(user)
- new_merge_request.project.add_developer(user)
- end
-
- it 'returns only the note that the user should see' do
- hidden_merge_request = create(:merge_request)
- new_cross_reference = "test commit #{hidden_merge_request.project.commit}"
- new_note = create(:system_note, noteable: merge_request, project: project, note: new_cross_reference)
- create(:system_note_metadata, note: new_note, action: 'cross_reference')
-
- get api(url, user, personal_access_token: pat)
- expect(response).to have_gitlab_http_status(200)
- expect(json_response.count).to eq(1)
- expect(json_response.first['notes'].count).to eq(1)
-
- parsed_note = json_response.first['notes'].first
- expect(parsed_note['id']).to eq(note.id)
- expect(parsed_note['body']).to eq(cross_reference)
- expect(parsed_note['system']).to be true
- end
-
- it 'avoids Git calls and N+1 SQL queries' do
- expect_any_instance_of(Repository).not_to receive(:find_commit).with(commit.id)
-
- control = ActiveRecord::QueryRecorder.new do
- get api(url, user, personal_access_token: pat)
- end
-
- expect(response).to have_gitlab_http_status(200)
-
- RequestStore.clear!
-
- new_note = create(:system_note, noteable: merge_request, project: project, note: cross_reference)
- create(:system_note_metadata, note: new_note, action: 'cross_reference')
-
- RequestStore.clear!
-
- expect { get api(url, user, personal_access_token: pat) }.not_to exceed_query_limit(control)
- expect(response).to have_gitlab_http_status(200)
- end
+ it_behaves_like 'with cross-reference system notes'
end
context 'when noteable is an Issue' do
diff --git a/spec/requests/api/graphql/multiplexed_queries_spec.rb b/spec/requests/api/graphql/multiplexed_queries_spec.rb
index 844fd979285..9ebb57f6b9c 100644
--- a/spec/requests/api/graphql/multiplexed_queries_spec.rb
+++ b/spec/requests/api/graphql/multiplexed_queries_spec.rb
@@ -6,9 +6,9 @@ describe 'Multiplexed queries' do
it 'returns responses for multiple queries' do
queries = [
- { query: 'query($text: String) { echo(text: $text) }',
+ { query: 'query($text: String!) { echo(text: $text) }',
variables: { 'text' => 'Hello' } },
- { query: 'query($text: String) { echo(text: $text) }',
+ { query: 'query($text: String!) { echo(text: $text) }',
variables: { 'text' => 'World' } }
]
@@ -23,8 +23,8 @@ describe 'Multiplexed queries' do
it 'returns error and data combinations' do
queries = [
- { query: 'query($text: String) { broken query }' },
- { query: 'query working($text: String) { echo(text: $text) }',
+ { query: 'query($text: String!) { broken query }' },
+ { query: 'query working($text: String!) { echo(text: $text) }',
variables: { 'text' => 'World' } }
]
diff --git a/spec/requests/api/graphql/namespace/root_storage_statistics_spec.rb b/spec/requests/api/graphql/namespace/root_storage_statistics_spec.rb
new file mode 100644
index 00000000000..ac76d991bd4
--- /dev/null
+++ b/spec/requests/api/graphql/namespace/root_storage_statistics_spec.rb
@@ -0,0 +1,55 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe 'rendering namespace statistics' do
+ include GraphqlHelpers
+
+ let(:namespace) { user.namespace }
+ let!(:statistics) { create(:namespace_root_storage_statistics, namespace: namespace, packages_size: 5.megabytes) }
+ let(:user) { create(:user) }
+
+ let(:query) do
+ graphql_query_for('namespace',
+ { 'fullPath' => namespace.full_path },
+ "rootStorageStatistics { #{all_graphql_fields_for('RootStorageStatistics')} }")
+ end
+
+ shared_examples 'a working namespace with storage statistics query' do
+ it_behaves_like 'a working graphql query' do
+ before do
+ post_graphql(query, current_user: user)
+ end
+ end
+
+ it 'includes the packages size if the user can read the statistics' do
+ post_graphql(query, current_user: user)
+
+ expect(graphql_data['namespace']['rootStorageStatistics']).not_to be_blank
+ expect(graphql_data['namespace']['rootStorageStatistics']['packagesSize']).to eq(5.megabytes)
+ end
+ end
+
+ it_behaves_like 'a working namespace with storage statistics query'
+
+ context 'when the namespace is a group' do
+ let(:group) { create(:group) }
+ let(:namespace) { group }
+
+ before do
+ group.add_owner(user)
+ end
+
+ it_behaves_like 'a working namespace with storage statistics query'
+
+ context 'when the namespace is public' do
+ let(:group) { create(:group, :public)}
+
+ it 'hides statistics for unauthenticated requests' do
+ post_graphql(query, current_user: nil)
+
+ expect(graphql_data['namespace']).to be_blank
+ end
+ end
+ end
+end
diff --git a/spec/requests/api/graphql/project/project_statistics_spec.rb b/spec/requests/api/graphql/project/project_statistics_spec.rb
index 14a3f37b779..ddee8537454 100644
--- a/spec/requests/api/graphql/project/project_statistics_spec.rb
+++ b/spec/requests/api/graphql/project/project_statistics_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'rendering namespace statistics' do
+describe 'rendering project statistics' do
include GraphqlHelpers
let(:project) { create(:project) }
diff --git a/spec/requests/api/issues/get_project_issues_spec.rb b/spec/requests/api/issues/get_project_issues_spec.rb
index 521d6b88734..b7aa3f93451 100644
--- a/spec/requests/api/issues/get_project_issues_spec.rb
+++ b/spec/requests/api/issues/get_project_issues_spec.rb
@@ -446,6 +446,14 @@ describe API::Issues do
expect_paginated_array_response([closed_issue.id, confidential_issue.id, issue.id])
end
+ it 'exposes known attributes' do
+ get api("#{base_url}/issues", user)
+
+ expect(response).to have_gitlab_http_status(200)
+ expect(json_response.last.keys).to include(*%w(id iid project_id title description))
+ expect(json_response.last).not_to have_key('subscribed')
+ end
+
context 'issues_statistics' do
context 'no state is treated as all state' do
let(:params) { {} }
diff --git a/spec/requests/api/issues/issues_spec.rb b/spec/requests/api/issues/issues_spec.rb
index 27cf66629fe..f19c2dcc6fe 100644
--- a/spec/requests/api/issues/issues_spec.rb
+++ b/spec/requests/api/issues/issues_spec.rb
@@ -607,6 +607,22 @@ describe API::Issues do
expect_paginated_array_response([closed_issue.id, issue.id])
end
+ context 'with issues list sort options' do
+ it 'accepts only predefined order by params' do
+ API::Helpers::IssuesHelpers.sort_options.each do |sort_opt|
+ get api('/issues', user), params: { order_by: sort_opt, sort: 'asc' }
+ expect(response).to have_gitlab_http_status(200)
+ end
+ end
+
+ it 'fails to sort with non predefined options' do
+ %w(milestone title abracadabra).each do |sort_opt|
+ get api('/issues', user), params: { order_by: sort_opt, sort: 'asc' }
+ expect(response).to have_gitlab_http_status(400)
+ end
+ end
+ end
+
it 'matches V4 response schema' do
get api('/issues', user)
diff --git a/spec/requests/api/labels_spec.rb b/spec/requests/api/labels_spec.rb
index ad0974f55a3..9aef67e28a7 100644
--- a/spec/requests/api/labels_spec.rb
+++ b/spec/requests/api/labels_spec.rb
@@ -6,6 +6,180 @@ describe API::Labels do
let!(:label1) { create(:label, title: 'label1', project: project) }
let!(:priority_label) { create(:label, title: 'bug', project: project, priority: 3) }
+ shared_examples 'label update API' do
+ it 'returns 200 if name is changed' do
+ request_params = {
+ new_name: 'New Label'
+ }.merge(spec_params)
+
+ put api("/projects/#{project.id}/labels", user),
+ params: request_params
+
+ expect(response).to have_gitlab_http_status(200)
+ expect(json_response['name']).to eq('New Label')
+ expect(json_response['color']).to eq(label1.color)
+ end
+
+ it 'returns 200 if colors is changed' do
+ request_params = {
+ color: '#FFFFFF'
+ }.merge(spec_params)
+
+ put api("/projects/#{project.id}/labels", user),
+ params: request_params
+
+ expect(response).to have_gitlab_http_status(200)
+ expect(json_response['name']).to eq(label1.name)
+ expect(json_response['color']).to eq('#FFFFFF')
+ end
+
+ it 'returns 200 if a priority is added' do
+ request_params = {
+ priority: 3
+ }.merge(spec_params)
+
+ put api("/projects/#{project.id}/labels", user),
+ params: request_params
+
+ expect(response.status).to eq(200)
+ expect(json_response['name']).to eq(label1.name)
+ expect(json_response['priority']).to eq(3)
+ end
+
+ it 'returns 400 if no new parameters given' do
+ put api("/projects/#{project.id}/labels", user), params: spec_params
+
+ expect(response).to have_gitlab_http_status(400)
+ expect(json_response['error']).to eq('new_name, color, description, priority are missing, '\
+ 'at least one parameter must be provided')
+ end
+
+ it 'returns 400 when color code is too short' do
+ request_params = {
+ color: '#FF'
+ }.merge(spec_params)
+
+ put api("/projects/#{project.id}/labels", user),
+ params: request_params
+
+ expect(response).to have_gitlab_http_status(400)
+ expect(json_response['message']['color']).to eq(['must be a valid color code'])
+ end
+
+ it 'returns 400 for too long color code' do
+ request_params = {
+ color: '#FFAAFFFF'
+ }.merge(spec_params)
+
+ put api("/projects/#{project.id}/labels", user),
+ params: request_params
+
+ expect(response).to have_gitlab_http_status(400)
+ expect(json_response['message']['color']).to eq(['must be a valid color code'])
+ end
+
+ it 'returns 400 for invalid priority' do
+ request_params = {
+ priority: 'foo'
+ }.merge(spec_params)
+
+ put api("/projects/#{project.id}/labels", user),
+ params: request_params
+
+ expect(response).to have_gitlab_http_status(400)
+ end
+
+ it 'returns 200 if name and colors and description are changed' do
+ request_params = {
+ new_name: 'New Label',
+ color: '#FFFFFF',
+ description: 'test'
+ }.merge(spec_params)
+
+ put api("/projects/#{project.id}/labels", user),
+ params: request_params
+
+ expect(response).to have_gitlab_http_status(200)
+ expect(json_response['name']).to eq('New Label')
+ expect(json_response['color']).to eq('#FFFFFF')
+ expect(json_response['description']).to eq('test')
+ end
+
+ it 'returns 400 for invalid name' do
+ request_params = {
+ new_name: ',',
+ color: '#FFFFFF'
+ }.merge(spec_params)
+
+ put api("/projects/#{project.id}/labels", user),
+ params: request_params
+
+ expect(response).to have_gitlab_http_status(400)
+ expect(json_response['message']['title']).to eq(['is invalid'])
+ end
+
+ it 'returns 200 if description is changed' do
+ request_params = {
+ description: 'test'
+ }.merge(spec_params)
+
+ put api("/projects/#{project.id}/labels", user),
+ params: request_params
+
+ expect(response).to have_gitlab_http_status(200)
+ expect(json_response['id']).to eq(expected_response_label_id)
+ expect(json_response['description']).to eq('test')
+ end
+
+ it 'returns 200 if priority is changed' do
+ request_params = {
+ priority: 10
+ }.merge(spec_params)
+
+ put api("/projects/#{project.id}/labels", user),
+ params: request_params
+
+ expect(response.status).to eq(200)
+ expect(json_response['id']).to eq(expected_response_label_id)
+ expect(json_response['priority']).to eq(10)
+ end
+
+ it 'returns 200 if a priority is removed' do
+ label = find_by_spec_params(spec_params)
+ expect(label).not_to be_nil
+
+ label.priorities.create(project: label.project, priority: 1)
+ label.save!
+
+ request_params = {
+ priority: nil
+ }.merge(spec_params)
+
+ put api("/projects/#{project.id}/labels", user),
+ params: request_params
+
+ expect(response.status).to eq(200)
+ expect(json_response['id']).to eq(expected_response_label_id)
+ expect(json_response['priority']).to be_nil
+ end
+
+ def find_by_spec_params(params)
+ if params.key?(:label_id)
+ Label.find(params[:label_id])
+ else
+ Label.find_by(name: params[:name])
+ end
+ end
+ end
+
+ shared_examples 'label delete API' do
+ it 'returns 204 for existing label' do
+ delete api("/projects/#{project.id}/labels", user), params: spec_params
+
+ expect(response).to have_gitlab_http_status(204)
+ end
+ end
+
before do
project.add_maintainer(user)
end
@@ -208,20 +382,34 @@ describe API::Labels do
end
describe 'DELETE /projects/:id/labels' do
- it 'returns 204 for existing label' do
- delete api("/projects/#{project.id}/labels", user), params: { name: 'label1' }
+ it_behaves_like 'label delete API' do
+ let(:spec_params) { { name: 'label1' } }
+ end
- expect(response).to have_gitlab_http_status(204)
+ it_behaves_like 'label delete API' do
+ let(:spec_params) { { label_id: label1.id } }
end
it 'returns 404 for non existing label' do
delete api("/projects/#{project.id}/labels", user), params: { name: 'label2' }
+
expect(response).to have_gitlab_http_status(404)
expect(json_response['message']).to eq('404 Label Not Found')
end
it 'returns 400 for wrong parameters' do
delete api("/projects/#{project.id}/labels", user)
+
+ expect(response).to have_gitlab_http_status(400)
+ end
+
+ it 'fails if label_id and name are given in params' do
+ delete api("/projects/#{project.id}/labels", user),
+ params: {
+ label_id: label1.id,
+ name: priority_label.name
+ }
+
expect(response).to have_gitlab_http_status(400)
end
@@ -232,152 +420,105 @@ describe API::Labels do
end
describe 'PUT /projects/:id/labels' do
- it 'returns 200 if name and colors and description are changed' do
- put api("/projects/#{project.id}/labels", user),
- params: {
- name: 'label1',
- new_name: 'New Label',
- color: '#FFFFFF',
- description: 'test'
- }
- expect(response).to have_gitlab_http_status(200)
- expect(json_response['name']).to eq('New Label')
- expect(json_response['color']).to eq('#FFFFFF')
- expect(json_response['description']).to eq('test')
+ context 'when using name' do
+ it_behaves_like 'label update API' do
+ let(:spec_params) { { name: 'label1' } }
+ let(:expected_response_label_id) { label1.id }
+ end
end
- it 'returns 200 if name is changed' do
- put api("/projects/#{project.id}/labels", user),
- params: {
- name: 'label1',
- new_name: 'New Label'
- }
- expect(response).to have_gitlab_http_status(200)
- expect(json_response['name']).to eq('New Label')
- expect(json_response['color']).to eq(label1.color)
+ context 'when using label_id' do
+ it_behaves_like 'label update API' do
+ let(:spec_params) { { label_id: label1.id } }
+ let(:expected_response_label_id) { label1.id }
+ end
end
- it 'returns 200 if colors is changed' do
+ it 'returns 404 if label does not exist' do
put api("/projects/#{project.id}/labels", user),
params: {
- name: 'label1',
- color: '#FFFFFF'
+ name: 'label2',
+ new_name: 'label3'
}
- expect(response).to have_gitlab_http_status(200)
- expect(json_response['name']).to eq(label1.name)
- expect(json_response['color']).to eq('#FFFFFF')
+
+ expect(response).to have_gitlab_http_status(404)
end
- it 'returns 200 if description is changed' do
+ it 'returns 404 if label by id does not exist' do
put api("/projects/#{project.id}/labels", user),
params: {
- name: 'bug',
- description: 'test'
+ label_id: 0,
+ new_name: 'label3'
}
- expect(response).to have_gitlab_http_status(200)
- expect(json_response['name']).to eq(priority_label.name)
- expect(json_response['description']).to eq('test')
- expect(json_response['priority']).to eq(3)
- end
-
- it 'returns 200 if priority is changed' do
- put api("/projects/#{project.id}/labels", user),
- params: {
- name: 'bug',
- priority: 10
- }
-
- expect(response.status).to eq(200)
- expect(json_response['name']).to eq(priority_label.name)
- expect(json_response['priority']).to eq(10)
+ expect(response).to have_gitlab_http_status(404)
end
- it 'returns 200 if a priority is added' do
- put api("/projects/#{project.id}/labels", user),
- params: {
- name: 'label1',
- priority: 3
- }
+ it 'returns 400 if no label name and id is given' do
+ put api("/projects/#{project.id}/labels", user), params: { new_name: 'label2' }
- expect(response.status).to eq(200)
- expect(json_response['name']).to eq(label1.name)
- expect(json_response['priority']).to eq(3)
+ expect(response).to have_gitlab_http_status(400)
+ expect(json_response['error']).to eq('label_id, name are missing, exactly one parameter must be provided')
end
- it 'returns 200 if the priority is removed' do
+ it 'fails if label_id and name are given in params' do
put api("/projects/#{project.id}/labels", user),
params: {
+ label_id: label1.id,
name: priority_label.name,
- priority: nil
+ new_name: 'New Label'
}
- expect(response.status).to eq(200)
- expect(json_response['name']).to eq(priority_label.name)
- expect(json_response['priority']).to be_nil
+ expect(response).to have_gitlab_http_status(400)
end
+ end
- it 'returns 404 if label does not exist' do
- put api("/projects/#{project.id}/labels", user),
- params: {
- name: 'label2',
- new_name: 'label3'
- }
- expect(response).to have_gitlab_http_status(404)
- end
+ describe 'PUT /projects/:id/labels/promote' do
+ let(:group) { create(:group) }
- it 'returns 400 if no label name given' do
- put api("/projects/#{project.id}/labels", user), params: { new_name: 'label2' }
- expect(response).to have_gitlab_http_status(400)
- expect(json_response['error']).to eq('name is missing')
+ before do
+ group.add_owner(user)
+ project.update!(group: group)
end
- it 'returns 400 if no new parameters given' do
- put api("/projects/#{project.id}/labels", user), params: { name: 'label1' }
- expect(response).to have_gitlab_http_status(400)
- expect(json_response['error']).to eq('new_name, color, description, priority are missing, '\
- 'at least one parameter must be provided')
+ it 'returns 200 if label is promoted' do
+ put api("/projects/#{project.id}/labels/promote", user), params: { name: label1.name }
+
+ expect(response).to have_gitlab_http_status(200)
+ expect(json_response['name']).to eq(label1.name)
+ expect(json_response['color']).to eq(label1.color)
end
- it 'returns 400 for invalid name' do
- put api("/projects/#{project.id}/labels", user),
- params: {
- name: 'label1',
- new_name: ',',
- color: '#FFFFFF'
- }
- expect(response).to have_gitlab_http_status(400)
- expect(json_response['message']['title']).to eq(['is invalid'])
+ it 'returns 200 if group label already exists' do
+ create(:group_label, title: label1.name, group: group)
+
+ expect { put api("/projects/#{project.id}/labels/promote", user), params: { name: label1.name } }
+ .to change(project.labels, :count).by(-1)
+ .and change(group.labels, :count).by(0)
+
+ expect(response).to have_gitlab_http_status(200)
end
- it 'returns 400 when color code is too short' do
- put api("/projects/#{project.id}/labels", user),
- params: {
- name: 'label1',
- color: '#FF'
- }
- expect(response).to have_gitlab_http_status(400)
- expect(json_response['message']['color']).to eq(['must be a valid color code'])
+ it 'returns 403 if guest promotes label' do
+ guest = create(:user)
+ project.add_guest(guest)
+
+ put api("/projects/#{project.id}/labels/promote", guest), params: { name: label1.name }
+
+ expect(response).to have_gitlab_http_status(403)
end
- it 'returns 400 for too long color code' do
- put api("/projects/#{project.id}/labels", user),
- params: {
- name: 'label1',
- color: '#FFAAFFFF'
- }
- expect(response).to have_gitlab_http_status(400)
- expect(json_response['message']['color']).to eq(['must be a valid color code'])
+ it 'returns 404 if label does not exist' do
+ put api("/projects/#{project.id}/labels/promote", user), params: { name: 'unknown' }
+
+ expect(response).to have_gitlab_http_status(404)
end
- it 'returns 400 for invalid priority' do
- put api("/projects/#{project.id}/labels", user),
- params: {
- name: 'label1',
- priority: 'foo'
- }
+ it 'returns 400 if no label name given' do
+ put api("/projects/#{project.id}/labels/promote", user)
expect(response).to have_gitlab_http_status(400)
+ expect(json_response['error']).to eq('name is missing')
end
end
diff --git a/spec/requests/api/notes_spec.rb b/spec/requests/api/notes_spec.rb
index 424f0a82e43..6c1e30791d2 100644
--- a/spec/requests/api/notes_spec.rb
+++ b/spec/requests/api/notes_spec.rb
@@ -9,6 +9,13 @@ describe API::Notes do
project.add_reporter(user)
end
+ context 'when there are cross-reference system notes' do
+ let(:url) { "/projects/#{project.id}/merge_requests/#{merge_request.iid}/notes" }
+ let(:notes_in_response) { json_response }
+
+ it_behaves_like 'with cross-reference system notes'
+ end
+
context "when noteable is an Issue" do
let!(:issue) { create(:issue, project: project, author: user) }
let!(:issue_note) { create(:note, noteable: issue, project: project, author: user) }
diff --git a/spec/requests/api/pipelines_spec.rb b/spec/requests/api/pipelines_spec.rb
index 35b3dd219f7..174b3214d13 100644
--- a/spec/requests/api/pipelines_spec.rb
+++ b/spec/requests/api/pipelines_spec.rb
@@ -17,6 +17,8 @@ describe API::Pipelines do
end
describe 'GET /projects/:id/pipelines ' do
+ it_behaves_like 'pipelines visibility table'
+
context 'authorized user' do
it 'returns project pipelines' do
get api("/projects/#{project.id}/pipelines", user)
@@ -401,6 +403,15 @@ describe API::Pipelines do
end
describe 'GET /projects/:id/pipelines/:pipeline_id' do
+ it_behaves_like 'pipelines visibility table' do
+ let(:pipelines_api_path) do
+ "/projects/#{project.id}/pipelines/#{pipeline.id}"
+ end
+
+ let(:api_response) { response_status == 200 ? response : json_response }
+ let(:response_200) { match_response_schema('public_api/v4/pipeline/detail') }
+ end
+
context 'authorized user' do
it 'exposes known attributes' do
get api("/projects/#{project.id}/pipelines/#{pipeline.id}", user)
diff --git a/spec/requests/jwt_controller_spec.rb b/spec/requests/jwt_controller_spec.rb
index bba473f1c20..8b2c698fee1 100644
--- a/spec/requests/jwt_controller_spec.rb
+++ b/spec/requests/jwt_controller_spec.rb
@@ -108,6 +108,14 @@ describe JwtController do
end
end
end
+
+ it 'does not cause session based checks to be activated' do
+ expect(Gitlab::Session).not_to receive(:with_session)
+
+ get '/jwt/auth', params: parameters, headers: headers
+
+ expect(response).to have_gitlab_http_status(200)
+ end
end
context 'using invalid login' do
diff --git a/spec/rubocop/cop/gitlab/union_spec.rb b/spec/rubocop/cop/gitlab/union_spec.rb
index 5b06f30b25f..f0544fdb66e 100644
--- a/spec/rubocop/cop/gitlab/union_spec.rb
+++ b/spec/rubocop/cop/gitlab/union_spec.rb
@@ -16,10 +16,4 @@ describe RuboCop::Cop::Gitlab::Union do
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Use the `FromUnion` concern, instead of using `Gitlab::SQL::Union` directly
SOURCE
end
-
- it 'does not flag the use of Gitlab::SQL::Union in a spec' do
- allow(cop).to receive(:in_spec?).and_return(true)
-
- expect_no_offenses('Gitlab::SQL::Union.new([foo])')
- end
end
diff --git a/spec/rubocop/cop/migration/add_limit_to_string_columns_spec.rb b/spec/rubocop/cop/migration/add_limit_to_string_columns_spec.rb
new file mode 100644
index 00000000000..97a3ae8f2bc
--- /dev/null
+++ b/spec/rubocop/cop/migration/add_limit_to_string_columns_spec.rb
@@ -0,0 +1,268 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require 'rubocop'
+require 'rubocop/rspec/support'
+
+require_relative '../../../../rubocop/cop/migration/add_limit_to_string_columns'
+
+describe RuboCop::Cop::Migration::AddLimitToStringColumns do
+ include CopHelper
+
+ subject(:cop) { described_class.new }
+
+ context 'in migration' do
+ before do
+ allow(cop).to receive(:in_migration?).and_return(true)
+
+ inspect_source(migration)
+ end
+
+ context 'when creating a table' do
+ context 'with string columns and limit' do
+ let(:migration) do
+ %q(
+ class CreateUsers < ActiveRecord::Migration[5.2]
+ DOWNTIME = false
+
+ def change
+ create_table :users do |t|
+ t.string :username, null: false, limit: 255
+ t.timestamps_with_timezone null: true
+ end
+ end
+ end
+ )
+ end
+
+ it 'register no offense' do
+ expect(cop.offenses.size).to eq(0)
+ end
+
+ context 'with limit in a different position' do
+ let(:migration) do
+ %q(
+ class CreateUsers < ActiveRecord::Migration[5.2]
+ DOWNTIME = false
+
+ def change
+ create_table :users do |t|
+ t.string :username, limit: 255, null: false
+ t.timestamps_with_timezone null: true
+ end
+ end
+ end
+ )
+ end
+
+ it 'registers an offense' do
+ expect(cop.offenses.size).to eq(0)
+ end
+ end
+ end
+
+ context 'with string columns and no limit' do
+ let(:migration) do
+ %q(
+ class CreateUsers < ActiveRecord::Migration[5.2]
+ DOWNTIME = false
+
+ def change
+ create_table :users do |t|
+ t.string :username, null: false
+ t.timestamps_with_timezone null: true
+ end
+ end
+ end
+ )
+ end
+
+ it 'registers an offense' do
+ expect(cop.offenses.size).to eq(1)
+ expect(cop.offenses.first.message)
+ .to eq('String columns should have a limit constraint. 255 is suggested')
+ end
+ end
+
+ context 'with no string columns' do
+ let(:migration) do
+ %q(
+ class CreateMilestoneReleases < ActiveRecord::Migration[5.2]
+ DOWNTIME = false
+
+ def change
+ create_table :milestone_releases do |t|
+ t.integer :milestone_id
+ t.integer :release_id
+ end
+ end
+ end
+ )
+ end
+
+ it 'register no offense' do
+ expect(cop.offenses.size).to eq(0)
+ end
+ end
+ end
+
+ context 'when adding columns' do
+ context 'with string columns with limit' do
+ let(:migration) do
+ %q(
+ class AddEmailToUsers < ActiveRecord::Migration[5.2]
+ DOWNTIME = false
+
+ def change
+ add_column :users, :email, :string, limit: 255
+ end
+ end
+ )
+ end
+
+ it 'registers no offense' do
+ expect(cop.offenses.size).to eq(0)
+ end
+
+ context 'with limit in a different position' do
+ let(:migration) do
+ %q(
+ class AddEmailToUsers < ActiveRecord::Migration[5.2]
+ DOWNTIME = false
+
+ def change
+ add_column :users, :email, :string, limit: 255, default: 'example@email.com'
+ end
+ end
+ )
+ end
+
+ it 'registers no offense' do
+ expect(cop.offenses.size).to eq(0)
+ end
+ end
+ end
+
+ context 'with string columns with no limit' do
+ let(:migration) do
+ %q(
+ class AddEmailToUsers < ActiveRecord::Migration[5.2]
+ DOWNTIME = false
+
+ def change
+ add_column :users, :email, :string
+ end
+ end
+ )
+ end
+
+ it 'registers offense' do
+ expect(cop.offenses.size).to eq(1)
+ expect(cop.offenses.first.message)
+ .to eq('String columns should have a limit constraint. 255 is suggested')
+ end
+ end
+
+ context 'with no string columns' do
+ let(:migration) do
+ %q(
+ class AddEmailToUsers < ActiveRecord::Migration[5.2]
+ DOWNTIME = false
+
+ def change
+ add_column :users, :active, :boolean, default: false
+ end
+ end
+ )
+ end
+
+ it 'registers no offense' do
+ expect(cop.offenses.size).to eq(0)
+ end
+ end
+ end
+
+ context 'with add_column_with_default' do
+ context 'with a limit' do
+ let(:migration) do
+ %q(
+ class AddRuleTypeToApprovalMergeRequestRules < ActiveRecord::Migration[5.2]
+ DOWNTIME = false
+
+ def change
+ add_column_with_default(:approval_merge_request_rules, :rule_type, :string, limit: 2, default: 1)
+ end
+ end
+ )
+ end
+
+ it 'registers no offense' do
+ expect(cop.offenses.size).to eq(0)
+ end
+ end
+
+ context 'without a limit' do
+ let(:migration) do
+ %q(
+ class AddRuleTypeToApprovalMergeRequestRules < ActiveRecord::Migration[5.2]
+ DOWNTIME = false
+
+ def change
+ add_column_with_default(:approval_merge_request_rules, :rule_type, :string, default: 1)
+ end
+ end
+ )
+ end
+
+ it 'registers an offense' do
+ expect(cop.offenses.size).to eq(1)
+ end
+ end
+ end
+
+ context 'with methods' do
+ let(:migration) do
+ %q(
+ class AddEmailToUsers < ActiveRecord::Migration[5.2]
+ DOWNTIME = false
+
+ def change
+ add_column_if_table_not_exists :users, :first_name, :string, limit: 255
+ search_namespace(user_name)
+ end
+
+ def add_column_if_not_exists(table, name, *args)
+ add_column(table, name, *args) unless column_exists?(table, name)
+ end
+
+ def search_namespace(username)
+ Uniquify.new.string(username) do |str|
+ query = "SELECT id FROM namespaces WHERE parent_id IS NULL AND path='#{str}' LIMIT 1"
+ connection.exec_query(query)
+ end
+ end
+ end
+ )
+ end
+
+ it 'registers no offense' do
+ expect(cop.offenses.size).to eq(0)
+ end
+ end
+ end
+
+ context 'outside of migrations' do
+ let(:active_record_model) do
+ %q(
+ class User < ApplicationRecord
+ end
+ )
+ end
+
+ it 'registers no offense' do
+ inspect_source(active_record_model)
+
+ expect(cop.offenses.size).to eq(0)
+ end
+ end
+end
diff --git a/spec/rubocop/cop/rspec/env_assignment_spec.rb b/spec/rubocop/cop/rspec/env_assignment_spec.rb
index 659633f6467..621afbad3ba 100644
--- a/spec/rubocop/cop/rspec/env_assignment_spec.rb
+++ b/spec/rubocop/cop/rspec/env_assignment_spec.rb
@@ -33,27 +33,13 @@ describe RuboCop::Cop::RSpec::EnvAssignment do
end
end
- context 'in a spec file' do
- before do
- allow(cop).to receive(:in_spec?).and_return(true)
- end
-
- context 'with a key using single quotes' do
- it_behaves_like 'an offensive ENV#[]= call', OFFENSE_CALL_SINGLE_QUOTES_KEY
- it_behaves_like 'an autocorrected ENV#[]= call', OFFENSE_CALL_SINGLE_QUOTES_KEY, %(stub_env('FOO', 'bar'))
- end
-
- context 'with a key using double quotes' do
- it_behaves_like 'an offensive ENV#[]= call', OFFENSE_CALL_DOUBLE_QUOTES_KEY
- it_behaves_like 'an autocorrected ENV#[]= call', OFFENSE_CALL_DOUBLE_QUOTES_KEY, %(stub_env("FOO", 'bar'))
- end
+ context 'with a key using single quotes' do
+ it_behaves_like 'an offensive ENV#[]= call', OFFENSE_CALL_SINGLE_QUOTES_KEY
+ it_behaves_like 'an autocorrected ENV#[]= call', OFFENSE_CALL_SINGLE_QUOTES_KEY, %(stub_env('FOO', 'bar'))
end
- context 'outside of a spec file' do
- it "does not register an offense for `#{OFFENSE_CALL_SINGLE_QUOTES_KEY}` in a non-spec file" do
- inspect_source(OFFENSE_CALL_SINGLE_QUOTES_KEY)
-
- expect(cop.offenses.size).to eq(0)
- end
+ context 'with a key using double quotes' do
+ it_behaves_like 'an offensive ENV#[]= call', OFFENSE_CALL_DOUBLE_QUOTES_KEY
+ it_behaves_like 'an autocorrected ENV#[]= call', OFFENSE_CALL_DOUBLE_QUOTES_KEY, %(stub_env("FOO", 'bar'))
end
end
diff --git a/spec/rubocop/cop/rspec/factories_in_migration_specs_spec.rb b/spec/rubocop/cop/rspec/factories_in_migration_specs_spec.rb
index 2763f2bda21..94324bc615d 100644
--- a/spec/rubocop/cop/rspec/factories_in_migration_specs_spec.rb
+++ b/spec/rubocop/cop/rspec/factories_in_migration_specs_spec.rb
@@ -8,8 +8,6 @@ require_relative '../../../../rubocop/cop/rspec/factories_in_migration_specs'
describe RuboCop::Cop::RSpec::FactoriesInMigrationSpecs do
include CopHelper
- let(:source_file) { 'spec/migrations/foo_spec.rb' }
-
subject(:cop) { described_class.new }
shared_examples 'an offensive factory call' do |namespace|
@@ -27,22 +25,6 @@ describe RuboCop::Cop::RSpec::FactoriesInMigrationSpecs do
end
end
- context 'in a migration spec file' do
- before do
- allow(cop).to receive(:in_migration_spec?).and_return(true)
- end
-
- it_behaves_like 'an offensive factory call', ''
- it_behaves_like 'an offensive factory call', 'FactoryBot.'
- end
-
- context 'outside of a migration spec file' do
- it "does not register an offense" do
- expect_no_offenses(<<-RUBY)
- describe 'foo' do
- let(:user) { create(:user) }
- end
- RUBY
- end
- end
+ it_behaves_like 'an offensive factory call', ''
+ it_behaves_like 'an offensive factory call', 'FactoryBot.'
end
diff --git a/spec/services/application_settings/update_service_spec.rb b/spec/services/application_settings/update_service_spec.rb
index adb5219d691..ab06c1a1209 100644
--- a/spec/services/application_settings/update_service_spec.rb
+++ b/spec/services/application_settings/update_service_spec.rb
@@ -201,6 +201,24 @@ describe ApplicationSettings::UpdateService do
enable_external_authorization_service_check
end
+ it 'does not validate labels if external authorization gets disabled' do
+ expect_any_instance_of(described_class).not_to receive(:validate_classification_label)
+
+ described_class.new(application_settings, admin, { external_authorization_service_enabled: false }).execute
+ end
+
+ it 'does validate labels if external authorization gets enabled ' do
+ expect_any_instance_of(described_class).to receive(:validate_classification_label)
+
+ described_class.new(application_settings, admin, { external_authorization_service_enabled: true }).execute
+ end
+
+ it 'does validate labels if external authorization is left unchanged' do
+ expect_any_instance_of(described_class).to receive(:validate_classification_label)
+
+ described_class.new(application_settings, admin, { external_authorization_service_default_label: 'new-label' }).execute
+ end
+
it 'does not save the settings with an error if the service denies access' do
expect(::Gitlab::ExternalAuthorization)
.to receive(:access_allowed?).with(admin, 'new-label') { false }
diff --git a/spec/services/ci/update_build_queue_service_spec.rb b/spec/services/ci/update_build_queue_service_spec.rb
index 4b869385128..522dd1ba1c2 100644
--- a/spec/services/ci/update_build_queue_service_spec.rb
+++ b/spec/services/ci/update_build_queue_service_spec.rb
@@ -7,84 +7,108 @@ describe Ci::UpdateBuildQueueService do
let(:build) { create(:ci_build, pipeline: pipeline) }
let(:pipeline) { create(:ci_pipeline, project: project) }
- context 'when updating specific runners' do
- let(:runner) { create(:ci_runner, :project, projects: [project]) }
-
- context 'when there is a runner that can pick build' do
- it 'ticks runner queue value' do
- expect { subject.execute(build) }.to change { runner.ensure_runner_queue_value }
- end
+ shared_examples 'refreshes runner' do
+ it 'ticks runner queue value' do
+ expect { subject.execute(build) }.to change { runner.ensure_runner_queue_value }
end
+ end
- context 'when there is no runner that can pick build' do
- let(:another_project) { create(:project) }
- let(:runner) { create(:ci_runner, :project, projects: [another_project]) }
-
- it 'does not tick runner queue value' do
- expect { subject.execute(build) }.not_to change { runner.ensure_runner_queue_value }
- end
+ shared_examples 'does not refresh runner' do
+ it 'ticks runner queue value' do
+ expect { subject.execute(build) }.not_to change { runner.ensure_runner_queue_value }
end
end
- context 'when updating shared runners' do
- let(:runner) { create(:ci_runner, :instance) }
-
- context 'when there is no runner that can pick build' do
- it 'ticks runner queue value' do
- expect { subject.execute(build) }.to change { runner.ensure_runner_queue_value }
+ shared_examples 'matching build' do
+ context 'when there is a online runner that can pick build' do
+ before do
+ runner.update!(contacted_at: 30.minutes.ago)
end
+
+ it_behaves_like 'refreshes runner'
end
+ end
+ shared_examples 'mismatching tags' do
context 'when there is no runner that can pick build due to tag mismatch' do
before do
build.tag_list = [:docker]
end
- it 'does not tick runner queue value' do
- expect { subject.execute(build) }.not_to change { runner.ensure_runner_queue_value }
- end
+ it_behaves_like 'does not refresh runner'
end
+ end
- context 'when there is no runner that can pick build due to being disabled on project' do
+ shared_examples 'recent runner queue' do
+ context 'when there is runner with expired cache' do
before do
- build.project.shared_runners_enabled = false
+ runner.update!(contacted_at: Ci::Runner.recent_queue_deadline)
end
- it 'does not tick runner queue value' do
- expect { subject.execute(build) }.not_to change { runner.ensure_runner_queue_value }
+ context 'when ci_update_queues_for_online_runners is enabled' do
+ before do
+ stub_feature_flags(ci_update_queues_for_online_runners: true)
+ end
+
+ it_behaves_like 'does not refresh runner'
+ end
+
+ context 'when ci_update_queues_for_online_runners is disabled' do
+ before do
+ stub_feature_flags(ci_update_queues_for_online_runners: false)
+ end
+
+ it_behaves_like 'refreshes runner'
end
end
end
- context 'when updating group runners' do
- let(:group) { create(:group) }
- let(:project) { create(:project, group: group) }
- let(:runner) { create(:ci_runner, :group, groups: [group]) }
+ context 'when updating specific runners' do
+ let(:runner) { create(:ci_runner, :project, projects: [project]) }
- context 'when there is a runner that can pick build' do
- it 'ticks runner queue value' do
- expect { subject.execute(build) }.to change { runner.ensure_runner_queue_value }
- end
+ it_behaves_like 'matching build'
+ it_behaves_like 'mismatching tags'
+ it_behaves_like 'recent runner queue'
+
+ context 'when the runner is assigned to another project' do
+ let(:another_project) { create(:project) }
+ let(:runner) { create(:ci_runner, :project, projects: [another_project]) }
+
+ it_behaves_like 'does not refresh runner'
end
+ end
- context 'when there is no runner that can pick build due to tag mismatch' do
+ context 'when updating shared runners' do
+ let(:runner) { create(:ci_runner, :instance) }
+
+ it_behaves_like 'matching build'
+ it_behaves_like 'mismatching tags'
+ it_behaves_like 'recent runner queue'
+
+ context 'when there is no runner that can pick build due to being disabled on project' do
before do
- build.tag_list = [:docker]
+ build.project.shared_runners_enabled = false
end
- it 'does not tick runner queue value' do
- expect { subject.execute(build) }.not_to change { runner.ensure_runner_queue_value }
- end
+ it_behaves_like 'does not refresh runner'
end
+ end
+
+ context 'when updating group runners' do
+ let(:group) { create(:group) }
+ let(:project) { create(:project, group: group) }
+ let(:runner) { create(:ci_runner, :group, groups: [group]) }
+
+ it_behaves_like 'matching build'
+ it_behaves_like 'mismatching tags'
+ it_behaves_like 'recent runner queue'
context 'when there is no runner that can pick build due to being disabled on project' do
before do
build.project.group_runners_enabled = false
end
- it 'does not tick runner queue value' do
- expect { subject.execute(build) }.not_to change { runner.ensure_runner_queue_value }
- end
+ it_behaves_like 'does not refresh runner'
end
end
end
diff --git a/spec/services/merge_requests/create_service_spec.rb b/spec/services/merge_requests/create_service_spec.rb
index ed48f4b1e44..699f2a98088 100644
--- a/spec/services/merge_requests/create_service_spec.rb
+++ b/spec/services/merge_requests/create_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe MergeRequests::CreateService do
+describe MergeRequests::CreateService, :clean_gitlab_redis_shared_state do
include ProjectForksHelper
let(:project) { create(:project, :repository) }
@@ -285,6 +285,12 @@ describe MergeRequests::CreateService do
end
end
end
+
+ it 'increments the usage data counter of create event' do
+ counter = Gitlab::UsageDataCounters::MergeRequestCounter
+
+ expect { service.execute }.to change { counter.read(:create) }.by(1)
+ end
end
it_behaves_like 'new issuable record that supports quick actions' do
diff --git a/spec/services/projects/forks_count_service_spec.rb b/spec/services/projects/forks_count_service_spec.rb
index 7e35648e9ff..1b44782468a 100644
--- a/spec/services/projects/forks_count_service_spec.rb
+++ b/spec/services/projects/forks_count_service_spec.rb
@@ -2,15 +2,17 @@
require 'spec_helper'
-describe Projects::ForksCountService do
+describe Projects::ForksCountService, :use_clean_rails_memory_store_caching do
+ let(:project) { build(:project) }
+ subject { described_class.new(project) }
+
+ it_behaves_like 'a counter caching service'
+
describe '#count' do
it 'returns the number of forks' do
- project = build(:project, id: 42)
- service = described_class.new(project)
-
- allow(service).to receive(:uncached_count).and_return(1)
+ allow(subject).to receive(:uncached_count).and_return(1)
- expect(service.count).to eq(1)
+ expect(subject.count).to eq(1)
end
end
end
diff --git a/spec/services/projects/open_issues_count_service_spec.rb b/spec/services/projects/open_issues_count_service_spec.rb
index 8efa34765d0..593a4df1f8f 100644
--- a/spec/services/projects/open_issues_count_service_spec.rb
+++ b/spec/services/projects/open_issues_count_service_spec.rb
@@ -2,10 +2,13 @@
require 'spec_helper'
-describe Projects::OpenIssuesCountService do
- describe '#count' do
- let(:project) { create(:project) }
+describe Projects::OpenIssuesCountService, :use_clean_rails_memory_store_caching do
+ let(:project) { create(:project) }
+ subject { described_class.new(project) }
+
+ it_behaves_like 'a counter caching service'
+ describe '#count' do
context 'when user is nil' do
it 'does not include confidential issues in the issue count' do
create(:issue, :opened, project: project)
@@ -53,9 +56,7 @@ describe Projects::OpenIssuesCountService do
end
end
- context '#refresh_cache', :use_clean_rails_memory_store_caching do
- let(:subject) { described_class.new(project) }
-
+ context '#refresh_cache' do
before do
create(:issue, :opened, project: project)
create(:issue, :opened, project: project)
diff --git a/spec/services/projects/open_merge_requests_count_service_spec.rb b/spec/services/projects/open_merge_requests_count_service_spec.rb
index 0d8227f7db5..f9fff4cbd4c 100644
--- a/spec/services/projects/open_merge_requests_count_service_spec.rb
+++ b/spec/services/projects/open_merge_requests_count_service_spec.rb
@@ -2,16 +2,21 @@
require 'spec_helper'
-describe Projects::OpenMergeRequestsCountService do
+describe Projects::OpenMergeRequestsCountService, :use_clean_rails_memory_store_caching do
+ set(:project) { create(:project) }
+
+ subject { described_class.new(project) }
+
+ it_behaves_like 'a counter caching service'
+
describe '#count' do
it 'returns the number of open merge requests' do
- project = create(:project)
create(:merge_request,
:opened,
source_project: project,
target_project: project)
- expect(described_class.new(project).count).to eq(1)
+ expect(subject.count).to eq(1)
end
end
end
diff --git a/spec/services/users/keys_count_service_spec.rb b/spec/services/users/keys_count_service_spec.rb
index bee8380e8b7..6b7493f343f 100644
--- a/spec/services/users/keys_count_service_spec.rb
+++ b/spec/services/users/keys_count_service_spec.rb
@@ -4,7 +4,9 @@ require 'spec_helper'
describe Users::KeysCountService, :use_clean_rails_memory_store_caching do
let(:user) { create(:user) }
- let(:service) { described_class.new(user) }
+ subject { described_class.new(user) }
+
+ it_behaves_like 'a counter caching service'
describe '#count' do
before do
@@ -12,53 +14,19 @@ describe Users::KeysCountService, :use_clean_rails_memory_store_caching do
end
it 'returns the number of SSH keys as an Integer' do
- expect(service.count).to eq(1)
- end
-
- it 'caches the number of keys in Redis', :request_store do
- service.delete_cache
- control_count = ActiveRecord::QueryRecorder.new { service.count }.count
- service.delete_cache
-
- expect { 2.times { service.count } }.not_to exceed_query_limit(control_count)
- end
- end
-
- describe '#refresh_cache' do
- it 'refreshes the Redis cache' do
- Rails.cache.write(service.cache_key, 10)
- service.refresh_cache
-
- expect(Rails.cache.fetch(service.cache_key, raw: true)).to be_zero
- end
- end
-
- describe '#delete_cache' do
- it 'removes the cache' do
- service.count
- service.delete_cache
-
- expect(Rails.cache.fetch(service.cache_key, raw: true)).to be_nil
+ expect(subject.count).to eq(1)
end
end
describe '#uncached_count' do
it 'returns the number of SSH keys' do
- expect(service.uncached_count).to be_zero
- end
-
- it 'does not cache the number of keys' do
- recorder = ActiveRecord::QueryRecorder.new do
- 2.times { service.uncached_count }
- end
-
- expect(recorder.count).to be > 0
+ expect(subject.uncached_count).to be_zero
end
end
describe '#cache_key' do
it 'returns the cache key' do
- expect(service.cache_key).to eq("users/key-count-service/#{user.id}")
+ expect(subject.cache_key).to eq("users/key-count-service/#{user.id}")
end
end
end
diff --git a/spec/services/web_hook_service_spec.rb b/spec/services/web_hook_service_spec.rb
index 50167a2e059..2a4368868d5 100644
--- a/spec/services/web_hook_service_spec.rb
+++ b/spec/services/web_hook_service_spec.rb
@@ -55,31 +55,38 @@ describe WebHookService do
describe '#execute' do
before do
project.hooks << [project_hook]
-
- WebMock.stub_request(:post, project_hook.url)
end
context 'when token is defined' do
let(:project_hook) { create(:project_hook, :token) }
it 'POSTs to the webhook URL' do
+ stub_full_request(project_hook.url, method: :post)
+
service_instance.execute
- expect(WebMock).to have_requested(:post, project_hook.url).with(
+
+ expect(WebMock).to have_requested(:post, stubbed_hostname(project_hook.url)).with(
headers: headers.merge({ 'X-Gitlab-Token' => project_hook.token })
).once
end
end
it 'POSTs to the webhook URL' do
+ stub_full_request(project_hook.url, method: :post)
+
service_instance.execute
- expect(WebMock).to have_requested(:post, project_hook.url).with(
+
+ expect(WebMock).to have_requested(:post, stubbed_hostname(project_hook.url)).with(
headers: headers
).once
end
it 'POSTs the data as JSON' do
+ stub_full_request(project_hook.url, method: :post)
+
service_instance.execute
- expect(WebMock).to have_requested(:post, project_hook.url).with(
+
+ expect(WebMock).to have_requested(:post, stubbed_hostname(project_hook.url)).with(
headers: headers
).once
end
@@ -115,7 +122,7 @@ describe WebHookService do
end
it 'catches exceptions' do
- WebMock.stub_request(:post, project_hook.url).to_raise(StandardError.new('Some error'))
+ stub_full_request(project_hook.url, method: :post).to_raise(StandardError.new('Some error'))
expect { service_instance.execute }.to raise_error(StandardError)
end
@@ -125,20 +132,20 @@ describe WebHookService do
exceptions.each do |exception_class|
exception = exception_class.new('Exception message')
- WebMock.stub_request(:post, project_hook.url).to_raise(exception)
+ stub_full_request(project_hook.url, method: :post).to_raise(exception)
expect(service_instance.execute).to eq({ status: :error, message: exception.to_s })
expect { service_instance.execute }.not_to raise_error
end
end
it 'handles 200 status code' do
- WebMock.stub_request(:post, project_hook.url).to_return(status: 200, body: 'Success')
+ stub_full_request(project_hook.url, method: :post).to_return(status: 200, body: 'Success')
expect(service_instance.execute).to include({ status: :success, http_status: 200, message: 'Success' })
end
it 'handles 2xx status codes' do
- WebMock.stub_request(:post, project_hook.url).to_return(status: 201, body: 'Success')
+ stub_full_request(project_hook.url, method: :post).to_return(status: 201, body: 'Success')
expect(service_instance.execute).to include({ status: :success, http_status: 201, message: 'Success' })
end
@@ -148,7 +155,7 @@ describe WebHookService do
context 'with success' do
before do
- WebMock.stub_request(:post, project_hook.url).to_return(status: 200, body: 'Success')
+ stub_full_request(project_hook.url, method: :post).to_return(status: 200, body: 'Success')
service_instance.execute
end
@@ -165,7 +172,7 @@ describe WebHookService do
context 'with exception' do
before do
- WebMock.stub_request(:post, project_hook.url).to_raise(SocketError.new('Some HTTP Post error'))
+ stub_full_request(project_hook.url, method: :post).to_raise(SocketError.new('Some HTTP Post error'))
service_instance.execute
end
@@ -182,7 +189,7 @@ describe WebHookService do
context 'with unsafe response body' do
before do
- WebMock.stub_request(:post, project_hook.url).to_return(status: 200, body: "\xBB")
+ stub_full_request(project_hook.url, method: :post).to_return(status: 200, body: "\xBB")
service_instance.execute
end
@@ -202,7 +209,7 @@ describe WebHookService do
let(:service_instance) { described_class.new(service_hook, data, 'service_hook') }
before do
- WebMock.stub_request(:post, service_hook.url).to_return(status: 200, body: 'Success')
+ stub_full_request(service_hook.url, method: :post).to_return(status: 200, body: 'Success')
end
it { expect { service_instance.execute }.not_to change(WebHookLog, :count) }
diff --git a/spec/support/capybara.rb b/spec/support/capybara.rb
index 8accc5c1df5..4c688094352 100644
--- a/spec/support/capybara.rb
+++ b/spec/support/capybara.rb
@@ -47,6 +47,9 @@ Capybara.register_driver :chrome do |app|
# Explicitly set user-data-dir to prevent crashes. See https://gitlab.com/gitlab-org/gitlab-ce/issues/58882#note_179811508
options.add_argument("user-data-dir=/tmp/chrome") if ENV['CI'] || ENV['CI_SERVER']
+ # Chrome 75 defaults to W3C mode which doesn't allow console log access
+ options.add_option(:w3c, false)
+
Capybara::Selenium::Driver.new(
app,
browser: :chrome,
diff --git a/spec/support/helpers/drag_to_helper.rb b/spec/support/helpers/drag_to_helper.rb
index 6099f87323f..2e9932f2e8a 100644
--- a/spec/support/helpers/drag_to_helper.rb
+++ b/spec/support/helpers/drag_to_helper.rb
@@ -1,8 +1,23 @@
# frozen_string_literal: true
module DragTo
- def drag_to(list_from_index: 0, from_index: 0, to_index: 0, list_to_index: 0, selector: '', scrollable: 'body', duration: 1000)
- evaluate_script("simulateDrag({scrollable: $('#{scrollable}').get(0), duration: #{duration}, from: {el: $('#{selector}').eq(#{list_from_index}).get(0), index: #{from_index}}, to: {el: $('#{selector}').eq(#{list_to_index}).get(0), index: #{to_index}}});")
+ def drag_to(list_from_index: 0, from_index: 0, to_index: 0, list_to_index: 0, selector: '', scrollable: 'body', duration: 1000, perform_drop: true)
+ js = <<~JS
+ simulateDrag({
+ scrollable: document.querySelector('#{scrollable}'),
+ duration: #{duration},
+ from: {
+ el: document.querySelectorAll('#{selector}')[#{list_from_index}],
+ index: #{from_index}
+ },
+ to: {
+ el: document.querySelectorAll('#{selector}')[#{list_to_index}],
+ index: #{to_index}
+ },
+ performDrop: #{perform_drop}
+ });
+ JS
+ evaluate_script(js)
Timeout.timeout(Capybara.default_max_wait_time) do
loop while drag_active?
diff --git a/spec/support/helpers/stub_configuration.rb b/spec/support/helpers/stub_configuration.rb
index c8b2bf040e6..dec7898d8d2 100644
--- a/spec/support/helpers/stub_configuration.rb
+++ b/spec/support/helpers/stub_configuration.rb
@@ -30,6 +30,10 @@ module StubConfiguration
allow(Gitlab.config.gitlab).to receive_messages(to_settings(messages))
end
+ def stub_config(messages)
+ allow(Gitlab.config).to receive_messages(to_settings(messages))
+ end
+
def stub_default_url_options(host: "localhost", protocol: "http")
url_options = { host: host, protocol: protocol }
allow(Rails.application.routes).to receive(:default_url_options).and_return(url_options)
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 fd24c443288..b89723b1e1a 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,8 @@ RSpec.shared_context 'GroupPolicy context' do
:admin_group_member,
:change_visibility_level,
:set_note_created_at,
- :create_subgroup
+ :create_subgroup,
+ :read_statistics
].compact
end
diff --git a/spec/support/shared_examples/cycle_analytics_stage_examples.rb b/spec/support/shared_examples/cycle_analytics_stage_examples.rb
new file mode 100644
index 00000000000..151f5325e84
--- /dev/null
+++ b/spec/support/shared_examples/cycle_analytics_stage_examples.rb
@@ -0,0 +1,74 @@
+# frozen_string_literal: true
+
+shared_examples_for 'cycle analytics stage' do
+ let(:valid_params) do
+ {
+ name: 'My Stage',
+ parent: parent,
+ start_event_identifier: :merge_request_created,
+ end_event_identifier: :merge_request_merged
+ }
+ end
+
+ describe 'validation' do
+ it 'is valid' do
+ expect(described_class.new(valid_params)).to be_valid
+ end
+
+ it 'validates presence of parent' do
+ stage = described_class.new(valid_params.except(:parent))
+
+ expect(stage).not_to be_valid
+ expect(stage.errors.details[parent_name]).to eq([{ error: :blank }])
+ end
+
+ it 'validates presence of start_event_identifier' do
+ stage = described_class.new(valid_params.except(:start_event_identifier))
+
+ expect(stage).not_to be_valid
+ expect(stage.errors.details[:start_event_identifier]).to eq([{ error: :blank }])
+ end
+
+ it 'validates presence of end_event_identifier' do
+ stage = described_class.new(valid_params.except(:end_event_identifier))
+
+ expect(stage).not_to be_valid
+ expect(stage.errors.details[:end_event_identifier]).to eq([{ error: :blank }])
+ end
+
+ it 'is invalid when end_event is not allowed for the given start_event' do
+ invalid_params = valid_params.merge(
+ start_event_identifier: :merge_request_merged,
+ end_event_identifier: :merge_request_created
+ )
+ stage = described_class.new(invalid_params)
+
+ expect(stage).not_to be_valid
+ expect(stage.errors.details[:end_event]).to eq([{ error: :not_allowed_for_the_given_start_event }])
+ end
+ end
+
+ describe '#subject_model' do
+ it 'infers the model from the start event' do
+ stage = described_class.new(valid_params)
+
+ expect(stage.subject_model).to eq(MergeRequest)
+ end
+ end
+
+ describe '#start_event' do
+ it 'builds start_event object based on start_event_identifier' do
+ stage = described_class.new(start_event_identifier: 'merge_request_created')
+
+ expect(stage.start_event).to be_a_kind_of(Gitlab::Analytics::CycleAnalytics::StageEvents::MergeRequestCreated)
+ end
+ end
+
+ describe '#end_event' do
+ it 'builds end_event object based on end_event_identifier' do
+ stage = described_class.new(end_event_identifier: 'merge_request_merged')
+
+ expect(stage.end_event).to be_a_kind_of(Gitlab::Analytics::CycleAnalytics::StageEvents::MergeRequestMerged)
+ end
+ end
+end
diff --git a/spec/support/shared_examples/quick_actions/issue/move_quick_action_shared_examples.rb b/spec/support/shared_examples/quick_actions/issue/move_quick_action_shared_examples.rb
index a37b2392d52..bebc8509d53 100644
--- a/spec/support/shared_examples/quick_actions/issue/move_quick_action_shared_examples.rb
+++ b/spec/support/shared_examples/quick_actions/issue/move_quick_action_shared_examples.rb
@@ -89,5 +89,54 @@ shared_examples 'move quick action' do
it_behaves_like 'applies the commands to issues in both projects, target and source'
end
end
+
+ context 'when editing comments' do
+ let(:target_project) { create(:project, :public) }
+
+ before do
+ target_project.add_maintainer(user)
+
+ sign_in(user)
+ visit project_issue_path(project, issue)
+ wait_for_all_requests
+ end
+
+ it 'moves the issue after quickcommand note was updated' do
+ # misspelled quick action
+ add_note("test note.\n/mvoe #{target_project.full_path}")
+
+ expect(issue.reload).not_to be_closed
+
+ edit_note("/mvoe #{target_project.full_path}", "test note.\n/move #{target_project.full_path}")
+ wait_for_all_requests
+
+ expect(page).to have_content 'test note.'
+ expect(issue.reload).to be_closed
+
+ visit project_issue_path(target_project, issue)
+ wait_for_all_requests
+
+ expect(page).to have_content 'Issues 1'
+ end
+
+ it 'deletes the note if it was updated to just contain a command' do
+ # missspelled quick action
+ add_note("test note.\n/mvoe #{target_project.full_path}")
+
+ expect(page).not_to have_content 'Commands applied'
+ expect(issue.reload).not_to be_closed
+
+ edit_note("/mvoe #{target_project.full_path}", "/move #{target_project.full_path}")
+ wait_for_all_requests
+
+ expect(page).not_to have_content "/move #{target_project.full_path}"
+ expect(issue.reload).to be_closed
+
+ visit project_issue_path(target_project, issue)
+ wait_for_all_requests
+
+ expect(page).to have_content 'Issues 1'
+ end
+ end
end
end
diff --git a/spec/support/shared_examples/requests/api/discussions.rb b/spec/support/shared_examples/requests/api/discussions.rb
index fc72287f265..a36bc2dc9b5 100644
--- a/spec/support/shared_examples/requests/api/discussions.rb
+++ b/spec/support/shared_examples/requests/api/discussions.rb
@@ -1,5 +1,59 @@
# frozen_string_literal: true
+shared_examples 'with cross-reference system notes' do
+ let(:merge_request) { create(:merge_request) }
+ let(:project) { merge_request.project }
+ let(:new_merge_request) { create(:merge_request) }
+ let(:commit) { new_merge_request.project.commit }
+ let!(:note) { create(:system_note, noteable: merge_request, project: project, note: cross_reference) }
+ let!(:note_metadata) { create(:system_note_metadata, note: note, action: 'cross_reference') }
+ let(:cross_reference) { "test commit #{commit.to_reference(project)}" }
+ let(:pat) { create(:personal_access_token, user: user) }
+
+ before do
+ project.add_developer(user)
+ new_merge_request.project.add_developer(user)
+
+ hidden_merge_request = create(:merge_request)
+ new_cross_reference = "test commit #{hidden_merge_request.project.commit}"
+ new_note = create(:system_note, noteable: merge_request, project: project, note: new_cross_reference)
+ create(:system_note_metadata, note: new_note, action: 'cross_reference')
+ end
+
+ it 'returns only the note that the user should see' do
+ get api(url, user, personal_access_token: pat)
+
+ expect(response).to have_gitlab_http_status(200)
+ expect(json_response.count).to eq(1)
+ expect(notes_in_response.count).to eq(1)
+
+ parsed_note = notes_in_response.first
+ expect(parsed_note['id']).to eq(note.id)
+ expect(parsed_note['body']).to eq(cross_reference)
+ expect(parsed_note['system']).to be true
+ end
+
+ it 'avoids Git calls and N+1 SQL queries', :request_store do
+ expect_any_instance_of(Repository).not_to receive(:find_commit).with(commit.id)
+
+ control = ActiveRecord::QueryRecorder.new do
+ get api(url, user, personal_access_token: pat)
+ end
+
+ expect(response).to have_gitlab_http_status(200)
+
+ RequestStore.clear!
+
+ new_note = create(:system_note, noteable: merge_request, project: project, note: cross_reference)
+ create(:system_note_metadata, note: new_note, action: 'cross_reference')
+
+ RequestStore.clear!
+
+ expect { get api(url, user, personal_access_token: pat) }.not_to exceed_query_limit(control)
+ expect(response).to have_gitlab_http_status(200)
+ end
+end
+
shared_examples 'discussions API' do |parent_type, noteable_type, id_name, can_reply_to_individual_notes: false|
describe "GET /#{parent_type}/:id/#{noteable_type}/:noteable_id/discussions" do
it "returns an array of discussions" do
diff --git a/spec/support/shared_examples/requests/api/pipelines/visibility_table_examples.rb b/spec/support/shared_examples/requests/api/pipelines/visibility_table_examples.rb
new file mode 100644
index 00000000000..dfd07176b1c
--- /dev/null
+++ b/spec/support/shared_examples/requests/api/pipelines/visibility_table_examples.rb
@@ -0,0 +1,235 @@
+# frozen_string_literal: true
+
+shared_examples 'pipelines visibility table' do
+ using RSpec::Parameterized::TableSyntax
+
+ let(:ci_user) { create(:user) }
+ let(:api_user) { user_role && ci_user }
+
+ let(:pipelines_api_path) do
+ "/projects/#{project.id}/pipelines"
+ end
+
+ let(:response_200) do
+ a_collection_containing_exactly(
+ a_hash_including('sha', 'ref', 'status', 'web_url', 'id' => pipeline.id)
+ )
+ end
+
+ let(:response_40x) do
+ a_hash_including('message')
+ end
+
+ let(:expected_response) do
+ if response_status == 200
+ response_200
+ else
+ response_40x
+ end
+ end
+
+ let(:api_response) { json_response }
+
+ let(:visibility_levels) do
+ {
+ private: Gitlab::VisibilityLevel::PRIVATE,
+ internal: Gitlab::VisibilityLevel::INTERNAL,
+ public: Gitlab::VisibilityLevel::PUBLIC
+ }
+ end
+
+ let(:builds_access_levels) do
+ {
+ enabled: ProjectFeature::ENABLED,
+ private: ProjectFeature::PRIVATE
+ }
+ end
+
+ let(:project_attributes) do
+ {
+ visibility_level: visibility_levels[visibility_level],
+ public_builds: public_builds
+ }
+ end
+
+ let(:project_feature_attributes) do
+ {
+ builds_access_level: builds_access_levels[builds_access_level]
+ }
+ end
+
+ where(:visibility_level, :builds_access_level, :public_builds, :is_admin, :user_role, :response_status) do
+ :private | :enabled | true | true | :non_member | 200
+ :private | :enabled | true | true | :guest | 200
+ :private | :enabled | true | true | :reporter | 200
+ :private | :enabled | true | true | :developer | 200
+ :private | :enabled | true | true | :maintainer | 200
+
+ :private | :enabled | true | false | nil | 404
+ :private | :enabled | true | false | :non_member | 404
+ :private | :enabled | true | false | :guest | 200
+ :private | :enabled | true | false | :reporter | 200
+ :private | :enabled | true | false | :developer | 200
+ :private | :enabled | true | false | :maintainer | 200
+
+ :private | :enabled | false | true | :non_member | 200
+ :private | :enabled | false | true | :guest | 200
+ :private | :enabled | false | true | :reporter | 200
+ :private | :enabled | false | true | :developer | 200
+ :private | :enabled | false | true | :maintainer | 200
+
+ :private | :enabled | false | false | nil | 404
+ :private | :enabled | false | false | :non_member | 404
+ :private | :enabled | false | false | :guest | 403
+ :private | :enabled | false | false | :reporter | 200
+ :private | :enabled | false | false | :developer | 200
+ :private | :enabled | false | false | :maintainer | 200
+
+ :private | :private | true | true | :non_member | 200
+ :private | :private | true | true | :guest | 200
+ :private | :private | true | true | :reporter | 200
+ :private | :private | true | true | :developer | 200
+ :private | :private | true | true | :maintainer | 200
+
+ :private | :private | true | false | nil | 404
+ :private | :private | true | false | :non_member | 404
+ :private | :private | true | false | :guest | 200
+ :private | :private | true | false | :reporter | 200
+ :private | :private | true | false | :developer | 200
+ :private | :private | true | false | :maintainer | 200
+
+ :private | :private | false | true | :non_member | 200
+ :private | :private | false | true | :guest | 200
+ :private | :private | false | true | :reporter | 200
+ :private | :private | false | true | :developer | 200
+ :private | :private | false | true | :maintainer | 200
+
+ :private | :private | false | false | nil | 404
+ :private | :private | false | false | :non_member | 404
+ :private | :private | false | false | :guest | 403
+ :private | :private | false | false | :reporter | 200
+ :private | :private | false | false | :developer | 200
+ :private | :private | false | false | :maintainer | 200
+
+ :internal | :enabled | true | true | :non_member | 200
+ :internal | :enabled | true | true | :guest | 200
+ :internal | :enabled | true | true | :reporter | 200
+ :internal | :enabled | true | true | :developer | 200
+ :internal | :enabled | true | true | :maintainer | 200
+
+ :internal | :enabled | true | false | nil | 404
+ :internal | :enabled | true | false | :non_member | 200
+ :internal | :enabled | true | false | :guest | 200
+ :internal | :enabled | true | false | :reporter | 200
+ :internal | :enabled | true | false | :developer | 200
+ :internal | :enabled | true | false | :maintainer | 200
+
+ :internal | :enabled | false | true | :non_member | 200
+ :internal | :enabled | false | true | :guest | 200
+ :internal | :enabled | false | true | :reporter | 200
+ :internal | :enabled | false | true | :developer | 200
+ :internal | :enabled | false | true | :maintainer | 200
+
+ :internal | :enabled | false | false | nil | 404
+ :internal | :enabled | false | false | :non_member | 403
+ :internal | :enabled | false | false | :guest | 403
+ :internal | :enabled | false | false | :reporter | 200
+ :internal | :enabled | false | false | :developer | 200
+ :internal | :enabled | false | false | :maintainer | 200
+
+ :internal | :private | true | true | :non_member | 200
+ :internal | :private | true | true | :guest | 200
+ :internal | :private | true | true | :reporter | 200
+ :internal | :private | true | true | :developer | 200
+ :internal | :private | true | true | :maintainer | 200
+
+ :internal | :private | true | false | nil | 404
+ :internal | :private | true | false | :non_member | 403
+ :internal | :private | true | false | :guest | 200
+ :internal | :private | true | false | :reporter | 200
+ :internal | :private | true | false | :developer | 200
+ :internal | :private | true | false | :maintainer | 200
+
+ :internal | :private | false | true | :non_member | 200
+ :internal | :private | false | true | :guest | 200
+ :internal | :private | false | true | :reporter | 200
+ :internal | :private | false | true | :developer | 200
+ :internal | :private | false | true | :maintainer | 200
+
+ :internal | :private | false | false | nil | 404
+ :internal | :private | false | false | :non_member | 403
+ :internal | :private | false | false | :guest | 403
+ :internal | :private | false | false | :reporter | 200
+ :internal | :private | false | false | :developer | 200
+ :internal | :private | false | false | :maintainer | 200
+
+ :public | :enabled | true | true | :non_member | 200
+ :public | :enabled | true | true | :guest | 200
+ :public | :enabled | true | true | :reporter | 200
+ :public | :enabled | true | true | :developer | 200
+ :public | :enabled | true | true | :maintainer | 200
+
+ :public | :enabled | true | false | nil | 200
+ :public | :enabled | true | false | :non_member | 200
+ :public | :enabled | true | false | :guest | 200
+ :public | :enabled | true | false | :reporter | 200
+ :public | :enabled | true | false | :developer | 200
+ :public | :enabled | true | false | :maintainer | 200
+
+ :public | :enabled | false | true | :non_member | 200
+ :public | :enabled | false | true | :guest | 200
+ :public | :enabled | false | true | :reporter | 200
+ :public | :enabled | false | true | :developer | 200
+ :public | :enabled | false | true | :maintainer | 200
+
+ :public | :enabled | false | false | nil | 403
+ :public | :enabled | false | false | :non_member | 403
+ :public | :enabled | false | false | :guest | 403
+ :public | :enabled | false | false | :reporter | 200
+ :public | :enabled | false | false | :developer | 200
+ :public | :enabled | false | false | :maintainer | 200
+
+ :public | :private | true | true | :non_member | 200
+ :public | :private | true | true | :guest | 200
+ :public | :private | true | true | :reporter | 200
+ :public | :private | true | true | :developer | 200
+ :public | :private | true | true | :maintainer | 200
+
+ :public | :private | true | false | nil | 403
+ :public | :private | true | false | :non_member | 403
+ :public | :private | true | false | :guest | 200
+ :public | :private | true | false | :reporter | 200
+ :public | :private | true | false | :developer | 200
+ :public | :private | true | false | :maintainer | 200
+
+ :public | :private | false | true | :non_member | 200
+ :public | :private | false | true | :guest | 200
+ :public | :private | false | true | :reporter | 200
+ :public | :private | false | true | :developer | 200
+ :public | :private | false | true | :maintainer | 200
+
+ :public | :private | false | false | nil | 403
+ :public | :private | false | false | :non_member | 403
+ :public | :private | false | false | :guest | 403
+ :public | :private | false | false | :reporter | 200
+ :public | :private | false | false | :developer | 200
+ :public | :private | false | false | :maintainer | 200
+ end
+
+ with_them do
+ before do
+ ci_user.update!(admin: is_admin) if user_role
+
+ project.update!(project_attributes)
+ project.project_feature.update!(project_feature_attributes)
+ project.add_role(ci_user, user_role) if user_role && user_role != :non_member
+
+ get api(pipelines_api_path, api_user)
+ end
+
+ it do
+ expect(response).to have_gitlab_http_status(response_status)
+ expect(api_response).to match(expected_response)
+ end
+ end
+end
diff --git a/spec/support/shared_examples/services/count_service_shared_examples.rb b/spec/support/shared_examples/services/count_service_shared_examples.rb
new file mode 100644
index 00000000000..9bea180a778
--- /dev/null
+++ b/spec/support/shared_examples/services/count_service_shared_examples.rb
@@ -0,0 +1,54 @@
+# frozen_string_literal: true
+
+# The calling spec should use `:use_clean_rails_memory_store_caching`
+# when including this shared example. E.g.:
+#
+# describe MyCountService, :use_clean_rails_memory_store_caching do
+# it_behaves_like 'a counter caching service'
+# end
+shared_examples 'a counter caching service' do
+ describe '#count' do
+ it 'caches the count', :request_store do
+ subject.delete_cache
+ control_count = ActiveRecord::QueryRecorder.new { subject.count }.count
+ subject.delete_cache
+
+ expect { 2.times { subject.count } }.not_to exceed_query_limit(control_count)
+ end
+ end
+
+ describe '#refresh_cache' do
+ it 'refreshes the cache' do
+ original_count = subject.count
+ Rails.cache.write(subject.cache_key, original_count + 1, raw: subject.raw?)
+
+ subject.refresh_cache
+
+ expect(fetch_cache || 0).to eq(original_count)
+ end
+ end
+
+ describe '#delete_cache' do
+ it 'removes the cache' do
+ subject.count
+ subject.delete_cache
+
+ expect(fetch_cache).to be_nil
+ end
+ end
+
+ describe '#uncached_count' do
+ it 'does not cache the count' do
+ subject.delete_cache
+ subject.uncached_count
+
+ expect(fetch_cache).to be_nil
+ end
+ end
+
+ private
+
+ def fetch_cache
+ Rails.cache.read(subject.cache_key, raw: subject.raw?)
+ end
+end
diff --git a/spec/views/layouts/_head.html.haml_spec.rb b/spec/views/layouts/_head.html.haml_spec.rb
index 70cdc08b4b6..d7f24950e6f 100644
--- a/spec/views/layouts/_head.html.haml_spec.rb
+++ b/spec/views/layouts/_head.html.haml_spec.rb
@@ -1,6 +1,8 @@
require 'spec_helper'
describe 'layouts/_head' do
+ include StubConfiguration
+
before do
allow(view).to receive(:current_application_settings).and_return(Gitlab::CurrentSettings.current_application_settings)
end
@@ -87,6 +89,24 @@ describe 'layouts/_head' do
end
end
+ context 'when a Piwik config is set' do
+ let(:piwik_host) { 'piwik.example.com' }
+
+ before do
+ stub_config(extra: {
+ piwik_url: piwik_host,
+ piwik_site_id: 12345
+ })
+ end
+
+ it 'add a Piwik Javascript' do
+ render
+
+ expect(rendered).to match(/<script.*>.*var u="\/\/#{piwik_host}\/".*<\/script>/m)
+ expect(rendered).to match(%r(<noscript>.*<img src="//#{piwik_host}/piwik.php.*</noscript>))
+ end
+ end
+
def stub_helper_with_safe_string(method)
allow_any_instance_of(PageLayoutHelper).to receive(method)
.and_return(%q{foo" http-equiv="refresh}.html_safe)