Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-08-31 18:10:41 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2020-08-31 18:10:41 +0300
commit2368893df711f330cd210005e616fc3b6003ff31 (patch)
treed48874fb1279741f8e97a7f397e46d14ac2df05f
parent729eabcb410add9dbcfa46677308003dc95a64d0 (diff)
Add latest changes from gitlab-org/gitlab@master
-rw-r--r--.gitlab/ci/review.gitlab-ci.yml2
-rw-r--r--app/controllers/projects/metrics_dashboard_controller.rb15
-rw-r--r--app/finders/users_finder.rb8
-rw-r--r--app/graphql/mutations/snippets/create.rb5
-rw-r--r--app/graphql/mutations/snippets/update.rb5
-rw-r--r--app/models/concerns/relative_positioning.rb4
-rw-r--r--app/models/namespace/root_storage_statistics.rb14
-rw-r--r--app/models/user.rb2
-rw-r--r--app/services/git/process_ref_changes_service.rb8
-rw-r--r--app/views/admin/dev_ops_score/_callout.html.haml6
-rw-r--r--app/views/admin/dev_ops_score/_no_data.html.haml2
-rw-r--r--app/views/admin/dev_ops_score/show.html.haml8
-rw-r--r--app/views/layouts/nav/sidebar/_admin.html.haml4
-rw-r--r--changelogs/unreleased/227929-metrics-dashboard-embeds-with-new-urls.yml5
-rw-r--r--changelogs/unreleased/232841-fj-track-snippet-edit-events.yml5
-rw-r--r--changelogs/unreleased/241144-fj-add-non-internal-filter-to-users-rest-endpoint.yml5
-rw-r--r--changelogs/unreleased/dblessing-emails-cascade-delete.yml5
-rw-r--r--changelogs/unreleased/id-remove-memoize-on-processing-ref-changes.yml5
-rw-r--r--changelogs/unreleased/mw-rename-devops-score-to-devops-report.yml5
-rw-r--r--db/migrate/20200819192143_add_emails_user_id_foreign_key.rb20
-rw-r--r--db/post_migrate/20200819202048_remove_orphaned_emails.rb20
-rw-r--r--db/post_migrate/20200819202222_validate_emails_user_id_foreign_key.rb16
-rw-r--r--db/schema_migrations/202008191921431
-rw-r--r--db/schema_migrations/202008192020481
-rw-r--r--db/schema_migrations/202008192022221
-rw-r--r--db/structure.sql3
-rw-r--r--doc/api/graphql/reference/gitlab_schema.graphql68
-rw-r--r--doc/api/graphql/reference/gitlab_schema.json230
-rw-r--r--doc/api/graphql/reference/index.md20
-rw-r--r--doc/api/users.md9
-rw-r--r--doc/development/contributing/issue_workflow.md8
-rw-r--r--doc/development/documentation/index.md61
-rw-r--r--doc/development/telemetry/usage_ping.md4
-rw-r--r--doc/operations/metrics/embed.md19
-rw-r--r--doc/operations/metrics/img/embedded_metrics_markdown_v12_8.pngbin13818 -> 0 bytes
-rw-r--r--doc/operations/metrics/img/embedded_metrics_rendered_v12_8.pngbin66002 -> 0 bytes
-rw-r--r--doc/operations/metrics/img/embedded_metrics_rendered_v13_4.pngbin0 -> 24072 bytes
-rw-r--r--doc/user/admin_area/analytics/convdev.md4
-rw-r--r--doc/user/admin_area/analytics/dev_ops_report.md (renamed from doc/user/admin_area/analytics/dev_ops_score.md)8
-rw-r--r--doc/user/admin_area/analytics/img/dev_ops_report_v13_4.pngbin0 -> 167541 bytes
-rw-r--r--doc/user/admin_area/analytics/img/dev_ops_score_v12_6.pngbin156530 -> 0 bytes
-rw-r--r--doc/user/admin_area/analytics/index.md2
-rw-r--r--doc/user/admin_area/monitoring/convdev.md4
-rw-r--r--doc/user/admin_area/monitoring/dev_ops_report.md (renamed from doc/user/admin_area/monitoring/dev_ops_score.md)4
-rw-r--r--doc/user/admin_area/settings/img/domain_denylist.png (renamed from doc/user/admin_area/settings/img/domain_blacklist.png)bin13601 -> 13601 bytes
-rw-r--r--doc/user/admin_area/settings/sign_up_restrictions.md16
-rw-r--r--lib/api/users.rb1
-rw-r--r--lib/banzai/filter/inline_metrics_filter.rb3
-rw-r--r--lib/gitlab/metrics/dashboard/url.rb58
-rw-r--r--lib/tasks/pngquant.rake50
-rw-r--r--locale/gitlab.pot23
-rw-r--r--rubocop/cop/rspec/top_level_describe_path.rb2
-rwxr-xr-xscripts/docs_screenshots.rb60
-rw-r--r--spec/controllers/projects/graphs_controller_spec.rb2
-rw-r--r--spec/controllers/projects/issues_controller_spec.rb60
-rw-r--r--spec/controllers/projects/notes_controller_spec.rb2
-rw-r--r--spec/db/schema_spec.rb1
-rw-r--r--spec/docs_screenshots/container_registry_docs.rb87
-rw-r--r--spec/features/admin/admin_dev_ops_score_spec.rb8
-rw-r--r--spec/features/boards/sidebar_spec.rb2
-rw-r--r--spec/features/groups/milestone_spec.rb2
-rw-r--r--spec/features/projects/members/invite_group_spec.rb2
-rw-r--r--spec/features/users/login_spec.rb2
-rw-r--r--spec/finders/users_finder_spec.rb17
-rw-r--r--spec/graphql/types/merge_request_type_spec.rb5
-rw-r--r--spec/lib/banzai/filter/inline_metrics_filter_spec.rb71
-rw-r--r--spec/lib/banzai/filter/inline_metrics_redactor_filter_spec.rb9
-rw-r--r--spec/lib/gitlab/alert_management/payload/prometheus_spec.rb2
-rw-r--r--spec/lib/gitlab/app_text_logger_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/jwt_spec.rb2
-rw-r--r--spec/lib/gitlab/conan_token_spec.rb2
-rw-r--r--spec/lib/gitlab/cycle_analytics/code_stage_spec.rb4
-rw-r--r--spec/lib/gitlab/cycle_analytics/issue_stage_spec.rb6
-rw-r--r--spec/lib/gitlab/cycle_analytics/plan_stage_spec.rb4
-rw-r--r--spec/lib/gitlab/cycle_analytics/review_stage_spec.rb4
-rw-r--r--spec/lib/gitlab/cycle_analytics/stage_summary_spec.rb2
-rw-r--r--spec/lib/gitlab/cycle_analytics/staging_stage_spec.rb4
-rw-r--r--spec/lib/gitlab/cycle_analytics/test_stage_spec.rb2
-rw-r--r--spec/lib/gitlab/database/migrations/background_migration_helpers_spec.rb2
-rw-r--r--spec/lib/gitlab/external_authorization/access_spec.rb10
-rw-r--r--spec/lib/gitlab/external_authorization/cache_spec.rb4
-rw-r--r--spec/lib/gitlab/github_import/importer/label_links_importer_spec.rb2
-rw-r--r--spec/lib/gitlab/github_import/importer/labels_importer_spec.rb4
-rw-r--r--spec/lib/gitlab/github_import/importer/pull_requests_importer_spec.rb2
-rw-r--r--spec/lib/gitlab/github_import/importer/repository_importer_spec.rb2
-rw-r--r--spec/lib/gitlab/incident_management/pager_duty/incident_issue_description_spec.rb3
-rw-r--r--spec/lib/gitlab/log_timestamp_formatter_spec.rb2
-rw-r--r--spec/lib/gitlab/metrics/dashboard/url_spec.rb103
-rw-r--r--spec/lib/gitlab/metrics/method_call_spec.rb2
-rw-r--r--spec/lib/gitlab/metrics/samplers/ruby_sampler_spec.rb2
-rw-r--r--spec/lib/gitlab/phabricator_import/cache/map_spec.rb2
-rw-r--r--spec/lib/gitlab/prometheus/queries/additional_metrics_environment_query_spec.rb2
-rw-r--r--spec/lib/gitlab/prometheus/queries/validate_query_spec.rb4
-rw-r--r--spec/lib/gitlab/prometheus_client_spec.rb10
-rw-r--r--spec/lib/gitlab/sidekiq_middleware/duplicate_jobs/strategies/until_executing_spec.rb3
-rw-r--r--spec/lib/gitlab/updated_notes_paginator_spec.rb2
-rw-r--r--spec/migrations/20190924152703_migrate_issue_trackers_data_spec.rb2
-rw-r--r--spec/migrations/20200122123016_backfill_project_settings_spec.rb2
-rw-r--r--spec/migrations/20200130145430_reschedule_migrate_issue_trackers_data_spec.rb2
-rw-r--r--spec/migrations/20200406102120_backfill_deployment_clusters_from_deployments_spec.rb2
-rw-r--r--spec/migrations/20200703125016_backfill_namespace_settings_spec.rb2
-rw-r--r--spec/migrations/backfill_imported_snippet_repositories_spec.rb2
-rw-r--r--spec/migrations/backfill_snippet_repositories_spec.rb2
-rw-r--r--spec/migrations/enqueue_reset_merge_status_second_run_spec.rb2
-rw-r--r--spec/migrations/enqueue_reset_merge_status_spec.rb2
-rw-r--r--spec/migrations/fix_projects_without_project_feature_spec.rb2
-rw-r--r--spec/migrations/fix_projects_without_prometheus_services_spec.rb2
-rw-r--r--spec/migrations/fix_wrong_pages_access_level_spec.rb2
-rw-r--r--spec/migrations/migrate_discussion_id_on_promoted_epics_spec.rb4
-rw-r--r--spec/migrations/schedule_calculate_wiki_sizes_spec.rb4
-rw-r--r--spec/migrations/schedule_fill_valid_time_for_pages_domain_certificates_spec.rb2
-rw-r--r--spec/migrations/schedule_migrate_security_scans_spec.rb4
-rw-r--r--spec/migrations/schedule_pages_metadata_migration_spec.rb2
-rw-r--r--spec/migrations/schedule_populate_merge_request_assignees_table_spec.rb2
-rw-r--r--spec/migrations/schedule_populate_personal_snippet_statistics_spec.rb2
-rw-r--r--spec/migrations/schedule_populate_project_snippet_statistics_spec.rb2
-rw-r--r--spec/migrations/schedule_populate_user_highest_roles_table_spec.rb2
-rw-r--r--spec/migrations/schedule_recalculate_project_authorizations_second_run_spec.rb2
-rw-r--r--spec/migrations/schedule_recalculate_project_authorizations_spec.rb4
-rw-r--r--spec/migrations/schedule_recalculate_project_authorizations_third_run_spec.rb2
-rw-r--r--spec/migrations/schedule_sync_issuables_state_id_spec.rb2
-rw-r--r--spec/migrations/schedule_sync_issuables_state_id_where_nil_spec.rb2
-rw-r--r--spec/migrations/schedule_update_existing_subgroup_to_match_visibility_level_of_parent_spec.rb8
-rw-r--r--spec/models/board_group_recent_visit_spec.rb2
-rw-r--r--spec/models/board_project_recent_visit_spec.rb2
-rw-r--r--spec/models/ci/build_spec.rb8
-rw-r--r--spec/models/clusters/applications/prometheus_spec.rb4
-rw-r--r--spec/models/concerns/prometheus_adapter_spec.rb10
-rw-r--r--spec/models/deployment_spec.rb10
-rw-r--r--spec/models/environment_spec.rb4
-rw-r--r--spec/models/metrics/dashboard/annotation_spec.rb2
-rw-r--r--spec/models/namespace/root_storage_statistics_spec.rb3
-rw-r--r--spec/models/remote_mirror_spec.rb4
-rw-r--r--spec/presenters/ci/build_presenter_spec.rb6
-rw-r--r--spec/requests/api/conan_packages_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/snippets/create_spec.rb4
-rw-r--r--spec/requests/api/graphql/mutations/snippets/update_spec.rb3
-rw-r--r--spec/requests/api/internal/base_spec.rb2
-rw-r--r--spec/requests/api/users_spec.rb20
-rw-r--r--spec/requests/projects/metrics_dashboard_spec.rb14
-rw-r--r--spec/serializers/analytics_build_entity_spec.rb2
-rw-r--r--spec/services/clusters/applications/schedule_update_service_spec.rb2
-rw-r--r--spec/services/deployments/after_create_service_spec.rb2
-rw-r--r--spec/services/git/process_ref_changes_service_spec.rb22
-rw-r--r--spec/services/merge_requests/delete_non_latest_diffs_service_spec.rb2
-rw-r--r--spec/services/note_summary_spec.rb2
-rw-r--r--spec/services/projects/hashed_storage/base_attachment_service_spec.rb2
-rw-r--r--spec/services/releases/create_service_spec.rb2
-rw-r--r--spec/services/submit_usage_ping_service_spec.rb8
-rw-r--r--spec/spec_helper.rb4
-rw-r--r--spec/support/helpers/docs_screenshot_helpers.rb39
-rw-r--r--spec/support/shared_contexts/finders/users_finder_shared_contexts.rb1
-rw-r--r--spec/support/shared_examples/lib/gitlab/background_migration/mentions_migration_shared_examples.rb2
-rw-r--r--spec/support/shared_examples/models/relative_positioning_shared_examples.rb12
-rw-r--r--spec/support/shared_examples/models/throttled_touch_shared_examples.rb2
-rw-r--r--spec/support/shared_examples/requests/api/graphql/mutations/snippets_shared_examples.rb39
-rw-r--r--spec/workers/cluster_update_app_worker_spec.rb2
-rw-r--r--spec/workers/repository_update_remote_mirror_worker_spec.rb2
-rw-r--r--tooling/lib/tooling/images.rb56
159 files changed, 1335 insertions, 330 deletions
diff --git a/.gitlab/ci/review.gitlab-ci.yml b/.gitlab/ci/review.gitlab-ci.yml
index 33c9a8ba987..e2fe5f467f8 100644
--- a/.gitlab/ci/review.gitlab-ci.yml
+++ b/.gitlab/ci/review.gitlab-ci.yml
@@ -43,7 +43,7 @@ review-build-cng:
HOST_SUFFIX: "${CI_ENVIRONMENT_SLUG}"
REVIEW_APPS_DOMAIN: "temp.gitlab-review.app" # FIXME: using temporary domain
DOMAIN: "-${CI_ENVIRONMENT_SLUG}.${REVIEW_APPS_DOMAIN}"
- GITLAB_HELM_CHART_REF: "v4.1.3"
+ GITLAB_HELM_CHART_REF: "v4.3.0"
environment:
name: review/${CI_COMMIT_REF_NAME}
url: https://gitlab-${CI_ENVIRONMENT_SLUG}.${REVIEW_APPS_DOMAIN}
diff --git a/app/controllers/projects/metrics_dashboard_controller.rb b/app/controllers/projects/metrics_dashboard_controller.rb
index ae3f0a7a0c2..9d0cbfd2a20 100644
--- a/app/controllers/projects/metrics_dashboard_controller.rb
+++ b/app/controllers/projects/metrics_dashboard_controller.rb
@@ -18,7 +18,13 @@ module Projects
if environment
render 'projects/environments/metrics'
elsif default_environment
- redirect_to project_metrics_dashboard_path(project, environment: default_environment)
+ redirect_to project_metrics_dashboard_path(
+ project,
+ **permitted_params
+ .to_h
+ .symbolize_keys
+ .merge(environment: default_environment)
+ )
else
render 'projects/environments/empty_metrics'
end
@@ -26,9 +32,14 @@ module Projects
private
+ def permitted_params
+ @permitted_params ||= params.permit(:dashboard_path, :environment, :page)
+ end
+
def environment
strong_memoize(:environment) do
- project.environments.find(params[:environment]) if params[:environment]
+ env = permitted_params[:environment]
+ project.environments.find(env) if env
end
end
diff --git a/app/finders/users_finder.rb b/app/finders/users_finder.rb
index f87e0c67604..cc94536bf79 100644
--- a/app/finders/users_finder.rb
+++ b/app/finders/users_finder.rb
@@ -17,6 +17,7 @@
# without_projects: boolean
# sort: string
# id: integer
+# non_internal: boolean
#
class UsersFinder
include CreatedAtFilter
@@ -42,6 +43,7 @@ class UsersFinder
users = by_created_at(users)
users = by_without_projects(users)
users = by_custom_attributes(users)
+ users = by_non_internal(users)
order(users)
end
@@ -112,6 +114,12 @@ class UsersFinder
users.without_projects
end
+ def by_non_internal(users)
+ return users unless params[:non_internal]
+
+ users.non_internal
+ end
+
# rubocop: disable CodeReuse/ActiveRecord
def order(users)
return users unless params[:sort]
diff --git a/app/graphql/mutations/snippets/create.rb b/app/graphql/mutations/snippets/create.rb
index 37a281871c2..a8aeb15afcd 100644
--- a/app/graphql/mutations/snippets/create.rb
+++ b/app/graphql/mutations/snippets/create.rb
@@ -51,6 +51,11 @@ module Mutations
snippet = service_response.payload[:snippet]
+ # Only when the user is not an api user and the operation was successful
+ if !api_user? && service_response.success?
+ ::Gitlab::UsageDataCounters::EditorUniqueCounter.track_snippet_editor_edit_action(author: current_user)
+ end
+
{
snippet: service_response.success? ? snippet : nil,
errors: errors_on_object(snippet)
diff --git a/app/graphql/mutations/snippets/update.rb b/app/graphql/mutations/snippets/update.rb
index fee2f61e927..d0db5fa2eb9 100644
--- a/app/graphql/mutations/snippets/update.rb
+++ b/app/graphql/mutations/snippets/update.rb
@@ -34,6 +34,11 @@ module Mutations
update_params(args)).execute(snippet)
snippet = result.payload[:snippet]
+ # Only when the user is not an api user and the operation was successful
+ if !api_user? && result.success?
+ ::Gitlab::UsageDataCounters::EditorUniqueCounter.track_snippet_editor_edit_action(author: current_user)
+ end
+
{
snippet: result.success? ? snippet : snippet.reset,
errors: errors_on_object(snippet)
diff --git a/app/models/concerns/relative_positioning.rb b/app/models/concerns/relative_positioning.rb
index a6fd912e135..3f65ebe3db7 100644
--- a/app/models/concerns/relative_positioning.rb
+++ b/app/models/concerns/relative_positioning.rb
@@ -83,9 +83,9 @@ module RelativePositioning
if gap_width < MIN_GAP
raise NoSpaceLeft
elsif gap_width > MAX_GAP
- if pos_before == MIN_POSITION
+ if pos_before <= MIN_POSITION
pos_after - IDEAL_DISTANCE
- elsif pos_after == MAX_POSITION
+ elsif pos_after >= MAX_POSITION
pos_before + IDEAL_DISTANCE
else
midpoint
diff --git a/app/models/namespace/root_storage_statistics.rb b/app/models/namespace/root_storage_statistics.rb
index 2ad6ea59588..5723a823e98 100644
--- a/app/models/namespace/root_storage_statistics.rb
+++ b/app/models/namespace/root_storage_statistics.rb
@@ -2,7 +2,16 @@
class Namespace::RootStorageStatistics < ApplicationRecord
SNIPPETS_SIZE_STAT_NAME = 'snippets_size'.freeze
- STATISTICS_ATTRIBUTES = %W(storage_size repository_size wiki_size lfs_objects_size build_artifacts_size packages_size #{SNIPPETS_SIZE_STAT_NAME}).freeze
+ STATISTICS_ATTRIBUTES = %W(
+ storage_size
+ repository_size
+ wiki_size
+ lfs_objects_size
+ build_artifacts_size
+ packages_size
+ #{SNIPPETS_SIZE_STAT_NAME}
+ pipeline_artifacts_size
+ ).freeze
self.primary_key = :namespace_id
@@ -40,7 +49,8 @@ class Namespace::RootStorageStatistics < ApplicationRecord
'COALESCE(SUM(ps.lfs_objects_size), 0) AS lfs_objects_size',
'COALESCE(SUM(ps.build_artifacts_size), 0) AS build_artifacts_size',
'COALESCE(SUM(ps.packages_size), 0) AS packages_size',
- "COALESCE(SUM(ps.snippets_size), 0) AS #{SNIPPETS_SIZE_STAT_NAME}"
+ "COALESCE(SUM(ps.snippets_size), 0) AS #{SNIPPETS_SIZE_STAT_NAME}",
+ 'COALESCE(SUM(ps.pipeline_artifacts_size), 0) AS pipeline_artifacts_size'
)
end
diff --git a/app/models/user.rb b/app/models/user.rb
index 1a67116c1f2..300e918513a 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -107,7 +107,7 @@ class User < ApplicationRecord
has_many :group_deploy_keys
has_many :gpg_keys
- has_many :emails, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent
+ has_many :emails
has_many :personal_access_tokens, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent
has_many :identities, dependent: :destroy, autosave: true # rubocop:disable Cop/ActiveRecordDependent
has_many :u2f_registrations, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent
diff --git a/app/services/git/process_ref_changes_service.rb b/app/services/git/process_ref_changes_service.rb
index c012c61a337..d039ed00efc 100644
--- a/app/services/git/process_ref_changes_service.rb
+++ b/app/services/git/process_ref_changes_service.rb
@@ -42,7 +42,7 @@ module Git
push_service_class = push_service_class_for(ref_type)
create_bulk_push_event = changes.size > Gitlab::CurrentSettings.push_event_activities_limit
- merge_request_branches = merge_request_branches_for(changes)
+ merge_request_branches = merge_request_branches_for(ref_type, changes)
changes.each do |change|
push_service_class.new(
@@ -74,8 +74,10 @@ module Git
Git::BranchPushService
end
- def merge_request_branches_for(changes)
- @merge_requests_branches ||= MergeRequests::PushedBranchesService.new(project, current_user, changes: changes).execute
+ def merge_request_branches_for(ref_type, changes)
+ return [] if ref_type == :tag
+
+ MergeRequests::PushedBranchesService.new(project, current_user, changes: changes).execute
end
end
end
diff --git a/app/views/admin/dev_ops_score/_callout.html.haml b/app/views/admin/dev_ops_score/_callout.html.haml
index 31ae7721f5f..1b50c27834d 100644
--- a/app/views/admin/dev_ops_score/_callout.html.haml
+++ b/app/views/admin/dev_ops_score/_callout.html.haml
@@ -2,12 +2,12 @@
.user-callout{ data: { uid: 'dev_ops_score_intro_callout_dismissed' } }
.bordered-box.landing.content-block
%button.btn.btn-default.close.js-close-callout{ type: 'button',
- 'aria-label' => _('Dismiss DevOps Score introduction') }
+ 'aria-label' => _('Dismiss DevOps Report introduction') }
= icon('times', class: 'dismiss-icon', 'aria-hidden' => 'true')
.user-callout-copy
%h4
- = _('Introducing Your DevOps Score')
+ = _('Introducing Your DevOps Report')
%p
- = _('Your DevOps Score gives an overview of how you are using GitLab from a feature perspective. View how you compare with other organizations, discover features you are not using, and learn best practices through blog posts and white papers.')
+ = _('Your DevOps Report gives an overview of how you are using GitLab from a feature perspective. View how you compare with other organizations, discover features you are not using, and learn best practices through blog posts and white papers.')
.svg-container.devops
= custom_icon('dev_ops_score_overview')
diff --git a/app/views/admin/dev_ops_score/_no_data.html.haml b/app/views/admin/dev_ops_score/_no_data.html.haml
index 36368ceca2b..8ea3797b1cc 100644
--- a/app/views/admin/dev_ops_score/_no_data.html.haml
+++ b/app/views/admin/dev_ops_score/_no_data.html.haml
@@ -4,4 +4,4 @@
%h4= _('Data is still calculating...')
%p
= _('In order to gather accurate feature usage data, it can take 1 to 2 weeks to see your index.')
- = link_to _('Learn more'), help_page_path('user/admin_area/analytics/dev_ops_score'), target: '_blank'
+ = link_to _('Learn more'), help_page_path('user/admin_area/analytics/dev_ops_report'), target: '_blank'
diff --git a/app/views/admin/dev_ops_score/show.html.haml b/app/views/admin/dev_ops_score/show.html.haml
index 9c056384164..520194acc88 100644
--- a/app/views/admin/dev_ops_score/show.html.haml
+++ b/app/views/admin/dev_ops_score/show.html.haml
@@ -1,4 +1,4 @@
-- page_title _('DevOps Score')
+- page_title _('DevOps Report')
- usage_ping_enabled = Gitlab::CurrentSettings.usage_ping_enabled
.container
@@ -16,10 +16,10 @@
%h2.devops-header-title{ class: "devops-#{score_level(@metric.average_percentage_score)}-score" }
= number_to_percentage(@metric.average_percentage_score, precision: 1)
.devops-header-subtitle
- = _('index')
+ = _('DevOps')
%br
- = _('score')
- = link_to icon('question-circle', 'aria-hidden' => 'true'), help_page_path('user/admin_area/analytics/dev_ops_score')
+ = _('Score')
+ = link_to icon('question-circle', 'aria-hidden' => 'true'), help_page_path('user/admin_area/analytics/dev_ops_report')
.devops-cards.board-card-container
- @metric.cards.each do |card|
diff --git a/app/views/layouts/nav/sidebar/_admin.html.haml b/app/views/layouts/nav/sidebar/_admin.html.haml
index 2e915a38c46..960a4a93019 100644
--- a/app/views/layouts/nav/sidebar/_admin.html.haml
+++ b/app/views/layouts/nav/sidebar/_admin.html.haml
@@ -62,9 +62,9 @@
= _('Analytics')
%li.divider.fly-out-top-item
= nav_link(controller: :dev_ops_score) do
- = link_to admin_dev_ops_score_path, title: _('DevOps Score') do
+ = link_to admin_dev_ops_score_path, title: _('DevOps Report') do
%span
- = _('DevOps Score')
+ = _('DevOps Report')
= nav_link(controller: :cohorts) do
= link_to admin_cohorts_path, title: _('Cohorts') do
%span
diff --git a/changelogs/unreleased/227929-metrics-dashboard-embeds-with-new-urls.yml b/changelogs/unreleased/227929-metrics-dashboard-embeds-with-new-urls.yml
new file mode 100644
index 00000000000..46f36353614
--- /dev/null
+++ b/changelogs/unreleased/227929-metrics-dashboard-embeds-with-new-urls.yml
@@ -0,0 +1,5 @@
+---
+title: Fix Metrics dashboard embeds when using new URLs
+merge_request: 39876
+author:
+type: fixed
diff --git a/changelogs/unreleased/232841-fj-track-snippet-edit-events.yml b/changelogs/unreleased/232841-fj-track-snippet-edit-events.yml
new file mode 100644
index 00000000000..9ee49bef669
--- /dev/null
+++ b/changelogs/unreleased/232841-fj-track-snippet-edit-events.yml
@@ -0,0 +1,5 @@
+---
+title: Track snippet editor actions
+merge_request: 40277
+author:
+type: changed
diff --git a/changelogs/unreleased/241144-fj-add-non-internal-filter-to-users-rest-endpoint.yml b/changelogs/unreleased/241144-fj-add-non-internal-filter-to-users-rest-endpoint.yml
new file mode 100644
index 00000000000..1b0cd053975
--- /dev/null
+++ b/changelogs/unreleased/241144-fj-add-non-internal-filter-to-users-rest-endpoint.yml
@@ -0,0 +1,5 @@
+---
+title: Add filter to exclude non internal users in REST API
+merge_request: 40372
+author:
+type: changed
diff --git a/changelogs/unreleased/dblessing-emails-cascade-delete.yml b/changelogs/unreleased/dblessing-emails-cascade-delete.yml
new file mode 100644
index 00000000000..cdba61207ab
--- /dev/null
+++ b/changelogs/unreleased/dblessing-emails-cascade-delete.yml
@@ -0,0 +1,5 @@
+---
+title: Add emails user_id foreign key with cascade delete
+merge_request: 39899
+author:
+type: other
diff --git a/changelogs/unreleased/id-remove-memoize-on-processing-ref-changes.yml b/changelogs/unreleased/id-remove-memoize-on-processing-ref-changes.yml
new file mode 100644
index 00000000000..2c52d5f3f61
--- /dev/null
+++ b/changelogs/unreleased/id-remove-memoize-on-processing-ref-changes.yml
@@ -0,0 +1,5 @@
+---
+title: Fix wrong caching logic in ProcessRefChangesService
+merge_request: 40821
+author:
+type: fixed
diff --git a/changelogs/unreleased/mw-rename-devops-score-to-devops-report.yml b/changelogs/unreleased/mw-rename-devops-score-to-devops-report.yml
new file mode 100644
index 00000000000..b470ced0329
--- /dev/null
+++ b/changelogs/unreleased/mw-rename-devops-score-to-devops-report.yml
@@ -0,0 +1,5 @@
+---
+title: Rename DevOps Score to DevOps Report
+merge_request: 39953
+author:
+type: changed
diff --git a/db/migrate/20200819192143_add_emails_user_id_foreign_key.rb b/db/migrate/20200819192143_add_emails_user_id_foreign_key.rb
new file mode 100644
index 00000000000..7f00aa6341b
--- /dev/null
+++ b/db/migrate/20200819192143_add_emails_user_id_foreign_key.rb
@@ -0,0 +1,20 @@
+# frozen_string_literal: true
+
+class AddEmailsUserIdForeignKey < ActiveRecord::Migration[6.0]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+ CONSTRAINT_NAME = 'fk_emails_user_id'
+
+ def up
+ with_lock_retries do
+ add_foreign_key :emails, :users, on_delete: :cascade, validate: false, name: CONSTRAINT_NAME
+ end
+ end
+
+ def down
+ with_lock_retries do
+ remove_foreign_key_if_exists :emails, column: :user_id, name: CONSTRAINT_NAME
+ end
+ end
+end
diff --git a/db/post_migrate/20200819202048_remove_orphaned_emails.rb b/db/post_migrate/20200819202048_remove_orphaned_emails.rb
new file mode 100644
index 00000000000..82cba244ad6
--- /dev/null
+++ b/db/post_migrate/20200819202048_remove_orphaned_emails.rb
@@ -0,0 +1,20 @@
+# frozen_string_literal: true
+
+class RemoveOrphanedEmails < ActiveRecord::Migration[6.0]
+ DOWNTIME = false
+
+ def up
+ execute <<~SQL
+ DELETE FROM emails
+ WHERE not exists (
+ SELECT 1 FROM users WHERE users.id = emails.user_id
+ );
+ SQL
+
+ execute 'DELETE FROM emails WHERE user_id IS NULL;'
+ end
+
+ def down
+ # no-op
+ end
+end
diff --git a/db/post_migrate/20200819202222_validate_emails_user_id_foreign_key.rb b/db/post_migrate/20200819202222_validate_emails_user_id_foreign_key.rb
new file mode 100644
index 00000000000..4f7f9deb540
--- /dev/null
+++ b/db/post_migrate/20200819202222_validate_emails_user_id_foreign_key.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+class ValidateEmailsUserIdForeignKey < ActiveRecord::Migration[6.0]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+ CONSTRAINT_NAME = 'fk_emails_user_id'
+
+ def up
+ validate_foreign_key :emails, :user_id, name: CONSTRAINT_NAME
+ end
+
+ def down
+ # no op
+ end
+end
diff --git a/db/schema_migrations/20200819192143 b/db/schema_migrations/20200819192143
new file mode 100644
index 00000000000..e0934e15f1f
--- /dev/null
+++ b/db/schema_migrations/20200819192143
@@ -0,0 +1 @@
+5a5278fdd9539d33a6de226a84ed39b7c5a26929cec68ec5e8d193afb3cfafa2 \ No newline at end of file
diff --git a/db/schema_migrations/20200819202048 b/db/schema_migrations/20200819202048
new file mode 100644
index 00000000000..a5428c7b40a
--- /dev/null
+++ b/db/schema_migrations/20200819202048
@@ -0,0 +1 @@
+476bce9b18177f37b31e15d42f5a1391c0bfbbd312a513c1d5b43085b90afb3e \ No newline at end of file
diff --git a/db/schema_migrations/20200819202222 b/db/schema_migrations/20200819202222
new file mode 100644
index 00000000000..f633502d0bb
--- /dev/null
+++ b/db/schema_migrations/20200819202222
@@ -0,0 +1 @@
+5e2dfdf725ad0a3d90b240ced74cf5a872f7126b716847f9f9e99b4ad2a22109 \ No newline at end of file
diff --git a/db/structure.sql b/db/structure.sql
index cb6c551bd43..1951b9385a7 100644
--- a/db/structure.sql
+++ b/db/structure.sql
@@ -22016,6 +22016,9 @@ ALTER TABLE ONLY public.events
ALTER TABLE ONLY public.vulnerabilities
ADD CONSTRAINT fk_efb96ab1e2 FOREIGN KEY (project_id) REFERENCES public.projects(id) ON DELETE CASCADE;
+ALTER TABLE ONLY public.emails
+ ADD CONSTRAINT fk_emails_user_id FOREIGN KEY (user_id) REFERENCES public.users(id) ON DELETE CASCADE;
+
ALTER TABLE ONLY public.clusters
ADD CONSTRAINT fk_f05c5e5a42 FOREIGN KEY (management_project_id) REFERENCES public.projects(id) ON DELETE SET NULL;
diff --git a/doc/api/graphql/reference/gitlab_schema.graphql b/doc/api/graphql/reference/gitlab_schema.graphql
index 321bb9d7f84..0523e95535d 100644
--- a/doc/api/graphql/reference/gitlab_schema.graphql
+++ b/doc/api/graphql/reference/gitlab_schema.graphql
@@ -1725,11 +1725,73 @@ type ClusterAgentDeletePayload {
errors: [String!]!
}
+type ClusterAgentToken {
+ """
+ Cluster agent this token is associated with
+ """
+ clusterAgent: ClusterAgent
+
+ """
+ Timestamp the token was created
+ """
+ createdAt: Time
+
+ """
+ Global ID of the token
+ """
+ id: ClustersAgentTokenID!
+}
+
+"""
+Autogenerated input type of ClusterAgentTokenCreate
+"""
+input ClusterAgentTokenCreateInput {
+ """
+ A unique identifier for the client performing the mutation.
+ """
+ clientMutationId: String
+
+ """
+ Global ID of the cluster agent that will be associated with the new token
+ """
+ clusterAgentId: ClustersAgentID!
+}
+
+"""
+Autogenerated return type of ClusterAgentTokenCreate
+"""
+type ClusterAgentTokenCreatePayload {
+ """
+ A unique identifier for the client performing the mutation.
+ """
+ clientMutationId: String
+
+ """
+ Errors encountered during execution of the mutation.
+ """
+ errors: [String!]!
+
+ """
+ Token secret value. Make sure you save it - you won't be able to access it again
+ """
+ secret: String
+
+ """
+ Token created after mutation
+ """
+ token: ClusterAgentToken
+}
+
"""
Identifier of Clusters::Agent
"""
scalar ClustersAgentID
+"""
+Identifier of Clusters::AgentToken
+"""
+scalar ClustersAgentTokenID
+
type Commit {
"""
Author of the commit
@@ -8548,6 +8610,11 @@ type MergeRequest implements Noteable {
allowCollaboration: Boolean
"""
+ Indicates if the merge request has all the required approvals. Returns true if no required approvals are configured.
+ """
+ approved: Boolean!
+
+ """
Users who approved the merge request
"""
approvedBy(
@@ -9792,6 +9859,7 @@ type Mutation {
boardListCreate(input: BoardListCreateInput!): BoardListCreatePayload
boardListUpdateLimitMetrics(input: BoardListUpdateLimitMetricsInput!): BoardListUpdateLimitMetricsPayload
clusterAgentDelete(input: ClusterAgentDeleteInput!): ClusterAgentDeletePayload
+ clusterAgentTokenCreate(input: ClusterAgentTokenCreateInput!): ClusterAgentTokenCreatePayload
commitCreate(input: CommitCreateInput!): CommitCreatePayload
configureSast(input: ConfigureSastInput!): ConfigureSastPayload
createAlertIssue(input: CreateAlertIssueInput!): CreateAlertIssuePayload
diff --git a/doc/api/graphql/reference/gitlab_schema.json b/doc/api/graphql/reference/gitlab_schema.json
index 1772c92c3b2..a2c9a369e29 100644
--- a/doc/api/graphql/reference/gitlab_schema.json
+++ b/doc/api/graphql/reference/gitlab_schema.json
@@ -4730,6 +4730,181 @@
"possibleTypes": null
},
{
+ "kind": "OBJECT",
+ "name": "ClusterAgentToken",
+ "description": null,
+ "fields": [
+ {
+ "name": "clusterAgent",
+ "description": "Cluster agent this token is associated with",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "OBJECT",
+ "name": "ClusterAgent",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "createdAt",
+ "description": "Timestamp the token was created",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "SCALAR",
+ "name": "Time",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "id",
+ "description": "Global ID of the token",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "ClustersAgentTokenID",
+ "ofType": null
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ }
+ ],
+ "inputFields": null,
+ "interfaces": [
+
+ ],
+ "enumValues": null,
+ "possibleTypes": null
+ },
+ {
+ "kind": "INPUT_OBJECT",
+ "name": "ClusterAgentTokenCreateInput",
+ "description": "Autogenerated input type of ClusterAgentTokenCreate",
+ "fields": null,
+ "inputFields": [
+ {
+ "name": "clusterAgentId",
+ "description": "Global ID of the cluster agent that will be associated with the new token",
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "ClustersAgentID",
+ "ofType": null
+ }
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "clientMutationId",
+ "description": "A unique identifier for the client performing the mutation.",
+ "type": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ },
+ "defaultValue": null
+ }
+ ],
+ "interfaces": null,
+ "enumValues": null,
+ "possibleTypes": null
+ },
+ {
+ "kind": "OBJECT",
+ "name": "ClusterAgentTokenCreatePayload",
+ "description": "Autogenerated return type of ClusterAgentTokenCreate",
+ "fields": [
+ {
+ "name": "clientMutationId",
+ "description": "A unique identifier for the client performing the mutation.",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "errors",
+ "description": "Errors encountered during execution of the mutation.",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ }
+ }
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "secret",
+ "description": "Token secret value. Make sure you save it - you won't be able to access it again",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "token",
+ "description": "Token created after mutation",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "OBJECT",
+ "name": "ClusterAgentToken",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ }
+ ],
+ "inputFields": null,
+ "interfaces": [
+
+ ],
+ "enumValues": null,
+ "possibleTypes": null
+ },
+ {
"kind": "SCALAR",
"name": "ClustersAgentID",
"description": "Identifier of Clusters::Agent",
@@ -4740,6 +4915,16 @@
"possibleTypes": null
},
{
+ "kind": "SCALAR",
+ "name": "ClustersAgentTokenID",
+ "description": "Identifier of Clusters::AgentToken",
+ "fields": null,
+ "inputFields": null,
+ "interfaces": null,
+ "enumValues": null,
+ "possibleTypes": null
+ },
+ {
"kind": "OBJECT",
"name": "Commit",
"description": null,
@@ -23819,6 +24004,24 @@
"deprecationReason": null
},
{
+ "name": "approved",
+ "description": "Indicates if the merge request has all the required approvals. Returns true if no required approvals are configured.",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "Boolean",
+ "ofType": null
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
"name": "approvedBy",
"description": "Users who approved the merge request",
"args": [
@@ -27730,6 +27933,33 @@
"deprecationReason": null
},
{
+ "name": "clusterAgentTokenCreate",
+ "description": null,
+ "args": [
+ {
+ "name": "input",
+ "description": null,
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "INPUT_OBJECT",
+ "name": "ClusterAgentTokenCreateInput",
+ "ofType": null
+ }
+ },
+ "defaultValue": null
+ }
+ ],
+ "type": {
+ "kind": "OBJECT",
+ "name": "ClusterAgentTokenCreatePayload",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
"name": "commitCreate",
"description": null,
"args": [
diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md
index 0ab83a1d5f7..0c75917db10 100644
--- a/doc/api/graphql/reference/index.md
+++ b/doc/api/graphql/reference/index.md
@@ -295,6 +295,25 @@ Autogenerated return type of ClusterAgentDelete
| `clientMutationId` | String | A unique identifier for the client performing the mutation. |
| `errors` | String! => Array | Errors encountered during execution of the mutation. |
+## ClusterAgentToken
+
+| Name | Type | Description |
+| --- | ---- | ---------- |
+| `clusterAgent` | ClusterAgent | Cluster agent this token is associated with |
+| `createdAt` | Time | Timestamp the token was created |
+| `id` | ClustersAgentTokenID! | Global ID of the token |
+
+## ClusterAgentTokenCreatePayload
+
+Autogenerated return type of ClusterAgentTokenCreate
+
+| Name | Type | Description |
+| --- | ---- | ---------- |
+| `clientMutationId` | String | A unique identifier for the client performing the mutation. |
+| `errors` | String! => Array | Errors encountered during execution of the mutation. |
+| `secret` | String | Token secret value. Make sure you save it - you won't be able to access it again |
+| `token` | ClusterAgentToken | Token created after mutation |
+
## Commit
| Name | Type | Description |
@@ -1319,6 +1338,7 @@ Autogenerated return type of MarkAsSpamSnippet
| Name | Type | Description |
| --- | ---- | ---------- |
| `allowCollaboration` | Boolean | Indicates if members of the target project can push to the fork |
+| `approved` | Boolean! | Indicates if the merge request has all the required approvals. Returns true if no required approvals are configured. |
| `author` | User | User who created this merge request |
| `commitCount` | Int | Number of commits in the merge request |
| `createdAt` | Time! | Timestamp of when the merge request was created |
diff --git a/doc/api/users.md b/doc/api/users.md
index 76075e8b7be..4c762958b52 100644
--- a/doc/api/users.md
+++ b/doc/api/users.md
@@ -61,6 +61,15 @@ GET /users?active=true
GET /users?blocked=true
```
+GitLab supports bot users such as the [alert bot](../operations/incident_management/generic_alerts.md)
+or the [support bot](../user/project/service_desk.md#support-bot-user).
+To exclude these users from the users' list, you can use the parameter `exclude_internal=true`
+([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/241144) in GitLab 13.4).
+
+```plaintext
+GET /users?exclude_internal=true
+```
+
NOTE: **Note:**
Username search is case insensitive.
diff --git a/doc/development/contributing/issue_workflow.md b/doc/development/contributing/issue_workflow.md
index b4bad20438f..33004037fae 100644
--- a/doc/development/contributing/issue_workflow.md
+++ b/doc/development/contributing/issue_workflow.md
@@ -43,7 +43,7 @@ Most issues will have labels for at least one of the following:
- Type: `~feature`, `~bug`, `~tooling`, `~documentation`, etc.
- Stage: `~"devops::plan"`, `~"devops::create"`, etc.
- Group: `~"group::source code"`, `~"group::knowledge"`, `~"group::editor"`, etc.
-- Category: `~"Category:Code Analytics"`, `~"Category:DevOps Score"`, `~"Category:Templates"`, etc.
+- Category: `~"Category:Code Analytics"`, `~"Category:DevOps Reports"`, `~"Category:Templates"`, etc.
- Feature: `~wiki`, `~ldap`, `~api`, `~issues`, `~"merge requests"`, etc.
- Department: `~UX`, `~Quality`
- Team: `~"Technical Writing"`, `~Delivery`
@@ -188,9 +188,9 @@ their color is `#428BCA`.
`<Category Name>` is the category name as it is in the single source of truth for categories at
<https://gitlab.com/gitlab-com/www-gitlab-com/blob/master/data/categories.yml>.
-For instance, the "DevOps Score" category is represented by the
-~"Category:DevOps Score" label in the `gitlab-org` group since its
-`devops_score.name` value is "DevOps Score".
+For instance, the "DevOps Report" category is represented by the
+~"Category:DevOps Reports" label in the `gitlab-org` group since its
+`devops_score.name` value is "DevOps Reports".
If a category's label doesn't respect this naming convention, it should be specified
with [the `label` attribute](https://about.gitlab.com/handbook/marketing/website/#category-attributes)
diff --git a/doc/development/documentation/index.md b/doc/development/documentation/index.md
index 283060ba8d4..c864e59c898 100644
--- a/doc/development/documentation/index.md
+++ b/doc/development/documentation/index.md
@@ -750,3 +750,64 @@ code review. For docs changes in merge requests, whenever a change to files unde
is made, Danger Bot leaves a comment with further instructions about the documentation
process. This is configured in the `Dangerfile` in the GitLab repository under
[/danger/documentation/](https://gitlab.com/gitlab-org/gitlab/tree/master/danger/documentation).
+
+## Automatic screenshot generator
+
+You can now set up an automatic screenshot generator to take and compress screenshots, with the
+help of a configuration file known as **screenshot generator**.
+
+### Use the tool
+
+To run the tool on an existing screenshot generator, take the following steps:
+
+1. Set up the [GitLab Development Kit (GDK)](https://gitlab.com/gitlab-org/gitlab-development-kit/blob/master/doc/howto/gitlab_docs.md).
+1. Navigate to the subdirectory with your cloned GitLab repository, typically `gdk/gitlab`.
+1. Make sure that your GDK database is fully migrated: `bin/rake db:migrate RAILS_ENV=development`.
+1. Install pngquant, see the tool website for more info: [`pngquant`](https://pngquant.org/)
+1. Run `scripts/docs_screenshots.rb spec/docs_screenshots/<name_of_screenshot_generator>.rb <milestone-version>`.
+1. Identify the location of the screenshots, based on the `gitlab/doc` location defined by the `it` parameter in your script.
+1. Commit the newly created screenshots.
+
+### Extending the tool
+
+To add an additional **screenshot generator**, take the following steps:
+
+- Locate the `spec/docs_screenshots` directory.
+- Add a new file with a `_docs.rb` extension.
+- Be sure to include the following bits in the file:
+
+```ruby
+require 'spec_helper'
+
+RSpec.describe '<What I am taking screenshots of>', :js do
+ include DocsScreenshotHelpers # Helper that enables the screenshots taking mechanism
+
+ before do
+ page.driver.browser.manage.window.resize_to(1366, 1024) # length and width of the page
+ end
+```
+
+- In addition, every `it` block must include the path where the screenshot is saved
+
+```ruby
+ it 'user/packages/container_registry/img/project_image_repositories_list'
+```
+
+#### Full page screenshots
+
+To take a full page screenshot simply `visit the page` and perform any expectation on real content (to have capybara wait till the page is ready and not take a white screenshot).
+
+#### Element screenshot
+
+To have the screenshot focuses few more steps are needed:
+
+- **find the area**: `screenshot_area = find('#js-registry-policies')`
+- **scroll the area in focus**: `scroll_to screenshot_area`
+- **wait for the content**: `expect(screenshot_area).to have_content 'Expiration interval'`
+- **set the crop area**: `set_crop_data(screenshot_area, 20)`
+
+In particular `set_crop_data` accepts as arguments: a `DOM` element and a padding, the padding will be added around the element enlarging the screenshot area.
+
+#### Live example
+
+Please use `spec/docs_screenshots/container_registry_docs.rb` as a guide and as an example to create your own scripts.
diff --git a/doc/development/telemetry/usage_ping.md b/doc/development/telemetry/usage_ping.md
index 7a3a501fa94..771486944c6 100644
--- a/doc/development/telemetry/usage_ping.md
+++ b/doc/development/telemetry/usage_ping.md
@@ -37,7 +37,7 @@ More useful links:
- The main purpose of Usage Ping is to build a better GitLab. Data about how GitLab is used is collected to better understand feature/stage adoption and usage, which helps us understand how GitLab is adding value and helps our team better understand the reasons why people use GitLab and with this knowledge we're able to make better product decisions.
- As a benefit of having the usage ping active, GitLab lets you analyze the users’ activities over time of your GitLab installation.
-- As a benefit of having the usage ping active, GitLab provides you with The DevOps Score,which gives you an overview of your entire instance’s adoption of Concurrent DevOps from planning to monitoring.
+- As a benefit of having the usage ping active, GitLab provides you with The DevOps Report,which gives you an overview of your entire instance’s adoption of Concurrent DevOps from planning to monitoring.
- You will get better, more proactive support. (assuming that our TAMs and support organization used the data to deliver more value)
- You will get insight and advice into how to get the most value out of your investment in GitLab. Wouldn't you want to know that a number of features or values are not being adopted in your organization?
- You get a report that illustrates how you compare against other similar organizations (anonymized), with specific advice and recommendations on how to improve your DevOps processes.
@@ -108,7 +108,7 @@ sequenceDiagram
S3 Bucket->>Snowflake DW: Import data
Snowflake DW->>Snowflake DW: Transform data using dbt
Snowflake DW->>Sisense Dashboards: Data available for querying
- Versions Application->>GitLab Instance: DevOps Score (Conversational Development Index)
+ Versions Application->>GitLab Instance: DevOps Report (Conversational Development Index)
```
## How Usage Ping works
diff --git a/doc/operations/metrics/embed.md b/doc/operations/metrics/embed.md
index 62d60921c85..fcf9679d164 100644
--- a/doc/operations/metrics/embed.md
+++ b/doc/operations/metrics/embed.md
@@ -20,15 +20,28 @@ metrics to others, and you want to have relevant information directly available.
NOTE: **Note:**
Requires [Kubernetes](../../user/project/integrations/prometheus_library/kubernetes.md) metrics.
+Note: **Note:**
+In GitLab versions 13.3 and earlier, metrics dashboard links were in the form
+`https://<root_url>/<project>/-/environments/<environment_id>/metrics`. These links
+are still supported, and can be used to embed metric charts.
+
To display metric charts, include a link of the form
-`https://<root_url>/<project>/-/environments/<environment_id>/metrics` in a field
+`https://<root_url>/<project>/-/metrics?environment=<environment_id>` in a field
that supports GitLab-flavored Markdown:
-![Embedded Metrics Markdown](img/embedded_metrics_markdown_v12_8.png)
+```markdown
+### Summary
+
+**Start time:** 2020-01-21T12:00:31+00:00
+
+### Metrics
+
+https://gitlab.com/gitlab-org/monitor/tanuki-inc/-/metrics?environment=1118134
+```
GitLab unfurls the link as an embedded metrics panel:
-![Embedded Metrics Rendered](img/embedded_metrics_rendered_v12_8.png)
+![Embedded Metrics Rendered](img/embedded_metrics_rendered_v13_4.png)
You can also embed a single chart. To get a link to a chart, click the
**{ellipsis_v}** **More actions** menu in the upper right corner of the chart,
diff --git a/doc/operations/metrics/img/embedded_metrics_markdown_v12_8.png b/doc/operations/metrics/img/embedded_metrics_markdown_v12_8.png
deleted file mode 100644
index ffd34705464..00000000000
--- a/doc/operations/metrics/img/embedded_metrics_markdown_v12_8.png
+++ /dev/null
Binary files differ
diff --git a/doc/operations/metrics/img/embedded_metrics_rendered_v12_8.png b/doc/operations/metrics/img/embedded_metrics_rendered_v12_8.png
deleted file mode 100644
index b024daaaa8e..00000000000
--- a/doc/operations/metrics/img/embedded_metrics_rendered_v12_8.png
+++ /dev/null
Binary files differ
diff --git a/doc/operations/metrics/img/embedded_metrics_rendered_v13_4.png b/doc/operations/metrics/img/embedded_metrics_rendered_v13_4.png
new file mode 100644
index 00000000000..876972dc721
--- /dev/null
+++ b/doc/operations/metrics/img/embedded_metrics_rendered_v13_4.png
Binary files differ
diff --git a/doc/user/admin_area/analytics/convdev.md b/doc/user/admin_area/analytics/convdev.md
index 9df8cbe021d..3ffda3f4400 100644
--- a/doc/user/admin_area/analytics/convdev.md
+++ b/doc/user/admin_area/analytics/convdev.md
@@ -1,5 +1,5 @@
---
-redirect_to: 'dev_ops_score.md'
+redirect_to: 'dev_ops_report.md'
---
-This document was moved to [another location](dev_ops_score.md).
+This document was moved to [another location](dev_ops_report.md).
diff --git a/doc/user/admin_area/analytics/dev_ops_score.md b/doc/user/admin_area/analytics/dev_ops_report.md
index 5f4ae21b5f0..8c21570937d 100644
--- a/doc/user/admin_area/analytics/dev_ops_score.md
+++ b/doc/user/admin_area/analytics/dev_ops_report.md
@@ -1,4 +1,4 @@
-# DevOps Score
+# DevOps Report
> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/30469) in GitLab 9.3.
> - [Renamed from Conversational Development Index](https://gitlab.com/gitlab-org/gitlab/-/issues/20976) in GitLab 12.6.
@@ -6,7 +6,7 @@
NOTE: **Note:**
Your GitLab instance's [usage ping](../settings/usage_statistics.md#usage-ping-core-only) must be activated in order to use this feature.
-The DevOps Score gives you an overview of your entire instance's adoption of
+The DevOps Report gives you an overview of your entire instance's adoption of
[Concurrent DevOps](https://about.gitlab.com/topics/concurrent-devops/)
from planning to monitoring.
@@ -15,9 +15,9 @@ the last 30 days, averaged over the number of active users in that time period.
provides a Lead score per feature, which is calculated based on GitLab's analysis
of top-performing instances based on [usage ping data](../settings/usage_statistics.md#usage-ping-core-only) that GitLab has
collected. Your score is compared to the lead score of each feature and then expressed as a percentage at the bottom of said feature.
-Your overall **index score** is an average of your feature scores. You can use this score to compare your DevOps status to other organizations.
+Your overall **DevOps Score** is an average of your feature scores. You can use this score to compare your DevOps status to other organizations.
-![DevOps Score](img/dev_ops_score_v12_6.png)
+![DevOps Report](img/dev_ops_report_v13_4.png)
The page also provides helpful links to articles and GitLab docs, to help you
improve your scores.
diff --git a/doc/user/admin_area/analytics/img/dev_ops_report_v13_4.png b/doc/user/admin_area/analytics/img/dev_ops_report_v13_4.png
new file mode 100644
index 00000000000..1fa070a6915
--- /dev/null
+++ b/doc/user/admin_area/analytics/img/dev_ops_report_v13_4.png
Binary files differ
diff --git a/doc/user/admin_area/analytics/img/dev_ops_score_v12_6.png b/doc/user/admin_area/analytics/img/dev_ops_score_v12_6.png
deleted file mode 100644
index 3d697a30f66..00000000000
--- a/doc/user/admin_area/analytics/img/dev_ops_score_v12_6.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/admin_area/analytics/index.md b/doc/user/admin_area/analytics/index.md
index b7fc8a656d0..b3336b471f8 100644
--- a/doc/user/admin_area/analytics/index.md
+++ b/doc/user/admin_area/analytics/index.md
@@ -6,5 +6,5 @@ Administrators have access to instance-wide analytics, as shown in **Admin Area
There are two kinds of statistics:
-- [Dev Ops Score](dev_ops_score.md): Provides an overview of your entire instance's feature usage.
+- [DevOps Report](dev_ops_report.md): Provides an overview of your entire instance's feature usage.
- [User Cohorts](user_cohorts.md): Display the monthly cohorts of new users and their activities over time.
diff --git a/doc/user/admin_area/monitoring/convdev.md b/doc/user/admin_area/monitoring/convdev.md
index afdf3dc5849..d9c3950f2e4 100644
--- a/doc/user/admin_area/monitoring/convdev.md
+++ b/doc/user/admin_area/monitoring/convdev.md
@@ -1,5 +1,5 @@
---
-redirect_to: '../analytics/dev_ops_score.md'
+redirect_to: '../analytics/dev_ops_report.md'
---
-Conversational Development Index was renamed to [DevOps Score](../analytics/dev_ops_score.md) in GitLab 12.6.
+Conversational Development Index was renamed to [DevOps Report](../analytics/dev_ops_report.md) in GitLab 12.6.
diff --git a/doc/user/admin_area/monitoring/dev_ops_score.md b/doc/user/admin_area/monitoring/dev_ops_report.md
index 70c668870fd..9ad9830ed59 100644
--- a/doc/user/admin_area/monitoring/dev_ops_score.md
+++ b/doc/user/admin_area/monitoring/dev_ops_report.md
@@ -1,5 +1,5 @@
---
-redirect_to: '../analytics/dev_ops_score.md'
+redirect_to: '../analytics/dev_ops_report.md'
---
-This document was moved to [another location](../analytics/dev_ops_score.md).
+This document was moved to [another location](../analytics/dev_ops_report.md).
diff --git a/doc/user/admin_area/settings/img/domain_blacklist.png b/doc/user/admin_area/settings/img/domain_denylist.png
index a7e972b7c0a..a7e972b7c0a 100644
--- a/doc/user/admin_area/settings/img/domain_blacklist.png
+++ b/doc/user/admin_area/settings/img/domain_denylist.png
Binary files differ
diff --git a/doc/user/admin_area/settings/sign_up_restrictions.md b/doc/user/admin_area/settings/sign_up_restrictions.md
index 8ef5ac8dc8f..99fc82f94ed 100644
--- a/doc/user/admin_area/settings/sign_up_restrictions.md
+++ b/doc/user/admin_area/settings/sign_up_restrictions.md
@@ -8,7 +8,7 @@ You can use sign-up restrictions to:
- Disable new signups.
- Require user email confirmation.
-- Blacklist or whitelist email addresses belonging to specific domains.
+- Denylist or allowlist email addresses belonging to specific domains.
NOTE: **Note:**
These restrictions are only applied during sign-up from an external user. An admin is
@@ -31,7 +31,7 @@ consider disabling new signups if you do not expect public users to sign up for
account.
Alternatively, you could also consider setting up a
-[whitelist](#whitelist-email-domains) or [blacklist](#blacklist-email-domains) on
+[allowlist](#allowlist-email-domains) or [denylist](#denylist-email-domains) on
email domains to prevent malicious users from creating accounts.
## Require email confirmation
@@ -48,14 +48,14 @@ their email address before they are allowed to sign in.
You can [change](../../../security/password_length_limits.md#modify-minimum-password-length-using-gitlab-ui)
the minimum number of characters a user must have in their password using the GitLab UI.
-## Whitelist email domains
+## Allowlist email domains
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/598) in GitLab 7.11.0
You can restrict users to only sign up using email addresses matching the given
domains list.
-## Blacklist email domains
+## Denylist email domains
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/5259) in GitLab 8.10.
@@ -71,17 +71,17 @@ To access this feature:
1. Navigate to the **Admin Area > Settings > General**.
1. Expand the **Sign-up restrictions** section.
-For the blacklist, you can enter the list manually or upload a `.txt` file that
+For the denylist, you can enter the list manually or upload a `.txt` file that
contains list entries.
-For the whitelist, you must enter the list manually.
+For the allowlist, you must enter the list manually.
-Both the whitelist and blacklist accept wildcards. For example, you can use
+Both the allowlist and denylist accept wildcards. For example, you can use
`*.company.com` to accept every `company.com` subdomain, or `*.io` to block all
domains ending in `.io`. Domains should be separated by a whitespace,
semicolon, comma, or a new line.
-![Domain Blacklist](img/domain_blacklist.png)
+![Domain Denylist](img/domain_denylist.png)
<!-- ## Troubleshooting
diff --git a/lib/api/users.rb b/lib/api/users.rb
index 335624963aa..aa3ecf4019d 100644
--- a/lib/api/users.rb
+++ b/lib/api/users.rb
@@ -84,6 +84,7 @@ module API
optional :created_after, type: DateTime, desc: 'Return users created after the specified time'
optional :created_before, type: DateTime, desc: 'Return users created before the specified time'
optional :without_projects, type: Boolean, default: false, desc: 'Filters only users without projects'
+ optional :exclude_internal, as: :non_internal, type: Boolean, default: false, desc: 'Filters only non internal users'
all_or_none_of :extern_uid, :provider
use :sort_params
diff --git a/lib/banzai/filter/inline_metrics_filter.rb b/lib/banzai/filter/inline_metrics_filter.rb
index 543d98e62be..2872ad7b632 100644
--- a/lib/banzai/filter/inline_metrics_filter.rb
+++ b/lib/banzai/filter/inline_metrics_filter.rb
@@ -10,7 +10,6 @@ module Banzai
# the cost of doing a full regex match.
def xpath_search
"descendant-or-self::a[contains(@href,'metrics') and \
- contains(@href,'environments') and \
starts-with(@href, '#{gitlab_domain}')]"
end
@@ -29,7 +28,7 @@ module Banzai
params['project'],
params['environment'],
embedded: true,
- **query_params(params['url'])
+ **query_params(params['url']).except(:environment)
)
end
end
diff --git a/lib/gitlab/metrics/dashboard/url.rb b/lib/gitlab/metrics/dashboard/url.rb
index 160ecfb85c9..6dcc73c0f6a 100644
--- a/lib/gitlab/metrics/dashboard/url.rb
+++ b/lib/gitlab/metrics/dashboard/url.rb
@@ -10,20 +10,23 @@ module Gitlab
QUERY_PATTERN = '(?<query>\?[a-zA-Z0-9%.()+_=-]+(&[a-zA-Z0-9%.()+_=-]+)*)?'
ANCHOR_PATTERN = '(?<anchor>\#[a-z0-9_-]+)?'
- OPTIONAL_DASH_PATTERN = '(?:/-)?'
+ DASH_PATTERN = '(?:/-)'
- # Matches urls for a metrics dashboard. This could be
- # either the /metrics endpoint or the /metrics_dashboard
- # endpoint.
+ # Matches urls for a metrics dashboard.
+ # This regex needs to match the old metrics URL, the new metrics URL,
+ # and the dashboard URL (inline_metrics_redactor_filter.rb
+ # uses this regex to match against the dashboard URL.)
#
- # EX - https://<host>/<namespace>/<project>/environments/<env_id>/metrics
+ # EX - Old URL: https://<host>/<namespace>/<project>/environments/<env_id>/metrics
+ # OR
+ # New URL: https://<host>/<namespace>/<project>/-/metrics?environment=<env_id>
+ # OR
+ # dashboard URL: https://<host>/<namespace>/<project>/environments/<env_id>/metrics_dashboard
def metrics_regex
strong_memoize(:metrics_regex) do
regex_for_project_metrics(
%r{
- /environments
- /(?<environment>\d+)
- /(metrics_dashboard|metrics)
+ ( #{environment_metrics_regex} ) | ( #{non_environment_metrics_regex} )
}x
)
end
@@ -36,6 +39,7 @@ module Gitlab
strong_memoize(:grafana_regex) do
regex_for_project_metrics(
%r{
+ #{DASH_PATTERN}?
/grafana
/metrics_dashboard
}x
@@ -44,16 +48,22 @@ module Gitlab
end
# Matches dashboard urls for a metric chart embed
- # for cluster metrics
+ # for cluster metrics.
+ # This regex needs to match the dashboard URL as well, not just the trigger URL.
+ # The inline_metrics_redactor_filter.rb uses this regex to match against
+ # the dashboard URL.
#
# EX - https://<host>/<namespace>/<project>/-/clusters/<cluster_id>/?group=Cluster%20Health&title=Memory%20Usage&y_label=Memory%20(GiB)
+ # dashboard URL - https://<host>/<namespace>/<project>/-/clusters/<cluster_id>/metrics_dashboard?group=Cluster%20Health&title=Memory%20Usage&y_label=Memory%20(GiB)
def clusters_regex
strong_memoize(:clusters_regex) do
regex_for_project_metrics(
%r{
+ #{DASH_PATTERN}?
/clusters
/(?<cluster_id>\d+)
/?
+ ( (/metrics) | ( /metrics_dashboard\.json ) )?
}x
)
end
@@ -67,10 +77,11 @@ module Gitlab
strong_memoize(:alert_regex) do
regex_for_project_metrics(
%r{
+ #{DASH_PATTERN}?
/prometheus
/alerts
/(?<alert>\d+)
- /metrics_dashboard
+ /metrics_dashboard(\.json)?
}x
)
end
@@ -95,16 +106,37 @@ module Gitlab
private
+ def environment_metrics_regex
+ %r{
+ #{DASH_PATTERN}?
+ /environments
+ /(?<environment>\d+)
+ /(metrics_dashboard|metrics)
+ }x
+ end
+
+ def non_environment_metrics_regex
+ %r{
+ #{DASH_PATTERN}
+ /metrics
+ (?= # Lookahead to ensure there is an environment query param
+ \?
+ .*
+ environment=(?<environment>\d+)
+ .*
+ )
+ }x
+ end
+
def regex_for_project_metrics(path_suffix_pattern)
%r{
- (?<url>
+ ^(?<url>
#{gitlab_host_pattern}
#{project_path_pattern}
- #{OPTIONAL_DASH_PATTERN}
#{path_suffix_pattern}
#{QUERY_PATTERN}
#{ANCHOR_PATTERN}
- )
+ )$
}x
end
diff --git a/lib/tasks/pngquant.rake b/lib/tasks/pngquant.rake
index ceb4de55373..63bc1c7c16e 100644
--- a/lib/tasks/pngquant.rake
+++ b/lib/tasks/pngquant.rake
@@ -2,10 +2,10 @@ return if Rails.env.production?
require 'png_quantizator'
require 'parallel'
+require_relative '../../tooling/lib/tooling/images'
# The amount of variance (in bytes) allowed in
# file size when testing for compression size
-TOLERANCE = 10000
namespace :pngquant do
# Returns an array of all images eligible for compression
@@ -13,55 +13,13 @@ namespace :pngquant do
Dir.glob('doc/**/*.png', File::FNM_CASEFOLD)
end
- # Runs pngquant on an image and optionally
- # writes the result to disk
- def compress_image(file, overwrite_original)
- compressed_file = "#{file}.compressed"
- FileUtils.copy(file, compressed_file)
-
- pngquant_file = PngQuantizator::Image.new(compressed_file)
-
- # Run the image repeatedly through pngquant until
- # the change in file size is within TOLERANCE
- loop do
- before = File.size(compressed_file)
- pngquant_file.quantize!
- after = File.size(compressed_file)
- break if before - after <= TOLERANCE
- end
-
- savings = File.size(file) - File.size(compressed_file)
- is_uncompressed = savings > TOLERANCE
-
- if is_uncompressed && overwrite_original
- FileUtils.copy(compressed_file, file)
- end
-
- FileUtils.remove(compressed_file)
-
- [is_uncompressed, savings]
- end
-
- # Ensures pngquant is available and prints an error if not
- def check_executable
- unless system('pngquant --version', out: File::NULL)
- warn(
- 'Error: pngquant executable was not detected in the system.'.color(:red),
- 'Download pngquant at https://pngquant.org/ and place the executable in /usr/local/bin'.color(:green)
- )
- abort
- end
- end
-
desc 'GitLab | Pngquant | Compress all documentation PNG images using pngquant'
task :compress do
- check_executable
-
files = doc_images
puts "Compressing #{files.size} PNG files in doc/**"
Parallel.each(files) do |file|
- was_uncompressed, savings = compress_image(file, true)
+ was_uncompressed, savings = Tooling::Image.compress_image(file)
if was_uncompressed
puts "#{file} was reduced by #{savings} bytes"
@@ -71,13 +29,11 @@ namespace :pngquant do
desc 'GitLab | Pngquant | Checks that all documentation PNG images have been compressed with pngquant'
task :lint do
- check_executable
-
files = doc_images
puts "Checking #{files.size} PNG files in doc/**"
uncompressed_files = Parallel.map(files) do |file|
- is_uncompressed, _ = compress_image(file, false)
+ is_uncompressed, _ = Tooling::Image.compress_image(file, true)
if is_uncompressed
puts "Uncompressed file detected: ".color(:red) + file
file
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 8b819f2acb7..85e76c9137b 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -5156,6 +5156,9 @@ msgstr ""
msgid "ClusterAgent|This feature is only available for premium plans"
msgstr ""
+msgid "ClusterAgent|User has insufficient permissions to create a token for this project"
+msgstr ""
+
msgid "ClusterAgent|You have insufficient permissions to create a cluster agent for this project"
msgstr ""
@@ -8583,7 +8586,10 @@ msgstr ""
msgid "Detect host keys"
msgstr ""
-msgid "DevOps Score"
+msgid "DevOps"
+msgstr ""
+
+msgid "DevOps Report"
msgstr ""
msgid "Diff content limits"
@@ -8729,7 +8735,7 @@ msgid_plural "Dismiss %d selected vulnerabilities as"
msgstr[0] ""
msgstr[1] ""
-msgid "Dismiss DevOps Score introduction"
+msgid "Dismiss DevOps Report introduction"
msgstr ""
msgid "Dismiss Merge Request promotion"
@@ -13318,7 +13324,7 @@ msgstr ""
msgid "Introducing Value Stream Analytics"
msgstr ""
-msgid "Introducing Your DevOps Score"
+msgid "Introducing Your DevOps Report"
msgstr ""
msgid "Invalid Git ref"
@@ -21469,6 +21475,9 @@ msgstr ""
msgid "Scopes can't be blank"
msgstr ""
+msgid "Score"
+msgstr ""
+
msgid "Scroll down"
msgstr ""
@@ -28572,7 +28581,7 @@ msgstr ""
msgid "Your Default Notification Email will be used for account notifications if a %{openingTag}group-specific email address%{closingTag} is not set."
msgstr ""
-msgid "Your DevOps Score gives an overview of how you are using GitLab from a feature perspective. View how you compare with other organizations, discover features you are not using, and learn best practices through blog posts and white papers."
+msgid "Your DevOps Report gives an overview of how you are using GitLab from a feature perspective. View how you compare with other organizations, discover features you are not using, and learn best practices through blog posts and white papers."
msgstr ""
msgid "Your GPG keys (%{count})"
@@ -29323,9 +29332,6 @@ msgstr ""
msgid "in project %{link_to_project}"
msgstr ""
-msgid "index"
-msgstr ""
-
msgid "instance completed"
msgid_plural "instances completed"
msgstr[0] ""
@@ -29997,9 +30003,6 @@ msgstr ""
msgid "satisfied"
msgstr ""
-msgid "score"
-msgstr ""
-
msgid "security Reports|There was an error creating the merge request"
msgstr ""
diff --git a/rubocop/cop/rspec/top_level_describe_path.rb b/rubocop/cop/rspec/top_level_describe_path.rb
index 61796e23af0..3cc1ee8df90 100644
--- a/rubocop/cop/rspec/top_level_describe_path.rb
+++ b/rubocop/cop/rspec/top_level_describe_path.rb
@@ -21,7 +21,7 @@ module RuboCop
private
def acceptable_file_path?(path)
- File.fnmatch?('*_spec.rb', path) || File.fnmatch?('*/frontend/fixtures/*', path)
+ File.fnmatch?('*_spec.rb', path) || File.fnmatch?('*/frontend/fixtures/*', path) || File.fnmatch?('*/docs_screenshots/*_docs.rb', path)
end
def shared_example?(node)
diff --git a/scripts/docs_screenshots.rb b/scripts/docs_screenshots.rb
new file mode 100755
index 00000000000..e02d67de748
--- /dev/null
+++ b/scripts/docs_screenshots.rb
@@ -0,0 +1,60 @@
+#!/usr/bin/env ruby
+
+# frozen_string_literal: true
+
+require 'png_quantizator'
+require 'open3'
+require 'parallel'
+require_relative '../tooling/lib/tooling/images.rb'
+
+generator = ARGV[0]
+milestone = ARGV[1]
+
+unless generator
+ warn('Error: missing generator, please supply one')
+ abort
+end
+
+unless milestone
+ warn('Error: missing milestone, please supply one')
+ abort
+end
+
+def rename_image(file, milestone)
+ path = File.dirname(file)
+ basename = File.basename(file)
+ final_name = File.join(path, "#{basename}_v#{milestone}.png")
+ FileUtils.mv(file, final_name)
+end
+
+system('spring', 'rspec', generator)
+
+files = []
+
+Open3.popen3("git diff --name-only -- '*.png'") do |stdin, stdout, stderr, thread|
+ files.concat stdout.read.chomp.split("\n")
+end
+
+Open3.popen3("git status --porcelain -- '*.png'") do |stdin, stdout, stderr, thread|
+ files.concat stdout.read.chomp.split("?? ")
+end
+
+files.reject!(&:empty?)
+
+if files.empty?
+ puts "No file generated, did you select the right screenshot generator?"
+else
+ puts "Compressing newly generated screenshots"
+
+ Parallel.each(files) do |file|
+ file_path = File.join(Dir.pwd, file.to_s.strip)
+ was_uncompressed, savings = Tooling::Image.compress_image(file_path)
+ rename_image(file_path, milestone)
+
+ if was_uncompressed
+ puts "#{file} was reduced by #{savings} bytes."
+ else
+ puts "Skipping already compressed file: #{file}."
+ end
+ end
+end
diff --git a/spec/controllers/projects/graphs_controller_spec.rb b/spec/controllers/projects/graphs_controller_spec.rb
index 49def8f80b0..be89fa0d361 100644
--- a/spec/controllers/projects/graphs_controller_spec.rb
+++ b/spec/controllers/projects/graphs_controller_spec.rb
@@ -44,7 +44,7 @@ RSpec.describe Projects::GraphsController do
context 'when anonymous users can read build report results' do
it 'sets the daily coverage options' do
- Timecop.freeze do
+ freeze_time do
get(:charts, params: { namespace_id: project.namespace.path, project_id: project.path, id: 'master' })
expect(assigns[:daily_coverage_options]).to eq(
diff --git a/spec/controllers/projects/issues_controller_spec.rb b/spec/controllers/projects/issues_controller_spec.rb
index a0e478ef368..f851418ae09 100644
--- a/spec/controllers/projects/issues_controller_spec.rb
+++ b/spec/controllers/projects/issues_controller_spec.rb
@@ -6,9 +6,9 @@ RSpec.describe Projects::IssuesController do
include ProjectForksHelper
include_context 'includes Spam constants'
- let(:project) { create(:project) }
- let(:user) { create(:user) }
- let(:issue) { create(:issue, project: project) }
+ let_it_be(:project, reload: true) { create(:project) }
+ let_it_be(:user, reload: true) { create(:user) }
+ let(:issue) { create(:issue, project: project) }
describe "GET #index" do
context 'external issue tracker' do
@@ -39,8 +39,8 @@ RSpec.describe Projects::IssuesController do
end
context 'when project has moved' do
- let(:new_project) { create(:project) }
- let(:issue) { create(:issue, project: new_project) }
+ let_it_be(:new_project) { create(:project) }
+ let_it_be(:issue) { create(:issue, project: new_project) }
before do
project.route.destroy
@@ -297,6 +297,7 @@ RSpec.describe Projects::IssuesController do
project.add_developer(developer)
end
+ let_it_be(:issue) { create(:issue, project: project) }
let(:developer) { user }
let(:params) do
{
@@ -401,7 +402,7 @@ RSpec.describe Projects::IssuesController do
end
context 'when moving issue to another private project' do
- let(:another_project) { create(:project, :private) }
+ let_it_be(:another_project) { create(:project, :private) }
context 'when user has access to move issue' do
before do
@@ -438,10 +439,10 @@ RSpec.describe Projects::IssuesController do
end
describe 'PUT #reorder' do
- let(:group) { create(:group, projects: [project]) }
- let!(:issue1) { create(:issue, project: project, relative_position: 10) }
- let!(:issue2) { create(:issue, project: project, relative_position: 20) }
- let!(:issue3) { create(:issue, project: project, relative_position: 30) }
+ let_it_be(:group) { create(:group, projects: [project]) }
+ let_it_be(:issue1) { create(:issue, project: project, relative_position: 10) }
+ let_it_be(:issue2) { create(:issue, project: project, relative_position: 20) }
+ let_it_be(:issue3) { create(:issue, project: project, relative_position: 30) }
before do
sign_in(user)
@@ -657,15 +658,15 @@ RSpec.describe Projects::IssuesController do
end
describe 'Confidential Issues' do
- let(:project) { create(:project_empty_repo, :public) }
- let(:assignee) { create(:assignee) }
- let(:author) { create(:user) }
- let(:non_member) { create(:user) }
- let(:member) { create(:user) }
- let(:admin) { create(:admin) }
- let!(:issue) { create(:issue, project: project) }
- let!(:unescaped_parameter_value) { create(:issue, :confidential, project: project, author: author) }
- let!(:request_forgery_timing_attack) { create(:issue, :confidential, project: project, assignees: [assignee]) }
+ let_it_be(:project) { create(:project_empty_repo, :public) }
+ let_it_be(:assignee) { create(:assignee) }
+ let_it_be(:author) { create(:user) }
+ let_it_be(:non_member) { create(:user) }
+ let_it_be(:member) { create(:user) }
+ let_it_be(:admin) { create(:admin) }
+ let_it_be(:issue) { create(:issue, project: project) }
+ let_it_be(:unescaped_parameter_value) { create(:issue, :confidential, project: project, author: author) }
+ let_it_be(:request_forgery_timing_attack) { create(:issue, :confidential, project: project, assignees: [assignee]) }
describe 'GET #index' do
it 'does not list confidential issues for guests' do
@@ -1077,7 +1078,7 @@ RSpec.describe Projects::IssuesController do
end
context 'resolving discussions in MergeRequest' do
- let(:discussion) { create(:diff_note_on_merge_request).to_discussion }
+ let_it_be(:discussion) { create(:diff_note_on_merge_request).to_discussion }
let(:merge_request) { discussion.noteable }
let(:project) { merge_request.source_project }
@@ -1376,9 +1377,9 @@ RSpec.describe Projects::IssuesController do
end
context "when the user is owner" do
- let(:owner) { create(:user) }
- let(:namespace) { create(:namespace, owner: owner) }
- let(:project) { create(:project, namespace: namespace) }
+ let_it_be(:owner) { create(:user) }
+ let_it_be(:namespace) { create(:namespace, owner: owner) }
+ let_it_be(:project) { create(:project, namespace: namespace) }
before do
sign_in(owner)
@@ -1461,7 +1462,8 @@ RSpec.describe Projects::IssuesController do
describe 'POST create_merge_request' do
let(:target_project_id) { nil }
- let(:project) { create(:project, :repository, :public) }
+
+ let_it_be(:project) { create(:project, :repository, :public) }
before do
project.add_developer(user)
@@ -1539,7 +1541,7 @@ RSpec.describe Projects::IssuesController do
end
describe 'POST #import_csv' do
- let(:project) { create(:project, :public) }
+ let_it_be(:project) { create(:project, :public) }
let(:file) { fixture_file_upload('spec/fixtures/csv_comma.csv') }
context 'unauthorized' do
@@ -1621,7 +1623,7 @@ RSpec.describe Projects::IssuesController do
end
context 'when not logged in' do
- let(:project) { create(:project_empty_repo, :public) }
+ let(:empty_project) { create(:project_empty_repo, :public) }
it 'redirects to the sign in page' do
request_csv
@@ -1738,7 +1740,7 @@ RSpec.describe Projects::IssuesController do
end
context 'with cross-reference system note', :request_store do
- let(:new_issue) { create(:issue) }
+ let_it_be(:new_issue) { create(:issue) }
let(:cross_reference) { "mentioned in #{new_issue.to_reference(issue.project)}" }
before do
@@ -1836,7 +1838,7 @@ RSpec.describe Projects::IssuesController do
end
context 'private project with token authentication' do
- let(:private_project) { create(:project, :private) }
+ let_it_be(:private_project) { create(:project, :private) }
it_behaves_like 'authenticates sessionless user', :index, :atom, ignore_incrementing: true do
before do
@@ -1856,7 +1858,7 @@ RSpec.describe Projects::IssuesController do
end
context 'public project with token authentication' do
- let(:public_project) { create(:project, :public) }
+ let_it_be(:public_project) { create(:project, :public) }
it_behaves_like 'authenticates sessionless user', :index, :atom, public: true do
before do
diff --git a/spec/controllers/projects/notes_controller_spec.rb b/spec/controllers/projects/notes_controller_spec.rb
index 570d65dba4f..8c59b2b378f 100644
--- a/spec/controllers/projects/notes_controller_spec.rb
+++ b/spec/controllers/projects/notes_controller_spec.rb
@@ -98,7 +98,7 @@ RSpec.describe Projects::NotesController do
let(:page_2_boundary) { microseconds(page_2.last.updated_at + NotesFinder::FETCH_OVERLAP) }
around do |example|
- Timecop.freeze do
+ freeze_time do
example.run
end
end
diff --git a/spec/db/schema_spec.rb b/spec/db/schema_spec.rb
index 1c9167ef025..ff39bf81d3f 100644
--- a/spec/db/schema_spec.rb
+++ b/spec/db/schema_spec.rb
@@ -35,7 +35,6 @@ RSpec.describe 'Database schema' do
deploy_keys_projects: %w[deploy_key_id],
deployments: %w[deployable_id environment_id user_id],
draft_notes: %w[discussion_id commit_id],
- emails: %w[user_id],
epics: %w[updated_by_id last_edited_by_id state_id],
events: %w[target_id],
forked_project_links: %w[forked_from_project_id],
diff --git a/spec/docs_screenshots/container_registry_docs.rb b/spec/docs_screenshots/container_registry_docs.rb
new file mode 100644
index 00000000000..7e533bdf1d7
--- /dev/null
+++ b/spec/docs_screenshots/container_registry_docs.rb
@@ -0,0 +1,87 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'Container Registry', :js do
+ include DocsScreenshotHelpers
+
+ let(:user) { create(:user) }
+ let(:group) { create(:group) }
+ let(:project) { create(:project, namespace: group) }
+
+ before do
+ page.driver.browser.manage.window.resize_to(1366, 1024)
+
+ group.add_owner(user)
+ sign_in(user)
+
+ stub_container_registry_config(enabled: true)
+ stub_container_registry_tags(repository: :any, tags: [])
+ end
+
+ context 'expiration policy settings' do
+ it 'user/packages/container_registry/img/expiration_policy_form' do
+ visit project_settings_ci_cd_path(project)
+ screenshot_area = find('#js-registry-policies')
+ scroll_to screenshot_area
+ expect(screenshot_area).to have_content 'Expiration interval'
+ set_crop_data(screenshot_area, 20)
+ end
+ end
+
+ context 'project container_registry' do
+ it 'user/packages/container_registry/img/project_empty_page' do
+ visit_project_container_registry
+
+ expect(page).to have_content _('There are no container images stored for this project')
+ end
+
+ context 'with a list of repositories' do
+ before do
+ stub_container_registry_tags(repository: %r{my/image}, tags: %w[latest], with_manifest: true)
+ create_list(:container_repository, 12, project: project)
+ end
+
+ it 'user/packages/container_registry/img/project_image_repositories_list' do
+ visit_project_container_registry
+
+ expect(page).to have_content 'Image Repositories'
+ end
+
+ it 'user/packages/container_registry/img/project_image_repositories_list_with_commands_open' do
+ visit_project_container_registry
+
+ click_on 'CLI Commands'
+ end
+ end
+ end
+
+ context 'group container_registry' do
+ it 'user/packages/container_registry/img/group_empty_page' do
+ visit_group_container_registry
+
+ expect(page).to have_content 'There are no container images available in this group'
+ end
+
+ context 'with a list of repositories' do
+ before do
+ stub_container_registry_tags(repository: %r{my/image}, tags: %w[latest], with_manifest: true)
+ create_list(:container_repository, 12, project: project)
+ end
+
+ it 'user/packages/container_registry/img/group_image_repositories_list' do
+ visit_group_container_registry
+
+ expect(page).to have_content 'Image Repositories'
+ end
+ end
+ end
+
+ def visit_project_container_registry
+ visit project_container_registry_index_path(project)
+ end
+
+ def visit_group_container_registry
+ visit group_container_registries_path(group)
+ end
+end
diff --git a/spec/features/admin/admin_dev_ops_score_spec.rb b/spec/features/admin/admin_dev_ops_score_spec.rb
index 72e82156526..31a2b4bbe72 100644
--- a/spec/features/admin/admin_dev_ops_score_spec.rb
+++ b/spec/features/admin/admin_dev_ops_score_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'DevOps Score page' do
+RSpec.describe 'DevOps Report page' do
before do
sign_in(create(:admin))
end
@@ -10,11 +10,11 @@ RSpec.describe 'DevOps Score page' do
it 'has dismissable intro callout', :js do
visit admin_dev_ops_score_path
- expect(page).to have_content 'Introducing Your DevOps Score'
+ expect(page).to have_content 'Introducing Your DevOps Report'
find('.js-close-callout').click
- expect(page).not_to have_content 'Introducing Your DevOps Score'
+ expect(page).not_to have_content 'Introducing Your DevOps Report'
end
context 'when usage ping is disabled' do
@@ -31,7 +31,7 @@ RSpec.describe 'DevOps Score page' do
it 'hides the intro callout' do
visit admin_dev_ops_score_path
- expect(page).not_to have_content 'Introducing Your DevOps Score'
+ expect(page).not_to have_content 'Introducing Your DevOps Report'
end
end
diff --git a/spec/features/boards/sidebar_spec.rb b/spec/features/boards/sidebar_spec.rb
index 65f2e5dfc0d..4b4cb444903 100644
--- a/spec/features/boards/sidebar_spec.rb
+++ b/spec/features/boards/sidebar_spec.rb
@@ -23,7 +23,7 @@ RSpec.describe 'Issue Boards', :js do
let(:application_settings) { {} }
around do |example|
- Timecop.freeze { example.run }
+ freeze_time { example.run }
end
before do
diff --git a/spec/features/groups/milestone_spec.rb b/spec/features/groups/milestone_spec.rb
index 2217bd9d6b5..3ae9a2b7555 100644
--- a/spec/features/groups/milestone_spec.rb
+++ b/spec/features/groups/milestone_spec.rb
@@ -8,7 +8,7 @@ RSpec.describe 'Group milestones' do
let_it_be(:user) { create(:group_member, :maintainer, user: create(:user), group: group ).user }
around do |example|
- Timecop.freeze { example.run }
+ freeze_time { example.run }
end
before do
diff --git a/spec/features/projects/members/invite_group_spec.rb b/spec/features/projects/members/invite_group_spec.rb
index 058cbfff662..30e32ad1366 100644
--- a/spec/features/projects/members/invite_group_spec.rb
+++ b/spec/features/projects/members/invite_group_spec.rb
@@ -112,7 +112,7 @@ RSpec.describe 'Project > Members > Invite group', :js do
let!(:group) { create(:group) }
around do |example|
- Timecop.freeze { example.run }
+ freeze_time { example.run }
end
before do
diff --git a/spec/features/users/login_spec.rb b/spec/features/users/login_spec.rb
index 2d0fcfe84e6..a2fd1caf6a3 100644
--- a/spec/features/users/login_spec.rb
+++ b/spec/features/users/login_spec.rb
@@ -503,7 +503,7 @@ RSpec.describe 'Login' do
context 'within the grace period' do
it 'redirects to two-factor configuration page' do
- Timecop.freeze do
+ freeze_time do
expect(authentication_metrics)
.to increment(:user_authenticated_counter)
diff --git a/spec/finders/users_finder_spec.rb b/spec/finders/users_finder_spec.rb
index 17b36247b05..a04f5452fcd 100644
--- a/spec/finders/users_finder_spec.rb
+++ b/spec/finders/users_finder_spec.rb
@@ -12,7 +12,7 @@ RSpec.describe UsersFinder do
it 'returns all users' do
users = described_class.new(user).execute
- expect(users).to contain_exactly(user, normal_user, blocked_user, omniauth_user)
+ expect(users).to contain_exactly(user, normal_user, blocked_user, omniauth_user, internal_user)
end
it 'filters by username' do
@@ -54,7 +54,7 @@ RSpec.describe UsersFinder do
it 'returns no external users' do
users = described_class.new(user, external: true).execute
- expect(users).to contain_exactly(user, normal_user, blocked_user, omniauth_user)
+ expect(users).to contain_exactly(user, normal_user, blocked_user, omniauth_user, internal_user)
end
it 'filters by created_at' do
@@ -68,19 +68,25 @@ RSpec.describe UsersFinder do
expect(users.map(&:username)).not_to include([filtered_user_before.username, filtered_user_after.username])
end
+ it 'filters by non internal users' do
+ users = described_class.new(user, non_internal: true).execute
+
+ expect(users).to contain_exactly(user, normal_user, blocked_user, omniauth_user)
+ end
+
it 'does not filter by custom attributes' do
users = described_class.new(
user,
custom_attributes: { foo: 'bar' }
).execute
- expect(users).to contain_exactly(user, normal_user, blocked_user, omniauth_user)
+ expect(users).to contain_exactly(user, normal_user, blocked_user, omniauth_user, internal_user)
end
it 'orders returned results' do
users = described_class.new(user, sort: 'id_asc').execute
- expect(users).to eq([normal_user, blocked_user, omniauth_user, user])
+ expect(users).to eq([normal_user, blocked_user, omniauth_user, internal_user, user])
end
end
@@ -96,13 +102,14 @@ RSpec.describe UsersFinder do
it 'returns all users' do
users = described_class.new(admin).execute
- expect(users).to contain_exactly(admin, normal_user, blocked_user, external_user, omniauth_user)
+ expect(users).to contain_exactly(admin, normal_user, blocked_user, external_user, omniauth_user, internal_user)
end
it 'filters by custom attributes' do
create :user_custom_attribute, user: normal_user, key: 'foo', value: 'foo'
create :user_custom_attribute, user: normal_user, key: 'bar', value: 'bar'
create :user_custom_attribute, user: blocked_user, key: 'foo', value: 'foo'
+ create :user_custom_attribute, user: internal_user, key: 'foo', value: 'foo'
users = described_class.new(
admin,
diff --git a/spec/graphql/types/merge_request_type_spec.rb b/spec/graphql/types/merge_request_type_spec.rb
index b11951190e0..a9a74114dda 100644
--- a/spec/graphql/types/merge_request_type_spec.rb
+++ b/spec/graphql/types/merge_request_type_spec.rb
@@ -27,7 +27,10 @@ RSpec.describe GitlabSchema.types['MergeRequest'] do
total_time_spent reference author merged_at commit_count
]
- expected_fields << 'approved_by' if Gitlab.ee?
+ if Gitlab.ee?
+ expected_fields << 'approved'
+ expected_fields << 'approved_by'
+ end
expect(described_class).to have_graphql_fields(*expected_fields)
end
diff --git a/spec/lib/banzai/filter/inline_metrics_filter_spec.rb b/spec/lib/banzai/filter/inline_metrics_filter_spec.rb
index 9b0b95b9da2..cdebd886b16 100644
--- a/spec/lib/banzai/filter/inline_metrics_filter_spec.rb
+++ b/spec/lib/banzai/filter/inline_metrics_filter_spec.rb
@@ -5,25 +5,68 @@ require 'spec_helper'
RSpec.describe Banzai::Filter::InlineMetricsFilter do
include FilterSpecHelper
- let(:params) { ['foo', 'bar', 12] }
- let(:query_params) { {} }
-
- let(:trigger_url) { urls.metrics_namespace_project_environment_url(*params, query_params) }
+ let(:environment_id) { 12 }
let(:dashboard_url) { urls.metrics_dashboard_namespace_project_environment_url(*params, **query_params, embedded: true) }
- it_behaves_like 'a metrics embed filter'
+ let(:query_params) do
+ {
+ dashboard: 'config/prometheus/common_metrics.yml',
+ group: 'System metrics (Kubernetes)',
+ title: 'Core Usage (Pod Average)',
+ y_label: 'Cores per Pod'
+ }
+ end
+
+ context 'with /-/environments/:environment_id/metrics URL' do
+ let(:params) { ['group', 'project', environment_id] }
+ let(:trigger_url) { urls.metrics_namespace_project_environment_url(*params, **query_params) }
+
+ context 'with no query params' do
+ let(:query_params) { {} }
+
+ it_behaves_like 'a metrics embed filter'
+ end
+
+ context 'with query params' do
+ it_behaves_like 'a metrics embed filter'
+ end
+ end
- context 'with query params specified' do
- let(:query_params) do
- {
- dashboard: 'config/prometheus/common_metrics.yml',
- group: 'System metrics (Kubernetes)',
- title: 'Core Usage (Pod Average)',
- y_label: 'Cores per Pod'
- }
+ context 'with /-/metrics?environment=:environment_id URL' do
+ let(:params) { %w(group project) }
+ let(:trigger_url) { urls.namespace_project_metrics_dashboard_url(*params, **query_params) }
+ let(:dashboard_url) do
+ urls.metrics_dashboard_namespace_project_environment_url(
+ *params.append(environment_id),
+ **query_params.except(:environment),
+ embedded: true
+ )
end
- it_behaves_like 'a metrics embed filter'
+ context 'with query params' do
+ it_behaves_like 'a metrics embed filter' do
+ before do
+ query_params.merge!(environment: environment_id)
+ end
+ end
+ end
+
+ context 'with only environment in query params' do
+ let(:query_params) { { environment: environment_id } }
+
+ it_behaves_like 'a metrics embed filter'
+ end
+
+ context 'with no query params' do
+ let(:query_params) { {} }
+
+ it 'ignores metrics URL without environment parameter' do
+ input = %(<a href="#{trigger_url}">example</a>)
+ filtered_input = filter(input).to_s
+
+ expect(CGI.unescape_html(filtered_input)).to eq(input)
+ end
+ end
end
it 'leaves links to other dashboards unchanged' do
diff --git a/spec/lib/banzai/filter/inline_metrics_redactor_filter_spec.rb b/spec/lib/banzai/filter/inline_metrics_redactor_filter_spec.rb
index 5f66844f498..3c736b46131 100644
--- a/spec/lib/banzai/filter/inline_metrics_redactor_filter_spec.rb
+++ b/spec/lib/banzai/filter/inline_metrics_redactor_filter_spec.rb
@@ -22,6 +22,13 @@ RSpec.describe Banzai::Filter::InlineMetricsRedactorFilter do
it_behaves_like 'redacts the embed placeholder'
it_behaves_like 'retains the embed placeholder when applicable'
+ context 'with /-/metrics?environment=:environment_id URL' do
+ let(:url) { urls.project_metrics_dashboard_url(project, embedded: true, environment: 1) }
+
+ it_behaves_like 'redacts the embed placeholder'
+ it_behaves_like 'retains the embed placeholder when applicable'
+ end
+
context 'for a grafana dashboard' do
let(:url) { urls.project_grafana_api_metrics_dashboard_url(project, embedded: true) }
@@ -33,7 +40,7 @@ RSpec.describe Banzai::Filter::InlineMetricsRedactorFilter do
let_it_be(:cluster) { create(:cluster, :provided_by_gcp, :project, projects: [project]) }
let(:params) { [project.namespace.path, project.path, cluster.id] }
let(:query_params) { { group: 'Cluster Health', title: 'CPU Usage', y_label: 'CPU (cores)' } }
- let(:url) { urls.metrics_dashboard_namespace_project_cluster_url(*params, **query_params) }
+ let(:url) { urls.metrics_dashboard_namespace_project_cluster_url(*params, **query_params, format: :json) }
context 'with user who can read cluster' do
it_behaves_like 'redacts the embed placeholder'
diff --git a/spec/lib/gitlab/alert_management/payload/prometheus_spec.rb b/spec/lib/gitlab/alert_management/payload/prometheus_spec.rb
index 2ddcad4134c..457db58a28b 100644
--- a/spec/lib/gitlab/alert_management/payload/prometheus_spec.rb
+++ b/spec/lib/gitlab/alert_management/payload/prometheus_spec.rb
@@ -45,7 +45,7 @@ RSpec.describe Gitlab::AlertManagement::Payload::Prometheus do
let(:current_time) { Time.current.utc }
around do |example|
- Timecop.freeze { example.run }
+ freeze_time { example.run }
end
subject { parsed_payload.starts_at }
diff --git a/spec/lib/gitlab/app_text_logger_spec.rb b/spec/lib/gitlab/app_text_logger_spec.rb
index 04c2e946640..e8bee0f9903 100644
--- a/spec/lib/gitlab/app_text_logger_spec.rb
+++ b/spec/lib/gitlab/app_text_logger_spec.rb
@@ -17,7 +17,7 @@ RSpec.describe Gitlab::AppTextLogger do
end
it 'logs time in UTC with ISO8601.3 standard' do
- Timecop.freeze do
+ freeze_time do
expect(subject.format_message('INFO', Time.now, nil, string_message))
.to include(Time.now.utc.iso8601(3))
end
diff --git a/spec/lib/gitlab/ci/jwt_spec.rb b/spec/lib/gitlab/ci/jwt_spec.rb
index a15f3310dab..9b133efad9c 100644
--- a/spec/lib/gitlab/ci/jwt_spec.rb
+++ b/spec/lib/gitlab/ci/jwt_spec.rb
@@ -20,7 +20,7 @@ RSpec.describe Gitlab::Ci::Jwt do
subject(:payload) { described_class.new(build, ttl: 30).payload }
it 'has correct values for the standard JWT attributes' do
- Timecop.freeze do
+ freeze_time do
now = Time.now.to_i
aggregate_failures do
diff --git a/spec/lib/gitlab/conan_token_spec.rb b/spec/lib/gitlab/conan_token_spec.rb
index b17f2eaa8d8..be1d3e757f5 100644
--- a/spec/lib/gitlab/conan_token_spec.rb
+++ b/spec/lib/gitlab/conan_token_spec.rb
@@ -85,7 +85,7 @@ RSpec.describe Gitlab::ConanToken do
it 'returns the encoded JWT' do
allow(SecureRandom).to receive(:uuid).and_return('u-u-i-d')
- Timecop.freeze do
+ freeze_time do
jwt = build_jwt(access_token_id: 123, user_id: 456)
token = described_class.new(access_token_id: 123, user_id: 456)
diff --git a/spec/lib/gitlab/cycle_analytics/code_stage_spec.rb b/spec/lib/gitlab/cycle_analytics/code_stage_spec.rb
index afab19de2ab..17104715580 100644
--- a/spec/lib/gitlab/cycle_analytics/code_stage_spec.rb
+++ b/spec/lib/gitlab/cycle_analytics/code_stage_spec.rb
@@ -34,7 +34,7 @@ RSpec.describe Gitlab::CycleAnalytics::CodeStage do
describe '#project_median' do
around do |example|
- Timecop.freeze { example.run }
+ freeze_time { example.run }
end
it 'counts median from issues with metrics' do
@@ -76,7 +76,7 @@ RSpec.describe Gitlab::CycleAnalytics::CodeStage do
describe '#group_median' do
around do |example|
- Timecop.freeze { example.run }
+ freeze_time { example.run }
end
it 'counts median from issues with metrics' do
diff --git a/spec/lib/gitlab/cycle_analytics/issue_stage_spec.rb b/spec/lib/gitlab/cycle_analytics/issue_stage_spec.rb
index 9ec71e6ed72..c7ab2b9b84b 100644
--- a/spec/lib/gitlab/cycle_analytics/issue_stage_spec.rb
+++ b/spec/lib/gitlab/cycle_analytics/issue_stage_spec.rb
@@ -29,7 +29,7 @@ RSpec.describe Gitlab::CycleAnalytics::IssueStage do
describe '#median' do
around do |example|
- Timecop.freeze { example.run }
+ freeze_time { example.run }
end
it 'counts median from issues with metrics' do
@@ -65,7 +65,7 @@ RSpec.describe Gitlab::CycleAnalytics::IssueStage do
describe '#group_median' do
around do |example|
- Timecop.freeze { example.run }
+ freeze_time { example.run }
end
it 'counts median from issues with metrics' do
@@ -87,7 +87,7 @@ RSpec.describe Gitlab::CycleAnalytics::IssueStage do
describe '#group_median' do
around do |example|
- Timecop.freeze { example.run }
+ freeze_time { example.run }
end
it 'counts median from issues with metrics' do
diff --git a/spec/lib/gitlab/cycle_analytics/plan_stage_spec.rb b/spec/lib/gitlab/cycle_analytics/plan_stage_spec.rb
index 66d00edacb7..2547c05c025 100644
--- a/spec/lib/gitlab/cycle_analytics/plan_stage_spec.rb
+++ b/spec/lib/gitlab/cycle_analytics/plan_stage_spec.rb
@@ -29,7 +29,7 @@ RSpec.describe Gitlab::CycleAnalytics::PlanStage do
describe '#project_median' do
around do |example|
- Timecop.freeze { example.run }
+ freeze_time { example.run }
end
it 'counts median from issues with metrics' do
@@ -67,7 +67,7 @@ RSpec.describe Gitlab::CycleAnalytics::PlanStage do
describe '#group_median' do
around do |example|
- Timecop.freeze { example.run }
+ freeze_time { example.run }
end
it 'counts median from issues with metrics' do
diff --git a/spec/lib/gitlab/cycle_analytics/review_stage_spec.rb b/spec/lib/gitlab/cycle_analytics/review_stage_spec.rb
index cdd1cca6837..5593013740e 100644
--- a/spec/lib/gitlab/cycle_analytics/review_stage_spec.rb
+++ b/spec/lib/gitlab/cycle_analytics/review_stage_spec.rb
@@ -27,7 +27,7 @@ RSpec.describe Gitlab::CycleAnalytics::ReviewStage do
describe '#project_median' do
around do |example|
- Timecop.freeze { example.run }
+ freeze_time { example.run }
end
it 'counts median from issues with metrics' do
@@ -70,7 +70,7 @@ RSpec.describe Gitlab::CycleAnalytics::ReviewStage do
describe '#group_median' do
around do |example|
- Timecop.freeze { example.run }
+ freeze_time { example.run }
end
it 'counts median from issues with metrics' do
diff --git a/spec/lib/gitlab/cycle_analytics/stage_summary_spec.rb b/spec/lib/gitlab/cycle_analytics/stage_summary_spec.rb
index 9ece24074e7..719d4a69985 100644
--- a/spec/lib/gitlab/cycle_analytics/stage_summary_spec.rb
+++ b/spec/lib/gitlab/cycle_analytics/stage_summary_spec.rb
@@ -231,7 +231,7 @@ RSpec.describe Gitlab::CycleAnalytics::StageSummary do
context 'when `from` and `to` are within a day' do
it 'returns the number of deployments made on that day' do
- Timecop.freeze(Time.now) do
+ freeze_time do
create(:deployment, :success, project: project)
options[:from] = options[:to] = Time.now
diff --git a/spec/lib/gitlab/cycle_analytics/staging_stage_spec.rb b/spec/lib/gitlab/cycle_analytics/staging_stage_spec.rb
index 69e42adb139..852f7041dc6 100644
--- a/spec/lib/gitlab/cycle_analytics/staging_stage_spec.rb
+++ b/spec/lib/gitlab/cycle_analytics/staging_stage_spec.rb
@@ -32,7 +32,7 @@ RSpec.describe Gitlab::CycleAnalytics::StagingStage do
describe '#project_median' do
around do |example|
- Timecop.freeze { example.run }
+ freeze_time { example.run }
end
it 'counts median from issues with metrics' do
@@ -79,7 +79,7 @@ RSpec.describe Gitlab::CycleAnalytics::StagingStage do
describe '#group_median' do
around do |example|
- Timecop.freeze { example.run }
+ freeze_time { example.run }
end
it 'counts median from issues with metrics' do
diff --git a/spec/lib/gitlab/cycle_analytics/test_stage_spec.rb b/spec/lib/gitlab/cycle_analytics/test_stage_spec.rb
index 9a207d32167..49ee6624260 100644
--- a/spec/lib/gitlab/cycle_analytics/test_stage_spec.rb
+++ b/spec/lib/gitlab/cycle_analytics/test_stage_spec.rb
@@ -37,7 +37,7 @@ RSpec.describe Gitlab::CycleAnalytics::TestStage do
end
around do |example|
- Timecop.freeze { example.run }
+ freeze_time { example.run }
end
it 'counts median from issues with metrics' do
diff --git a/spec/lib/gitlab/database/migrations/background_migration_helpers_spec.rb b/spec/lib/gitlab/database/migrations/background_migration_helpers_spec.rb
index 042ac498373..48132d68031 100644
--- a/spec/lib/gitlab/database/migrations/background_migration_helpers_spec.rb
+++ b/spec/lib/gitlab/database/migrations/background_migration_helpers_spec.rb
@@ -86,7 +86,7 @@ RSpec.describe Gitlab::Database::Migrations::BackgroundMigrationHelpers do
let!(:id3) { create(:user).id }
around do |example|
- Timecop.freeze { example.run }
+ freeze_time { example.run }
end
before do
diff --git a/spec/lib/gitlab/external_authorization/access_spec.rb b/spec/lib/gitlab/external_authorization/access_spec.rb
index 4bb81230ac0..a6773cc19e1 100644
--- a/spec/lib/gitlab/external_authorization/access_spec.rb
+++ b/spec/lib/gitlab/external_authorization/access_spec.rb
@@ -7,7 +7,7 @@ RSpec.describe Gitlab::ExternalAuthorization::Access, :clean_gitlab_redis_cache
describe '#loaded?' do
it 'is `true` when it was loaded recently' do
- Timecop.freeze do
+ freeze_time do
allow(access).to receive(:loaded_at).and_return(5.minutes.ago)
expect(access).to be_loaded
@@ -19,7 +19,7 @@ RSpec.describe Gitlab::ExternalAuthorization::Access, :clean_gitlab_redis_cache
end
it 'is `false` when there the result was loaded a long time ago' do
- Timecop.freeze do
+ freeze_time do
allow(access).to receive(:loaded_at).and_return(2.weeks.ago)
expect(access).not_to be_loaded
@@ -70,7 +70,7 @@ RSpec.describe Gitlab::ExternalAuthorization::Access, :clean_gitlab_redis_cache
end
it 'stores the result in redis' do
- Timecop.freeze do
+ freeze_time do
fake_cache = double
expect(fake_cache).to receive(:store).with(true, nil, Time.now)
expect(access).to receive(:cache).and_return(fake_cache)
@@ -118,7 +118,7 @@ RSpec.describe Gitlab::ExternalAuthorization::Access, :clean_gitlab_redis_cache
end
it 'does not load from the webservice' do
- Timecop.freeze do
+ freeze_time do
expect(fake_cache).to receive(:load).and_return([true, nil, Time.now])
expect(access).to receive(:load_from_cache).and_call_original
@@ -129,7 +129,7 @@ RSpec.describe Gitlab::ExternalAuthorization::Access, :clean_gitlab_redis_cache
end
it 'loads from the webservice when the cached result was too old' do
- Timecop.freeze do
+ freeze_time do
expect(fake_cache).to receive(:load).and_return([true, nil, 2.days.ago])
expect(access).to receive(:load_from_cache).and_call_original
diff --git a/spec/lib/gitlab/external_authorization/cache_spec.rb b/spec/lib/gitlab/external_authorization/cache_spec.rb
index 9037c04cf2b..a8e7932b82c 100644
--- a/spec/lib/gitlab/external_authorization/cache_spec.rb
+++ b/spec/lib/gitlab/external_authorization/cache_spec.rb
@@ -22,7 +22,7 @@ RSpec.describe Gitlab::ExternalAuthorization::Cache, :clean_gitlab_redis_cache d
describe '#load' do
it 'reads stored info from redis' do
- Timecop.freeze do
+ freeze_time do
set_in_redis(:access, false)
set_in_redis(:reason, 'Access denied for now')
set_in_redis(:refreshed_at, Time.now)
@@ -38,7 +38,7 @@ RSpec.describe Gitlab::ExternalAuthorization::Cache, :clean_gitlab_redis_cache d
describe '#store' do
it 'sets the values in redis' do
- Timecop.freeze do
+ freeze_time do
cache.store(true, 'the reason', Time.now)
expect(read_from_redis(:access)).to eq('true')
diff --git a/spec/lib/gitlab/github_import/importer/label_links_importer_spec.rb b/spec/lib/gitlab/github_import/importer/label_links_importer_spec.rb
index 4d3245fc988..6d143f78c66 100644
--- a/spec/lib/gitlab/github_import/importer/label_links_importer_spec.rb
+++ b/spec/lib/gitlab/github_import/importer/label_links_importer_spec.rb
@@ -38,7 +38,7 @@ RSpec.describe Gitlab::GithubImport::Importer::LabelLinksImporter do
.to receive(:find_target_id)
.and_return(1)
- Timecop.freeze do
+ freeze_time do
expect(Gitlab::Database)
.to receive(:bulk_insert)
.with(
diff --git a/spec/lib/gitlab/github_import/importer/labels_importer_spec.rb b/spec/lib/gitlab/github_import/importer/labels_importer_spec.rb
index 0010b959a49..ca9d3e1e21c 100644
--- a/spec/lib/gitlab/github_import/importer/labels_importer_spec.rb
+++ b/spec/lib/gitlab/github_import/importer/labels_importer_spec.rb
@@ -85,13 +85,13 @@ RSpec.describe Gitlab::GithubImport::Importer::LabelsImporter, :clean_gitlab_red
end
it 'includes the created timestamp' do
- Timecop.freeze do
+ freeze_time do
expect(label_hash[:created_at]).to eq(Time.zone.now)
end
end
it 'includes the updated timestamp' do
- Timecop.freeze do
+ freeze_time do
expect(label_hash[:updated_at]).to eq(Time.zone.now)
end
end
diff --git a/spec/lib/gitlab/github_import/importer/pull_requests_importer_spec.rb b/spec/lib/gitlab/github_import/importer/pull_requests_importer_spec.rb
index 05ac0248ec9..0835c6155b9 100644
--- a/spec/lib/gitlab/github_import/importer/pull_requests_importer_spec.rb
+++ b/spec/lib/gitlab/github_import/importer/pull_requests_importer_spec.rb
@@ -164,7 +164,7 @@ RSpec.describe Gitlab::GithubImport::Importer::PullRequestsImporter do
.to receive(:increment)
.and_call_original
- Timecop.freeze do
+ freeze_time do
importer.update_repository
expect(project.last_repository_updated_at).to be_like_time(Time.zone.now)
diff --git a/spec/lib/gitlab/github_import/importer/repository_importer_spec.rb b/spec/lib/gitlab/github_import/importer/repository_importer_spec.rb
index 65dba2711b9..180c6d9e420 100644
--- a/spec/lib/gitlab/github_import/importer/repository_importer_spec.rb
+++ b/spec/lib/gitlab/github_import/importer/repository_importer_spec.rb
@@ -261,7 +261,7 @@ RSpec.describe Gitlab::GithubImport::Importer::RepositoryImporter do
describe '#update_clone_time' do
it 'sets the timestamp for when the cloning process finished' do
- Timecop.freeze do
+ freeze_time do
expect(project)
.to receive(:update_column)
.with(:last_repository_updated_at, Time.zone.now)
diff --git a/spec/lib/gitlab/incident_management/pager_duty/incident_issue_description_spec.rb b/spec/lib/gitlab/incident_management/pager_duty/incident_issue_description_spec.rb
index 6dc96217f09..535cce6aa04 100644
--- a/spec/lib/gitlab/incident_management/pager_duty/incident_issue_description_spec.rb
+++ b/spec/lib/gitlab/incident_management/pager_duty/incident_issue_description_spec.rb
@@ -1,7 +1,6 @@
# frozen_string_literal: true
require 'fast_spec_helper'
-require 'timecop'
RSpec.describe Gitlab::IncidentManagement::PagerDuty::IncidentIssueDescription do
describe '#to_s' do
@@ -50,7 +49,7 @@ RSpec.describe Gitlab::IncidentManagement::PagerDuty::IncidentIssueDescription d
let(:created_at) { nil }
it 'description contains current time in UTC' do
- Timecop.freeze do
+ freeze_time do
now = Time.current.utc.strftime('%d %B %Y, %-l:%M%p (%Z)')
expect(to_s).to include(
diff --git a/spec/lib/gitlab/log_timestamp_formatter_spec.rb b/spec/lib/gitlab/log_timestamp_formatter_spec.rb
index e06baa2324f..b51d0fec15e 100644
--- a/spec/lib/gitlab/log_timestamp_formatter_spec.rb
+++ b/spec/lib/gitlab/log_timestamp_formatter_spec.rb
@@ -8,7 +8,7 @@ RSpec.describe Gitlab::LogTimestampFormatter do
let(:formatted_timestamp) { Time.now.utc.iso8601(3) }
it 'logs the timestamp in UTC and ISO8601.3 format' do
- Timecop.freeze(Time.now) do
+ freeze_time do
expect(subject.call('', Time.now, '', '')).to include formatted_timestamp
end
end
diff --git a/spec/lib/gitlab/metrics/dashboard/url_spec.rb b/spec/lib/gitlab/metrics/dashboard/url_spec.rb
index 205e1000376..830d43169a9 100644
--- a/spec/lib/gitlab/metrics/dashboard/url_spec.rb
+++ b/spec/lib/gitlab/metrics/dashboard/url_spec.rb
@@ -6,11 +6,12 @@ RSpec.describe Gitlab::Metrics::Dashboard::Url do
include Gitlab::Routing.url_helpers
describe '#metrics_regex' do
+ let(:environment_id) { 1 }
let(:url_params) do
[
'foo',
'bar',
- 1,
+ environment_id,
{
start: '2019-08-02T05:43:09.000Z',
dashboard: 'config/prometheus/common_metrics.yml',
@@ -33,12 +34,42 @@ RSpec.describe Gitlab::Metrics::Dashboard::Url do
subject { described_class.metrics_regex }
- context 'for metrics route' do
+ context 'for /-/environments/:environment_id/metrics route' do
let(:url) { metrics_namespace_project_environment_url(*url_params) }
it_behaves_like 'regex which matches url when expected'
end
+ context 'for /-/metrics?environment=:environment_id route' do
+ let(:url) { namespace_project_metrics_dashboard_url(*url_params) }
+ let(:url_params) do
+ [
+ 'namespace1',
+ 'project1',
+ {
+ environment: environment_id,
+ start: '2019-08-02T05:43:09.000Z',
+ dashboard: 'config/prometheus/common_metrics.yml',
+ group: 'awesome group',
+ anchor: 'title'
+ }
+ ]
+ end
+
+ let(:expected_params) do
+ {
+ 'url' => url,
+ 'namespace' => 'namespace1',
+ 'project' => 'project1',
+ 'environment' => "#{environment_id}",
+ 'query' => "?dashboard=config%2Fprometheus%2Fcommon_metrics.yml&environment=#{environment_id}&group=awesome+group&start=2019-08-02T05%3A43%3A09.000Z",
+ 'anchor' => '#title'
+ }
+ end
+
+ it_behaves_like 'regex which matches url when expected'
+ end
+
context 'for metrics_dashboard route' do
let(:url) { metrics_dashboard_namespace_project_environment_url(*url_params) }
@@ -47,16 +78,19 @@ RSpec.describe Gitlab::Metrics::Dashboard::Url do
end
describe '#clusters_regex' do
- let(:url) do
- Gitlab::Routing.url_helpers.namespace_project_cluster_url(
+ let(:url) { Gitlab::Routing.url_helpers.namespace_project_cluster_url(*url_params) }
+ let(:url_params) do
+ [
'foo',
'bar',
'1',
- group: 'Cluster Health',
- title: 'Memory Usage',
- y_label: 'Memory 20(GiB)',
- anchor: 'title'
- )
+ {
+ group: 'Cluster Health',
+ title: 'Memory Usage',
+ y_label: 'Memory 20(GiB)',
+ anchor: 'title'
+ }
+ ]
end
let(:expected_params) do
@@ -73,6 +107,27 @@ RSpec.describe Gitlab::Metrics::Dashboard::Url do
subject { described_class.clusters_regex }
it_behaves_like 'regex which matches url when expected'
+
+ context 'for metrics_dashboard route' do
+ let(:url) do
+ metrics_dashboard_namespace_project_cluster_url(
+ *url_params, cluster_type: :project, embedded: true, format: :json
+ )
+ end
+
+ let(:expected_params) do
+ {
+ 'url' => url,
+ 'namespace' => 'foo',
+ 'project' => 'bar',
+ 'cluster_id' => '1',
+ 'query' => '?cluster_type=project&embedded=true',
+ 'anchor' => nil
+ }
+ end
+
+ it_behaves_like 'regex which matches url when expected'
+ end
end
describe '#grafana_regex' do
@@ -103,15 +158,18 @@ RSpec.describe Gitlab::Metrics::Dashboard::Url do
end
describe '#alert_regex' do
- let(:url) do
- Gitlab::Routing.url_helpers.metrics_dashboard_namespace_project_prometheus_alert_url(
+ let(:url) { Gitlab::Routing.url_helpers.metrics_dashboard_namespace_project_prometheus_alert_url(*url_params) }
+ let(:url_params) do
+ [
'foo',
'bar',
'1',
- start: '2020-02-10T12:59:49.938Z',
- end: '2020-02-10T20:59:49.938Z',
- anchor: "anchor"
- )
+ {
+ start: '2020-02-10T12:59:49.938Z',
+ end: '2020-02-10T20:59:49.938Z',
+ anchor: "anchor"
+ }
+ ]
end
let(:expected_params) do
@@ -128,6 +186,21 @@ RSpec.describe Gitlab::Metrics::Dashboard::Url do
subject { described_class.alert_regex }
it_behaves_like 'regex which matches url when expected'
+
+ it_behaves_like 'regex which matches url when expected' do
+ let(:url) { Gitlab::Routing.url_helpers.metrics_dashboard_namespace_project_prometheus_alert_url(*url_params, format: :json) }
+
+ let(:expected_params) do
+ {
+ 'url' => url,
+ 'namespace' => 'foo',
+ 'project' => 'bar',
+ 'alert' => '1',
+ 'query' => nil,
+ 'anchor' => nil
+ }
+ end
+ end
end
describe '#build_dashboard_url' do
diff --git a/spec/lib/gitlab/metrics/method_call_spec.rb b/spec/lib/gitlab/metrics/method_call_spec.rb
index 825c91b6cb4..fb5436a90e3 100644
--- a/spec/lib/gitlab/metrics/method_call_spec.rb
+++ b/spec/lib/gitlab/metrics/method_call_spec.rb
@@ -30,7 +30,7 @@ RSpec.describe Gitlab::Metrics::MethodCall do
end
around do |example|
- Timecop.freeze do
+ freeze_time do
example.run
end
end
diff --git a/spec/lib/gitlab/metrics/samplers/ruby_sampler_spec.rb b/spec/lib/gitlab/metrics/samplers/ruby_sampler_spec.rb
index 59a70ac74a5..eb6c83096b9 100644
--- a/spec/lib/gitlab/metrics/samplers/ruby_sampler_spec.rb
+++ b/spec/lib/gitlab/metrics/samplers/ruby_sampler_spec.rb
@@ -12,7 +12,7 @@ RSpec.describe Gitlab::Metrics::Samplers::RubySampler do
describe '#initialize' do
it 'sets process_start_time_seconds' do
- Timecop.freeze do
+ freeze_time do
expect(sampler.metrics[:process_start_time_seconds].get).to eq(Time.now.to_i)
end
end
diff --git a/spec/lib/gitlab/phabricator_import/cache/map_spec.rb b/spec/lib/gitlab/phabricator_import/cache/map_spec.rb
index 0f760852a68..08ac85c2625 100644
--- a/spec/lib/gitlab/phabricator_import/cache/map_spec.rb
+++ b/spec/lib/gitlab/phabricator_import/cache/map_spec.rb
@@ -50,7 +50,7 @@ RSpec.describe Gitlab::PhabricatorImport::Cache::Map, :clean_gitlab_redis_cache
describe '#set_gitlab_model' do
around do |example|
- Timecop.freeze { example.run }
+ freeze_time { example.run }
end
it 'sets the class and id in redis with a ttl' 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 f5911963108..d0dee2ad366 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
@@ -4,7 +4,7 @@ require 'spec_helper'
RSpec.describe Gitlab::Prometheus::Queries::AdditionalMetricsEnvironmentQuery do
around do |example|
- Timecop.freeze { example.run }
+ freeze_time { example.run }
end
include_examples 'additional metrics query' do
diff --git a/spec/lib/gitlab/prometheus/queries/validate_query_spec.rb b/spec/lib/gitlab/prometheus/queries/validate_query_spec.rb
index 045c063ab34..e3706a4b106 100644
--- a/spec/lib/gitlab/prometheus/queries/validate_query_spec.rb
+++ b/spec/lib/gitlab/prometheus/queries/validate_query_spec.rb
@@ -28,7 +28,7 @@ RSpec.describe Gitlab::Prometheus::Queries::ValidateQuery do
let(:error_message) { "invalid parameter 'query': 1:9: parse error: unexpected identifier \"query\"" }
it 'returns invalid' do
- Timecop.freeze do
+ freeze_time do
stub_prometheus_query_error(
prometheus_query_with_time_url(query, Time.now),
error_message
@@ -53,7 +53,7 @@ RSpec.describe Gitlab::Prometheus::Queries::ValidateQuery do
end
it 'catches exception and returns invalid' do
- Timecop.freeze do
+ freeze_time do
expect(subject.query(query)).to eq(valid: false, error: message)
end
end
diff --git a/spec/lib/gitlab/prometheus_client_spec.rb b/spec/lib/gitlab/prometheus_client_spec.rb
index 0774c2f3144..7c0c2962aed 100644
--- a/spec/lib/gitlab/prometheus_client_spec.rb
+++ b/spec/lib/gitlab/prometheus_client_spec.rb
@@ -136,7 +136,7 @@ RSpec.describe Gitlab::PrometheusClient do
let(:query_url) { prometheus_query_with_time_url(prometheus_query, Time.now.utc) }
around do |example|
- Timecop.freeze { example.run }
+ freeze_time { example.run }
end
context 'when request returns vector results' do
@@ -195,7 +195,7 @@ RSpec.describe Gitlab::PrometheusClient do
let(:query_url) { prometheus_query_with_time_url(query, Time.now.utc) }
around do |example|
- Timecop.freeze { example.run }
+ freeze_time { example.run }
end
context 'when request returns vector results' do
@@ -228,7 +228,7 @@ RSpec.describe Gitlab::PrometheusClient do
let(:query_url) { prometheus_series_url('series_name', 'other_service') }
around do |example|
- Timecop.freeze { example.run }
+ freeze_time { example.run }
end
it 'calls endpoint and returns list of series' do
@@ -259,7 +259,7 @@ RSpec.describe Gitlab::PrometheusClient do
let(:query_url) { prometheus_query_range_url(prometheus_query) }
around do |example|
- Timecop.freeze { example.run }
+ freeze_time { example.run }
end
context 'when non utc time is passed' do
@@ -358,7 +358,7 @@ RSpec.describe Gitlab::PrometheusClient do
let(:query_url) { prometheus_query_url(prometheus_query) }
around do |example|
- Timecop.freeze { example.run }
+ freeze_time { example.run }
end
context 'when response status code is 200' do
diff --git a/spec/lib/gitlab/sidekiq_middleware/duplicate_jobs/strategies/until_executing_spec.rb b/spec/lib/gitlab/sidekiq_middleware/duplicate_jobs/strategies/until_executing_spec.rb
index 77d760d1ae3..10b18052e9a 100644
--- a/spec/lib/gitlab/sidekiq_middleware/duplicate_jobs/strategies/until_executing_spec.rb
+++ b/spec/lib/gitlab/sidekiq_middleware/duplicate_jobs/strategies/until_executing_spec.rb
@@ -1,7 +1,6 @@
# frozen_string_literal: true
require 'fast_spec_helper'
-require 'timecop'
RSpec.describe Gitlab::SidekiqMiddleware::DuplicateJobs::Strategies::UntilExecuting do
let(:fake_duplicate_job) do
@@ -77,7 +76,7 @@ RSpec.describe Gitlab::SidekiqMiddleware::DuplicateJobs::Strategies::UntilExecut
context 'scheduled in the future' do
it 'adds the jid of the existing job to the job hash' do
- Timecop.freeze do
+ freeze_time do
allow(fake_duplicate_job).to receive(:scheduled?).twice.and_return(true)
allow(fake_duplicate_job).to receive(:scheduled_at).and_return(Time.now + time_diff)
allow(fake_duplicate_job).to receive(:options).and_return({ including_scheduled: true })
diff --git a/spec/lib/gitlab/updated_notes_paginator_spec.rb b/spec/lib/gitlab/updated_notes_paginator_spec.rb
index eedc11777d4..ce6a7719fb4 100644
--- a/spec/lib/gitlab/updated_notes_paginator_spec.rb
+++ b/spec/lib/gitlab/updated_notes_paginator_spec.rb
@@ -15,7 +15,7 @@ RSpec.describe Gitlab::UpdatedNotesPaginator do
let(:page_1_boundary) { page_1.last.updated_at + NotesFinder::FETCH_OVERLAP }
around do |example|
- Timecop.freeze do
+ freeze_time do
example.run
end
end
diff --git a/spec/migrations/20190924152703_migrate_issue_trackers_data_spec.rb b/spec/migrations/20190924152703_migrate_issue_trackers_data_spec.rb
index 6c957ee1428..196f5ead8d2 100644
--- a/spec/migrations/20190924152703_migrate_issue_trackers_data_spec.rb
+++ b/spec/migrations/20190924152703_migrate_issue_trackers_data_spec.rb
@@ -52,7 +52,7 @@ RSpec.describe MigrateIssueTrackersData do
it 'schedules background migrations at correct time' do
Sidekiq::Testing.fake! do
- Timecop.freeze do
+ freeze_time do
migrate!
expect(migration_name).to be_scheduled_delayed_migration(3.minutes, jira_service.id, bugzilla_service.id)
diff --git a/spec/migrations/20200122123016_backfill_project_settings_spec.rb b/spec/migrations/20200122123016_backfill_project_settings_spec.rb
index 0992ddde0c1..60c6206a83b 100644
--- a/spec/migrations/20200122123016_backfill_project_settings_spec.rb
+++ b/spec/migrations/20200122123016_backfill_project_settings_spec.rb
@@ -19,7 +19,7 @@ RSpec.describe BackfillProjectSettings, :sidekiq, schema: 20200114113341 do
it 'schedules BackfillProjectSettings background jobs' do
Sidekiq::Testing.fake! do
- Timecop.freeze do
+ freeze_time do
migrate!
expect(described_class::MIGRATION).to be_scheduled_delayed_migration(2.minutes, 1, 2)
diff --git a/spec/migrations/20200130145430_reschedule_migrate_issue_trackers_data_spec.rb b/spec/migrations/20200130145430_reschedule_migrate_issue_trackers_data_spec.rb
index d5208976928..e140be476ab 100644
--- a/spec/migrations/20200130145430_reschedule_migrate_issue_trackers_data_spec.rb
+++ b/spec/migrations/20200130145430_reschedule_migrate_issue_trackers_data_spec.rb
@@ -53,7 +53,7 @@ RSpec.describe RescheduleMigrateIssueTrackersData do
describe "#up" do
it 'schedules background migrations at correct time' do
Sidekiq::Testing.fake! do
- Timecop.freeze do
+ freeze_time do
migrate!
expect(migration_name).to be_scheduled_delayed_migration(3.minutes, jira_service.id, bugzilla_service.id)
diff --git a/spec/migrations/20200406102120_backfill_deployment_clusters_from_deployments_spec.rb b/spec/migrations/20200406102120_backfill_deployment_clusters_from_deployments_spec.rb
index 47bc7428286..c6b221b09a5 100644
--- a/spec/migrations/20200406102120_backfill_deployment_clusters_from_deployments_spec.rb
+++ b/spec/migrations/20200406102120_backfill_deployment_clusters_from_deployments_spec.rb
@@ -27,7 +27,7 @@ RSpec.describe BackfillDeploymentClustersFromDeployments, :migration, :sidekiq,
batch_2_end = create_deployment(**deployment_data)
Sidekiq::Testing.fake! do
- Timecop.freeze do
+ freeze_time do
migrate!
# batch 1
diff --git a/spec/migrations/20200703125016_backfill_namespace_settings_spec.rb b/spec/migrations/20200703125016_backfill_namespace_settings_spec.rb
index 7b84ef9e236..9ff88009d8a 100644
--- a/spec/migrations/20200703125016_backfill_namespace_settings_spec.rb
+++ b/spec/migrations/20200703125016_backfill_namespace_settings_spec.rb
@@ -17,7 +17,7 @@ RSpec.describe BackfillNamespaceSettings, :sidekiq, schema: 20200703124823 do
it 'schedules BackfillNamespaceSettings background jobs' do
Sidekiq::Testing.fake! do
- Timecop.freeze do
+ freeze_time do
migrate!
expect(described_class::MIGRATION).to be_scheduled_delayed_migration(2.minutes, 1, 2)
diff --git a/spec/migrations/backfill_imported_snippet_repositories_spec.rb b/spec/migrations/backfill_imported_snippet_repositories_spec.rb
index 208bda274e2..998a691bf77 100644
--- a/spec/migrations/backfill_imported_snippet_repositories_spec.rb
+++ b/spec/migrations/backfill_imported_snippet_repositories_spec.rb
@@ -30,7 +30,7 @@ RSpec.describe BackfillImportedSnippetRepositories do
create_snippet(10)
Sidekiq::Testing.fake! do
- Timecop.freeze do
+ freeze_time do
migrate!
expect(described_class::MIGRATION)
diff --git a/spec/migrations/backfill_snippet_repositories_spec.rb b/spec/migrations/backfill_snippet_repositories_spec.rb
index 084faa16a37..6d417669ad6 100644
--- a/spec/migrations/backfill_snippet_repositories_spec.rb
+++ b/spec/migrations/backfill_snippet_repositories_spec.rb
@@ -28,7 +28,7 @@ RSpec.describe BackfillSnippetRepositories do
stub_const("#{described_class.name}::BATCH_SIZE", 2)
Sidekiq::Testing.fake! do
- Timecop.freeze do
+ freeze_time do
migrate!
expect(described_class::MIGRATION)
diff --git a/spec/migrations/enqueue_reset_merge_status_second_run_spec.rb b/spec/migrations/enqueue_reset_merge_status_second_run_spec.rb
index f5728534675..d4189326366 100644
--- a/spec/migrations/enqueue_reset_merge_status_second_run_spec.rb
+++ b/spec/migrations/enqueue_reset_merge_status_second_run_spec.rb
@@ -33,7 +33,7 @@ RSpec.describe EnqueueResetMergeStatusSecondRun do
stub_const("#{described_class.name}::BATCH_SIZE", 2)
Sidekiq::Testing.fake! do
- Timecop.freeze do
+ freeze_time do
migrate!
expect(described_class::MIGRATION)
diff --git a/spec/migrations/enqueue_reset_merge_status_spec.rb b/spec/migrations/enqueue_reset_merge_status_spec.rb
index 683d2caf9ca..c581293ddcd 100644
--- a/spec/migrations/enqueue_reset_merge_status_spec.rb
+++ b/spec/migrations/enqueue_reset_merge_status_spec.rb
@@ -33,7 +33,7 @@ RSpec.describe EnqueueResetMergeStatus do
stub_const("#{described_class.name}::BATCH_SIZE", 2)
Sidekiq::Testing.fake! do
- Timecop.freeze do
+ freeze_time do
migrate!
expect(described_class::MIGRATION)
diff --git a/spec/migrations/fix_projects_without_project_feature_spec.rb b/spec/migrations/fix_projects_without_project_feature_spec.rb
index 2a4ba3f3ca5..1ec67c07ba3 100644
--- a/spec/migrations/fix_projects_without_project_feature_spec.rb
+++ b/spec/migrations/fix_projects_without_project_feature_spec.rb
@@ -20,7 +20,7 @@ RSpec.describe FixProjectsWithoutProjectFeature do
around do |example|
Sidekiq::Testing.fake! do
- Timecop.freeze do
+ freeze_time do
example.call
end
end
diff --git a/spec/migrations/fix_projects_without_prometheus_services_spec.rb b/spec/migrations/fix_projects_without_prometheus_services_spec.rb
index 73ede2ad90c..a4504ab6773 100644
--- a/spec/migrations/fix_projects_without_prometheus_services_spec.rb
+++ b/spec/migrations/fix_projects_without_prometheus_services_spec.rb
@@ -20,7 +20,7 @@ RSpec.describe FixProjectsWithoutPrometheusService, :migration do
around do |example|
Sidekiq::Testing.fake! do
- Timecop.freeze do
+ freeze_time do
example.call
end
end
diff --git a/spec/migrations/fix_wrong_pages_access_level_spec.rb b/spec/migrations/fix_wrong_pages_access_level_spec.rb
index 9ee5fa783a4..80787e0f115 100644
--- a/spec/migrations/fix_wrong_pages_access_level_spec.rb
+++ b/spec/migrations/fix_wrong_pages_access_level_spec.rb
@@ -29,7 +29,7 @@ RSpec.describe FixWrongPagesAccessLevel, :sidekiq_might_not_need_inline, schema:
it 'correctly schedules background migrations' do
Sidekiq::Testing.fake! do
- Timecop.freeze do
+ freeze_time do
first_id = create_project_feature("project1", project_class::PRIVATE, feature_class::PRIVATE).id
last_id = create_project_feature("project2", project_class::PRIVATE, feature_class::PUBLIC).id
diff --git a/spec/migrations/migrate_discussion_id_on_promoted_epics_spec.rb b/spec/migrations/migrate_discussion_id_on_promoted_epics_spec.rb
index e3119be495d..92a49046193 100644
--- a/spec/migrations/migrate_discussion_id_on_promoted_epics_spec.rb
+++ b/spec/migrations/migrate_discussion_id_on_promoted_epics_spec.rb
@@ -53,7 +53,7 @@ RSpec.describe MigrateDiscussionIdOnPromotedEpics do
stub_const("#{described_class.name}::BATCH_SIZE", 2)
Sidekiq::Testing.fake! do
- Timecop.freeze do
+ freeze_time do
migrate!
expect(migration_name).to be_scheduled_delayed_migration(2.minutes, %w(id1 id2))
@@ -69,7 +69,7 @@ RSpec.describe MigrateDiscussionIdOnPromotedEpics do
create_note(create_epic, 'id3')
Sidekiq::Testing.fake! do
- Timecop.freeze do
+ freeze_time do
migrate!
expect(migration_name).to be_scheduled_delayed_migration(2.minutes, %w(id1))
diff --git a/spec/migrations/schedule_calculate_wiki_sizes_spec.rb b/spec/migrations/schedule_calculate_wiki_sizes_spec.rb
index c60ffc3619e..0af491d863b 100644
--- a/spec/migrations/schedule_calculate_wiki_sizes_spec.rb
+++ b/spec/migrations/schedule_calculate_wiki_sizes_spec.rb
@@ -21,7 +21,7 @@ RSpec.describe ScheduleCalculateWikiSizes do
let!(:project_statistic3) { project_statistics.create!(project_id: project3.id, namespace_id: namespace.id, wiki_size: nil) }
it 'schedules a background migration' do
- Timecop.freeze do
+ freeze_time do
migrate!
expect(migration_name).to be_scheduled_delayed_migration(5.minutes, project_statistic2.id, project_statistic3.id)
@@ -49,7 +49,7 @@ RSpec.describe ScheduleCalculateWikiSizes do
it 'does not schedule a background migration' do
Sidekiq::Testing.fake! do
- Timecop.freeze do
+ freeze_time do
migrate!
expect(BackgroundMigrationWorker.jobs.size).to eq 0
diff --git a/spec/migrations/schedule_fill_valid_time_for_pages_domain_certificates_spec.rb b/spec/migrations/schedule_fill_valid_time_for_pages_domain_certificates_spec.rb
index a51bc374d5f..539b9ee96a8 100644
--- a/spec/migrations/schedule_fill_valid_time_for_pages_domain_certificates_spec.rb
+++ b/spec/migrations/schedule_fill_valid_time_for_pages_domain_certificates_spec.rb
@@ -22,7 +22,7 @@ RSpec.describe ScheduleFillValidTimeForPagesDomainCertificates do
it 'correctly schedules background migrations' do
Sidekiq::Testing.fake! do
- Timecop.freeze do
+ freeze_time do
migrate!
first_id = domains_table.find_by_domain("domain3.example.com").id
diff --git a/spec/migrations/schedule_migrate_security_scans_spec.rb b/spec/migrations/schedule_migrate_security_scans_spec.rb
index 4fd17b20666..61b14f239ae 100644
--- a/spec/migrations/schedule_migrate_security_scans_spec.rb
+++ b/spec/migrations/schedule_migrate_security_scans_spec.rb
@@ -40,7 +40,7 @@ RSpec.describe ScheduleMigrateSecurityScans, :sidekiq do
it 'schedules migration of security scans' do
Sidekiq::Testing.fake! do
- Timecop.freeze do
+ freeze_time do
migration.up
expect(described_class::MIGRATION).to be_scheduled_delayed_migration(5.minutes, job_artifact_1.id, job_artifact_1.id)
@@ -57,7 +57,7 @@ RSpec.describe ScheduleMigrateSecurityScans, :sidekiq do
it 'schedules migration of security scans' do
Sidekiq::Testing.fake! do
- Timecop.freeze do
+ freeze_time do
migration.up
expect(BackgroundMigrationWorker.jobs).to be_empty
diff --git a/spec/migrations/schedule_pages_metadata_migration_spec.rb b/spec/migrations/schedule_pages_metadata_migration_spec.rb
index c37e19eb71c..94311237cf4 100644
--- a/spec/migrations/schedule_pages_metadata_migration_spec.rb
+++ b/spec/migrations/schedule_pages_metadata_migration_spec.rb
@@ -17,7 +17,7 @@ RSpec.describe SchedulePagesMetadataMigration do
it 'schedules pages metadata migration' do
Sidekiq::Testing.fake! do
- Timecop.freeze do
+ freeze_time do
migrate!
expect(described_class::MIGRATION).to be_scheduled_delayed_migration(2.minutes, 111, 111)
diff --git a/spec/migrations/schedule_populate_merge_request_assignees_table_spec.rb b/spec/migrations/schedule_populate_merge_request_assignees_table_spec.rb
index 8b26cd589fd..93185b330c7 100644
--- a/spec/migrations/schedule_populate_merge_request_assignees_table_spec.rb
+++ b/spec/migrations/schedule_populate_merge_request_assignees_table_spec.rb
@@ -31,7 +31,7 @@ RSpec.describe SchedulePopulateMergeRequestAssigneesTable do
stub_const("#{described_class.name}::BATCH_SIZE", 2)
Sidekiq::Testing.fake! do
- Timecop.freeze do
+ freeze_time do
migrate!
expect(described_class::MIGRATION)
diff --git a/spec/migrations/schedule_populate_personal_snippet_statistics_spec.rb b/spec/migrations/schedule_populate_personal_snippet_statistics_spec.rb
index ce618449884..8678361fc64 100644
--- a/spec/migrations/schedule_populate_personal_snippet_statistics_spec.rb
+++ b/spec/migrations/schedule_populate_personal_snippet_statistics_spec.rb
@@ -38,7 +38,7 @@ RSpec.describe SchedulePopulatePersonalSnippetStatistics do
stub_const("#{described_class}::BATCH_SIZE", 4)
Sidekiq::Testing.fake! do
- Timecop.freeze do
+ freeze_time do
migrate!
aggregate_failures do
diff --git a/spec/migrations/schedule_populate_project_snippet_statistics_spec.rb b/spec/migrations/schedule_populate_project_snippet_statistics_spec.rb
index 05e9d4d2f79..d5f048ed5cb 100644
--- a/spec/migrations/schedule_populate_project_snippet_statistics_spec.rb
+++ b/spec/migrations/schedule_populate_project_snippet_statistics_spec.rb
@@ -43,7 +43,7 @@ RSpec.describe SchedulePopulateProjectSnippetStatistics do
stub_const("#{described_class}::BATCH_SIZE", 4)
Sidekiq::Testing.fake! do
- Timecop.freeze do
+ freeze_time do
migrate!
aggregate_failures do
diff --git a/spec/migrations/schedule_populate_user_highest_roles_table_spec.rb b/spec/migrations/schedule_populate_user_highest_roles_table_spec.rb
index c7e5c6f30a6..32def8ab47d 100644
--- a/spec/migrations/schedule_populate_user_highest_roles_table_spec.rb
+++ b/spec/migrations/schedule_populate_user_highest_roles_table_spec.rb
@@ -32,7 +32,7 @@ RSpec.describe SchedulePopulateUserHighestRolesTable do
stub_const("#{described_class.name}::BATCH_SIZE", 2)
Sidekiq::Testing.fake! do
- Timecop.freeze do
+ freeze_time do
migrate!
expect(described_class::MIGRATION).to be_scheduled_delayed_migration(5.minutes, 1, 4)
diff --git a/spec/migrations/schedule_recalculate_project_authorizations_second_run_spec.rb b/spec/migrations/schedule_recalculate_project_authorizations_second_run_spec.rb
index 06f1a7e28eb..a02e00de1e3 100644
--- a/spec/migrations/schedule_recalculate_project_authorizations_second_run_spec.rb
+++ b/spec/migrations/schedule_recalculate_project_authorizations_second_run_spec.rb
@@ -16,7 +16,7 @@ RSpec.describe ScheduleRecalculateProjectAuthorizationsSecondRun do
it 'schedules background migration' do
Sidekiq::Testing.fake! do
- Timecop.freeze do
+ freeze_time do
migrate!
expect(BackgroundMigrationWorker.jobs.size).to eq(2)
diff --git a/spec/migrations/schedule_recalculate_project_authorizations_spec.rb b/spec/migrations/schedule_recalculate_project_authorizations_spec.rb
index 9519b103284..378e6aa133d 100644
--- a/spec/migrations/schedule_recalculate_project_authorizations_spec.rb
+++ b/spec/migrations/schedule_recalculate_project_authorizations_spec.rb
@@ -26,7 +26,7 @@ RSpec.describe ScheduleRecalculateProjectAuthorizations do
it 'schedules background migration' do
Sidekiq::Testing.fake! do
- Timecop.freeze do
+ freeze_time do
migrate!
expect(BackgroundMigrationWorker.jobs.size).to eq(2)
@@ -45,7 +45,7 @@ RSpec.describe ScheduleRecalculateProjectAuthorizations do
access_level: 30)
Sidekiq::Testing.fake! do
- Timecop.freeze do
+ freeze_time do
migrate!
expect(BackgroundMigrationWorker.jobs.size).to eq(2)
diff --git a/spec/migrations/schedule_recalculate_project_authorizations_third_run_spec.rb b/spec/migrations/schedule_recalculate_project_authorizations_third_run_spec.rb
index 300bb940dd8..5328abf7ea7 100644
--- a/spec/migrations/schedule_recalculate_project_authorizations_third_run_spec.rb
+++ b/spec/migrations/schedule_recalculate_project_authorizations_third_run_spec.rb
@@ -16,7 +16,7 @@ RSpec.describe ScheduleRecalculateProjectAuthorizationsThirdRun do
it 'schedules background migration' do
Sidekiq::Testing.fake! do
- Timecop.freeze do
+ freeze_time do
migrate!
expect(BackgroundMigrationWorker.jobs.size).to eq(2)
diff --git a/spec/migrations/schedule_sync_issuables_state_id_spec.rb b/spec/migrations/schedule_sync_issuables_state_id_spec.rb
index ecfebbde348..d22d636e084 100644
--- a/spec/migrations/schedule_sync_issuables_state_id_spec.rb
+++ b/spec/migrations/schedule_sync_issuables_state_id_spec.rb
@@ -20,7 +20,7 @@ RSpec.describe ScheduleSyncIssuablesStateId do
it 'correctly schedules issuable sync background migration' do
Sidekiq::Testing.fake! do
- Timecop.freeze do
+ freeze_time do
migrate!
expect(migration).to be_scheduled_delayed_migration(120.seconds, resource_1.id, resource_2.id)
diff --git a/spec/migrations/schedule_sync_issuables_state_id_where_nil_spec.rb b/spec/migrations/schedule_sync_issuables_state_id_where_nil_spec.rb
index d23f5b69d22..3d450f0e6bc 100644
--- a/spec/migrations/schedule_sync_issuables_state_id_where_nil_spec.rb
+++ b/spec/migrations/schedule_sync_issuables_state_id_where_nil_spec.rb
@@ -20,7 +20,7 @@ RSpec.describe ScheduleSyncIssuablesStateIdWhereNil do
it 'correctly schedules issuable sync background migration' do
Sidekiq::Testing.fake! do
- Timecop.freeze do
+ freeze_time do
migrate!
expect(migration).to be_scheduled_delayed_migration(120.seconds, resource_1.id, resource_3.id)
diff --git a/spec/migrations/schedule_update_existing_subgroup_to_match_visibility_level_of_parent_spec.rb b/spec/migrations/schedule_update_existing_subgroup_to_match_visibility_level_of_parent_spec.rb
index 949d8d8794f..deb7aae737a 100644
--- a/spec/migrations/schedule_update_existing_subgroup_to_match_visibility_level_of_parent_spec.rb
+++ b/spec/migrations/schedule_update_existing_subgroup_to_match_visibility_level_of_parent_spec.rb
@@ -14,7 +14,7 @@ RSpec.describe ScheduleUpdateExistingSubgroupToMatchVisibilityLevelOfParent do
create_namespace('child', Gitlab::VisibilityLevel::PUBLIC, parent_id: parent.id)
Sidekiq::Testing.fake! do
- Timecop.freeze do
+ freeze_time do
migrate!
expect(BackgroundMigrationWorker.jobs.size).to eq(1)
@@ -30,7 +30,7 @@ RSpec.describe ScheduleUpdateExistingSubgroupToMatchVisibilityLevelOfParent do
create_namespace('child', Gitlab::VisibilityLevel::PUBLIC, parent_id: middle_group.id)
Sidekiq::Testing.fake! do
- Timecop.freeze do
+ freeze_time do
migrate!
expect(BackgroundMigrationWorker.jobs.size).to eq(1)
@@ -47,7 +47,7 @@ RSpec.describe ScheduleUpdateExistingSubgroupToMatchVisibilityLevelOfParent do
create_namespace('child', Gitlab::VisibilityLevel::PUBLIC, parent_id: middle_group.id)
Sidekiq::Testing.fake! do
- Timecop.freeze do
+ freeze_time do
migrate!
expect(BackgroundMigrationWorker.jobs.size).to eq(1)
@@ -66,7 +66,7 @@ RSpec.describe ScheduleUpdateExistingSubgroupToMatchVisibilityLevelOfParent do
create_namespace('child', Gitlab::VisibilityLevel::PUBLIC, parent_id: middle_group.id)
Sidekiq::Testing.fake! do
- Timecop.freeze do
+ freeze_time do
migrate!
expect(BackgroundMigrationWorker.jobs.size).to eq(2)
diff --git a/spec/models/board_group_recent_visit_spec.rb b/spec/models/board_group_recent_visit_spec.rb
index 4d16e1ff839..c6fbd263072 100644
--- a/spec/models/board_group_recent_visit_spec.rb
+++ b/spec/models/board_group_recent_visit_spec.rb
@@ -28,7 +28,7 @@ RSpec.describe BoardGroupRecentVisit do
let!(:visit) { create :board_group_recent_visit, group: board.group, board: board, user: user, updated_at: 7.days.ago }
it 'updates the timestamp' do
- Timecop.freeze do
+ freeze_time do
described_class.visited!(user, board)
expect(described_class.count).to eq 1
diff --git a/spec/models/board_project_recent_visit_spec.rb b/spec/models/board_project_recent_visit_spec.rb
index 8e74405fd8c..145a4f5b1a7 100644
--- a/spec/models/board_project_recent_visit_spec.rb
+++ b/spec/models/board_project_recent_visit_spec.rb
@@ -28,7 +28,7 @@ RSpec.describe BoardProjectRecentVisit do
let!(:visit) { create :board_project_recent_visit, project: board.project, board: board, user: user, updated_at: 7.days.ago }
it 'updates the timestamp' do
- Timecop.freeze do
+ freeze_time do
described_class.visited!(user, board)
expect(described_class.count).to eq 1
diff --git a/spec/models/ci/build_spec.rb b/spec/models/ci/build_spec.rb
index 069ac23c5a4..c4934da73fc 100644
--- a/spec/models/ci/build_spec.rb
+++ b/spec/models/ci/build_spec.rb
@@ -448,7 +448,7 @@ RSpec.describe Ci::Build do
end
it 'schedules BuildScheduleWorker at the right time' do
- Timecop.freeze do
+ freeze_time do
expect(Ci::BuildScheduleWorker)
.to receive(:perform_at).with(be_like_time(1.minute.since), build.id)
@@ -496,7 +496,7 @@ RSpec.describe Ci::Build do
let(:option) { { start_in: '1 day' } }
it 'returns date after 1 day' do
- Timecop.freeze do
+ freeze_time do
is_expected.to eq(1.day.since)
end
end
@@ -506,7 +506,7 @@ RSpec.describe Ci::Build do
let(:option) { { start_in: '1 week' } }
it 'returns date after 1 week' do
- Timecop.freeze do
+ freeze_time do
is_expected.to eq(1.week.since)
end
end
@@ -4087,7 +4087,7 @@ RSpec.describe Ci::Build do
let(:path) { 'other_artifacts_0.1.2/another-subdirectory/banana_sample.gif' }
around do |example|
- Timecop.freeze { example.run }
+ freeze_time { example.run }
end
before do
diff --git a/spec/models/clusters/applications/prometheus_spec.rb b/spec/models/clusters/applications/prometheus_spec.rb
index 6ae4b37d5ca..82971596176 100644
--- a/spec/models/clusters/applications/prometheus_spec.rb
+++ b/spec/models/clusters/applications/prometheus_spec.rb
@@ -46,7 +46,7 @@ RSpec.describe Clusters::Applications::Prometheus do
subject { create(:clusters_applications_prometheus, :installed, cluster: cluster) }
it 'sets last_update_started_at to now' do
- Timecop.freeze do
+ freeze_time do
expect { subject.make_updating }.to change { subject.reload.last_update_started_at }.to be_within(1.second).of(Time.current)
end
end
@@ -353,7 +353,7 @@ RSpec.describe Clusters::Applications::Prometheus do
let(:timestamp) { Time.current - 5.minutes }
around do |example|
- Timecop.freeze { example.run }
+ freeze_time { example.run }
end
before do
diff --git a/spec/models/concerns/prometheus_adapter_spec.rb b/spec/models/concerns/prometheus_adapter_spec.rb
index e795e2b06cb..235e505c6e9 100644
--- a/spec/models/concerns/prometheus_adapter_spec.rb
+++ b/spec/models/concerns/prometheus_adapter_spec.rb
@@ -25,7 +25,7 @@ RSpec.describe PrometheusAdapter, :use_clean_rails_memory_store_caching do
let(:validation_respone) { { data: { valid: true } } }
around do |example|
- Timecop.freeze { example.run }
+ freeze_time { example.run }
end
context 'with valid data' do
@@ -45,7 +45,7 @@ RSpec.describe PrometheusAdapter, :use_clean_rails_memory_store_caching do
let(:environment) { build_stubbed(:environment, slug: 'env-slug') }
around do |example|
- Timecop.freeze { example.run }
+ freeze_time { example.run }
end
context 'with valid data' do
@@ -85,7 +85,7 @@ RSpec.describe PrometheusAdapter, :use_clean_rails_memory_store_caching do
let(:deployment_query) { Gitlab::Prometheus::Queries::DeploymentQuery }
around do |example|
- Timecop.freeze { example.run }
+ freeze_time { example.run }
end
context 'with valid data' do
@@ -107,7 +107,7 @@ RSpec.describe PrometheusAdapter, :use_clean_rails_memory_store_caching do
let(:time_window) { [1552642245.067, 1552642095.831] }
around do |example|
- Timecop.freeze { example.run }
+ freeze_time { example.run }
end
context 'with valid data' do
@@ -137,7 +137,7 @@ RSpec.describe PrometheusAdapter, :use_clean_rails_memory_store_caching do
end
around do |example|
- Timecop.freeze { example.run }
+ freeze_time { example.run }
end
context 'when service is inactive' do
diff --git a/spec/models/deployment_spec.rb b/spec/models/deployment_spec.rb
index b320390711e..6ea94b4cd1a 100644
--- a/spec/models/deployment_spec.rb
+++ b/spec/models/deployment_spec.rb
@@ -99,7 +99,7 @@ RSpec.describe Deployment do
end
it 'starts running' do
- Timecop.freeze do
+ freeze_time do
expect(deployment).to be_running
expect(deployment.finished_at).to be_nil
end
@@ -110,7 +110,7 @@ RSpec.describe Deployment do
let(:deployment) { create(:deployment, :running) }
it 'has correct status' do
- Timecop.freeze do
+ freeze_time do
deployment.succeed!
expect(deployment).to be_success
@@ -137,7 +137,7 @@ RSpec.describe Deployment do
let(:deployment) { create(:deployment, :running) }
it 'has correct status' do
- Timecop.freeze do
+ freeze_time do
deployment.drop!
expect(deployment).to be_failed
@@ -157,7 +157,7 @@ RSpec.describe Deployment do
let(:deployment) { create(:deployment, :running) }
it 'has correct status' do
- Timecop.freeze do
+ freeze_time do
deployment.cancel!
expect(deployment).to be_canceled
@@ -584,7 +584,7 @@ RSpec.describe Deployment do
end
it 'updates finished_at when transitioning to a finished status' do
- Timecop.freeze do
+ freeze_time do
deploy.update_status('success')
expect(deploy.read_attribute(:finished_at)).to eq(Time.current)
diff --git a/spec/models/environment_spec.rb b/spec/models/environment_spec.rb
index 2696d144db4..bb0b3748b76 100644
--- a/spec/models/environment_spec.rb
+++ b/spec/models/environment_spec.rb
@@ -1222,7 +1222,7 @@ RSpec.describe Environment, :use_clean_rails_memory_store_caching do
let(:environment) { build(:environment, :will_auto_stop) }
it 'returns when it will expire' do
- Timecop.freeze { is_expected.to eq(1.day.to_i) }
+ freeze_time { is_expected.to eq(1.day.to_i) }
end
end
@@ -1248,7 +1248,7 @@ RSpec.describe Environment, :use_clean_rails_memory_store_caching do
end
with_them do
it 'sets correct auto_stop_in' do
- Timecop.freeze do
+ freeze_time do
if expected_result.is_a?(Integer) || expected_result.nil?
subject
diff --git a/spec/models/metrics/dashboard/annotation_spec.rb b/spec/models/metrics/dashboard/annotation_spec.rb
index bd4baeb8851..4b7492016f3 100644
--- a/spec/models/metrics/dashboard/annotation_spec.rb
+++ b/spec/models/metrics/dashboard/annotation_spec.rb
@@ -100,7 +100,7 @@ RSpec.describe Metrics::Dashboard::Annotation do
describe '#ending_before' do
it 'returns annotations only for appointed dashboard' do
- Timecop.freeze do
+ freeze_time do
twelve_minutes_old_annotation = create(:metrics_dashboard_annotation, starting_at: 15.minutes.ago, ending_at: 12.minutes.ago)
create(:metrics_dashboard_annotation, starting_at: 15.minutes.ago, ending_at: 11.minutes.ago)
diff --git a/spec/models/namespace/root_storage_statistics_spec.rb b/spec/models/namespace/root_storage_statistics_spec.rb
index ce6f875ee09..92a8d17a2a8 100644
--- a/spec/models/namespace/root_storage_statistics_spec.rb
+++ b/spec/models/namespace/root_storage_statistics_spec.rb
@@ -44,6 +44,7 @@ RSpec.describe Namespace::RootStorageStatistics, type: :model do
total_packages_size = stat1.packages_size + stat2.packages_size
total_storage_size = stat1.storage_size + stat2.storage_size
total_snippets_size = stat1.snippets_size + stat2.snippets_size
+ total_pipeline_artifacts_size = stat1.pipeline_artifacts_size + stat2.pipeline_artifacts_size
expect(root_storage_statistics.repository_size).to eq(total_repository_size)
expect(root_storage_statistics.wiki_size).to eq(total_wiki_size)
@@ -52,6 +53,7 @@ RSpec.describe Namespace::RootStorageStatistics, type: :model do
expect(root_storage_statistics.packages_size).to eq(total_packages_size)
expect(root_storage_statistics.storage_size).to eq(total_storage_size)
expect(root_storage_statistics.snippets_size).to eq(total_snippets_size)
+ expect(root_storage_statistics.pipeline_artifacts_size).to eq(total_pipeline_artifacts_size)
end
it 'works when there are no projects' do
@@ -67,6 +69,7 @@ RSpec.describe Namespace::RootStorageStatistics, type: :model do
expect(root_storage_statistics.packages_size).to eq(0)
expect(root_storage_statistics.storage_size).to eq(0)
expect(root_storage_statistics.snippets_size).to eq(0)
+ expect(root_storage_statistics.pipeline_artifacts_size).to eq(0)
end
end
diff --git a/spec/models/remote_mirror_spec.rb b/spec/models/remote_mirror_spec.rb
index ebc9760ab14..c7dbf3c0e92 100644
--- a/spec/models/remote_mirror_spec.rb
+++ b/spec/models/remote_mirror_spec.rb
@@ -283,7 +283,7 @@ RSpec.describe RemoteMirror, :mailer do
let(:remote_mirror) { create(:project, :repository, :remote_mirror).remote_mirrors.first }
around do |example|
- Timecop.freeze { example.run }
+ freeze_time { example.run }
end
context 'with remote mirroring disabled' do
@@ -397,7 +397,7 @@ RSpec.describe RemoteMirror, :mailer do
let(:timestamp) { Time.current - 5.minutes }
around do |example|
- Timecop.freeze { example.run }
+ freeze_time { example.run }
end
before do
diff --git a/spec/presenters/ci/build_presenter_spec.rb b/spec/presenters/ci/build_presenter_spec.rb
index 8d302b242b3..1ff2ea3d225 100644
--- a/spec/presenters/ci/build_presenter_spec.rb
+++ b/spec/presenters/ci/build_presenter_spec.rb
@@ -228,7 +228,7 @@ RSpec.describe Ci::BuildPresenter do
let(:build) { create(:ci_build, :scheduled) }
it 'returns execution time' do
- Timecop.freeze do
+ freeze_time do
is_expected.to be_like_time(60.0)
end
end
@@ -238,7 +238,7 @@ RSpec.describe Ci::BuildPresenter do
let(:build) { create(:ci_build, :expired_scheduled) }
it 'returns execution time' do
- Timecop.freeze do
+ freeze_time do
is_expected.to eq(0)
end
end
@@ -249,7 +249,7 @@ RSpec.describe Ci::BuildPresenter do
let(:build) { create(:ci_build) }
it 'does not return execution time' do
- Timecop.freeze do
+ freeze_time do
is_expected.to be_falsy
end
end
diff --git a/spec/requests/api/conan_packages_spec.rb b/spec/requests/api/conan_packages_spec.rb
index 6569ce91bb8..58c360d055b 100644
--- a/spec/requests/api/conan_packages_spec.rb
+++ b/spec/requests/api/conan_packages_spec.rb
@@ -153,7 +153,7 @@ RSpec.describe API::ConanPackages do
end
it 'token has valid validity time' do
- Timecop.freeze do
+ freeze_time do
subject
payload = JSONWebToken::HMACToken.decode(
diff --git a/spec/requests/api/graphql/mutations/snippets/create_spec.rb b/spec/requests/api/graphql/mutations/snippets/create_spec.rb
index 705e3647f4a..1bb446de708 100644
--- a/spec/requests/api/graphql/mutations/snippets/create_spec.rb
+++ b/spec/requests/api/graphql/mutations/snippets/create_spec.rb
@@ -99,6 +99,8 @@ RSpec.describe 'Creating a Snippet' do
it_behaves_like 'a mutation that returns errors in the response', errors: ['Snippet actions have invalid data']
it_behaves_like 'does not create snippet'
end
+
+ it_behaves_like 'snippet edit usage data counters'
end
context 'with PersonalSnippet' do
@@ -129,6 +131,8 @@ RSpec.describe 'Creating a Snippet' do
it_behaves_like 'a mutation that returns top-level errors',
errors: [Gitlab::Graphql::Authorize::AuthorizeResource::RESOURCE_ACCESS_ERROR]
end
+
+ it_behaves_like 'snippet edit usage data counters'
end
context 'when there are ActiveRecord validation errors' do
diff --git a/spec/requests/api/graphql/mutations/snippets/update_spec.rb b/spec/requests/api/graphql/mutations/snippets/update_spec.rb
index 9564bbc46de..58ce74b9263 100644
--- a/spec/requests/api/graphql/mutations/snippets/update_spec.rb
+++ b/spec/requests/api/graphql/mutations/snippets/update_spec.rb
@@ -131,6 +131,7 @@ RSpec.describe 'Updating a Snippet' do
it_behaves_like 'graphql update actions'
it_behaves_like 'when the snippet is not found'
+ it_behaves_like 'snippet edit usage data counters'
end
describe 'ProjectSnippet' do
@@ -173,6 +174,8 @@ RSpec.describe 'Updating a Snippet' do
expect(errors.first['message']).to eq(Gitlab::Graphql::Authorize::AuthorizeResource::RESOURCE_ACCESS_ERROR)
end
end
+
+ it_behaves_like 'snippet edit usage data counters'
end
it_behaves_like 'when the snippet is not found'
diff --git a/spec/requests/api/internal/base_spec.rb b/spec/requests/api/internal/base_spec.rb
index 873189af397..bb7288ed227 100644
--- a/spec/requests/api/internal/base_spec.rb
+++ b/spec/requests/api/internal/base_spec.rb
@@ -415,7 +415,7 @@ RSpec.describe API::Internal::Base do
let(:env) { {} }
around do |example|
- Timecop.freeze { example.run }
+ freeze_time { example.run }
end
before do
diff --git a/spec/requests/api/users_spec.rb b/spec/requests/api/users_spec.rb
index 6c6497a240b..39cff2ad74e 100644
--- a/spec/requests/api/users_spec.rb
+++ b/spec/requests/api/users_spec.rb
@@ -348,6 +348,26 @@ RSpec.describe API::Users, :do_not_mock_admin_mode do
expect(response).to match_response_schema('public_api/v4/user/basics')
expect(json_response.first.keys).not_to include 'is_admin'
end
+
+ context 'exclude_internal param' do
+ let_it_be(:internal_user) { User.alert_bot }
+
+ it 'returns all users when it is not set' do
+ get api("/users?exclude_internal=false", user)
+
+ expect(response).to match_response_schema('public_api/v4/user/basics')
+ expect(response).to include_pagination_headers
+ expect(json_response.map { |u| u['id'] }).to include(internal_user.id)
+ end
+
+ it 'returns all non internal users when it is set' do
+ get api("/users?exclude_internal=true", user)
+
+ expect(response).to match_response_schema('public_api/v4/user/basics')
+ expect(response).to include_pagination_headers
+ expect(json_response.map { |u| u['id'] }).not_to include(internal_user.id)
+ end
+ end
end
context "when admin" do
diff --git a/spec/requests/projects/metrics_dashboard_spec.rb b/spec/requests/projects/metrics_dashboard_spec.rb
index f35af571e79..0b6e2ef5151 100644
--- a/spec/requests/projects/metrics_dashboard_spec.rb
+++ b/spec/requests/projects/metrics_dashboard_spec.rb
@@ -14,7 +14,7 @@ RSpec.describe 'Projects::MetricsDashboardController' do
end
describe 'GET /:namespace/:project/-/metrics' do
- it 'returns 200' do
+ it "redirects to default environment's metrics dashboard" do
send_request
expect(response).to redirect_to(dashboard_route(environment: environment))
end
@@ -24,6 +24,18 @@ RSpec.describe 'Projects::MetricsDashboardController' do
expect(assigns(:default_environment).id).to eq(environment.id)
end
+ it 'retains existing parameters when redirecting' do
+ get "#{dashboard_route(dashboard_path: '.gitlab/dashboards/dashboard_path.yml')}/panel/new"
+
+ expect(response).to redirect_to(
+ dashboard_route(
+ dashboard_path: '.gitlab/dashboards/dashboard_path.yml',
+ page: 'panel/new',
+ environment: environment
+ )
+ )
+ end
+
context 'with anonymous user and public dashboard visibility' do
let(:anonymous_user) { create(:user) }
let(:project) do
diff --git a/spec/serializers/analytics_build_entity_spec.rb b/spec/serializers/analytics_build_entity_spec.rb
index 20bd017d1cf..09804681f5d 100644
--- a/spec/serializers/analytics_build_entity_spec.rb
+++ b/spec/serializers/analytics_build_entity_spec.rb
@@ -16,7 +16,7 @@ RSpec.describe AnalyticsBuildEntity do
subject { entity.as_json }
around do |example|
- Timecop.freeze { example.run }
+ freeze_time { example.run }
end
it 'contains the URL' do
diff --git a/spec/services/clusters/applications/schedule_update_service_spec.rb b/spec/services/clusters/applications/schedule_update_service_spec.rb
index f559fb1b7aa..01a75a334e6 100644
--- a/spec/services/clusters/applications/schedule_update_service_spec.rb
+++ b/spec/services/clusters/applications/schedule_update_service_spec.rb
@@ -7,7 +7,7 @@ RSpec.describe Clusters::Applications::ScheduleUpdateService do
let(:project) { create(:project) }
around do |example|
- Timecop.freeze { example.run }
+ freeze_time { example.run }
end
context 'when application is able to be updated' do
diff --git a/spec/services/deployments/after_create_service_spec.rb b/spec/services/deployments/after_create_service_spec.rb
index 3287eed03b7..6cdb4c88191 100644
--- a/spec/services/deployments/after_create_service_spec.rb
+++ b/spec/services/deployments/after_create_service_spec.rb
@@ -122,7 +122,7 @@ RSpec.describe Deployments::AfterCreateService do
end
it 'renews auto stop at' do
- Timecop.freeze do
+ freeze_time do
environment.update!(auto_stop_at: nil)
expect { subject.execute }
diff --git a/spec/services/git/process_ref_changes_service_spec.rb b/spec/services/git/process_ref_changes_service_spec.rb
index fc313bf6eb9..087f4ba372b 100644
--- a/spec/services/git/process_ref_changes_service_spec.rb
+++ b/spec/services/git/process_ref_changes_service_spec.rb
@@ -172,23 +172,31 @@ RSpec.describe Git::ProcessRefChangesService do
[
{ index: 0, oldrev: Gitlab::Git::BLANK_SHA, newrev: '789012', ref: "#{ref_prefix}/create1" },
{ index: 1, oldrev: Gitlab::Git::BLANK_SHA, newrev: '789013', ref: "#{ref_prefix}/create2" },
- { index: 2, oldrev: Gitlab::Git::BLANK_SHA, newrev: '789014', ref: "#{ref_prefix}/create3" }
+ { index: 2, oldrev: Gitlab::Git::BLANK_SHA, newrev: '789014', ref: "#{ref_prefix}/create3" },
+ { index: 3, oldrev: '789015', newrev: '789016', ref: "#{ref_prefix}/changed1" },
+ { index: 4, oldrev: '789017', newrev: '789018', ref: "#{ref_prefix}/changed2" },
+ { index: 5, oldrev: '789019', newrev: Gitlab::Git::BLANK_SHA, ref: "#{ref_prefix}/removed1" },
+ { index: 6, oldrev: '789020', newrev: Gitlab::Git::BLANK_SHA, ref: "#{ref_prefix}/removed2" }
]
end
let(:git_changes) { double(branch_changes: branch_changes, tag_changes: tag_changes) }
- it 'schedules job for existing merge requests' do
- expect_next_instance_of(MergeRequests::PushedBranchesService) do |service|
- expect(service).to receive(:execute).and_return(%w(create1 create2))
- end
+ before do
+ allow(MergeRequests::PushedBranchesService).to receive(:new).and_return(
+ double(execute: %w(create1 create2)), double(execute: %w(changed1)), double(execute: %w(removed2))
+ )
+ end
+ it 'schedules job for existing merge requests' do
expect(UpdateMergeRequestsWorker).to receive(:perform_async)
.with(project.id, user.id, Gitlab::Git::BLANK_SHA, '789012', "#{ref_prefix}/create1").ordered
expect(UpdateMergeRequestsWorker).to receive(:perform_async)
.with(project.id, user.id, Gitlab::Git::BLANK_SHA, '789013', "#{ref_prefix}/create2").ordered
- expect(UpdateMergeRequestsWorker).not_to receive(:perform_async)
- .with(project.id, user.id, Gitlab::Git::BLANK_SHA, '789014', "#{ref_prefix}/create3").ordered
+ expect(UpdateMergeRequestsWorker).to receive(:perform_async)
+ .with(project.id, user.id, '789015', '789016', "#{ref_prefix}/changed1").ordered
+ expect(UpdateMergeRequestsWorker).to receive(:perform_async)
+ .with(project.id, user.id, '789020', Gitlab::Git::BLANK_SHA, "#{ref_prefix}/removed2").ordered
subject.execute
end
diff --git a/spec/services/merge_requests/delete_non_latest_diffs_service_spec.rb b/spec/services/merge_requests/delete_non_latest_diffs_service_spec.rb
index 377615bbc6f..cdaacaf5fca 100644
--- a/spec/services/merge_requests/delete_non_latest_diffs_service_spec.rb
+++ b/spec/services/merge_requests/delete_non_latest_diffs_service_spec.rb
@@ -19,7 +19,7 @@ RSpec.describe MergeRequests::DeleteNonLatestDiffsService, :clean_gitlab_redis_s
expect(diffs.count).to eq(4)
- Timecop.freeze do
+ freeze_time do
expect(DeleteDiffFilesWorker)
.to receive(:bulk_perform_in)
.with(5.minutes, [[diffs.first.id], [diffs.second.id]])
diff --git a/spec/services/note_summary_spec.rb b/spec/services/note_summary_spec.rb
index 38174748b19..ad244f62292 100644
--- a/spec/services/note_summary_spec.rb
+++ b/spec/services/note_summary_spec.rb
@@ -23,7 +23,7 @@ RSpec.describe NoteSummary do
describe '#note' do
it 'returns note hash' do
- Timecop.freeze do
+ freeze_time do
expect(create_note_summary.note).to eq(noteable: noteable, project: project, author: user, note: 'note',
created_at: Time.current)
end
diff --git a/spec/services/projects/hashed_storage/base_attachment_service_spec.rb b/spec/services/projects/hashed_storage/base_attachment_service_spec.rb
index 5e1b6f2e404..969381b8748 100644
--- a/spec/services/projects/hashed_storage/base_attachment_service_spec.rb
+++ b/spec/services/projects/hashed_storage/base_attachment_service_spec.rb
@@ -30,7 +30,7 @@ RSpec.describe Projects::HashedStorage::BaseAttachmentService do
target_path = Dir.mktmpdir
expect(Dir.exist?(target_path)).to be_truthy
- Timecop.freeze do
+ freeze_time do
suffix = Time.current.utc.to_i
subject.send(:discard_path!, target_path)
diff --git a/spec/services/releases/create_service_spec.rb b/spec/services/releases/create_service_spec.rb
index ad4696b0074..90648340b66 100644
--- a/spec/services/releases/create_service_spec.rb
+++ b/spec/services/releases/create_service_spec.rb
@@ -202,7 +202,7 @@ RSpec.describe Releases::CreateService do
let(:last_release) { project.releases.last }
around do |example|
- Timecop.freeze { example.run }
+ freeze_time { example.run }
end
subject { service.execute }
diff --git a/spec/services/submit_usage_ping_service_spec.rb b/spec/services/submit_usage_ping_service_spec.rb
index 450af68d383..401d1ed5adc 100644
--- a/spec/services/submit_usage_ping_service_spec.rb
+++ b/spec/services/submit_usage_ping_service_spec.rb
@@ -68,7 +68,7 @@ RSpec.describe SubmitUsagePingService do
end
end
- shared_examples 'saves DevOps score data from the response' do
+ shared_examples 'saves DevOps report data from the response' do
it do
expect { subject.execute }
.to change { DevOpsScore::Metric.count }
@@ -123,15 +123,15 @@ RSpec.describe SubmitUsagePingService do
stub_response(body: with_conv_index_params)
end
- it_behaves_like 'saves DevOps score data from the response'
+ it_behaves_like 'saves DevOps report data from the response'
end
- context 'when DevOps score data is passed' do
+ context 'when DevOps report data is passed' do
before do
stub_response(body: with_dev_ops_score_params)
end
- it_behaves_like 'saves DevOps score data from the response'
+ it_behaves_like 'saves DevOps report data from the response'
end
context 'with save_raw_usage_data feature enabled' do
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index adf21c1c965..de4bd178b9d 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -100,6 +100,10 @@ RSpec.configure do |config|
metadata[:enable_admin_mode] = true if location =~ %r{(ee)?/spec/controllers/admin/}
end
+ config.define_derived_metadata(file_path: %r{(ee)?/spec/.+_docs\.rb\z}) do |metadata|
+ metadata[:type] = :feature
+ end
+
config.include LicenseHelpers
config.include ActiveJob::TestHelper
config.include ActiveSupport::Testing::TimeHelpers
diff --git a/spec/support/helpers/docs_screenshot_helpers.rb b/spec/support/helpers/docs_screenshot_helpers.rb
new file mode 100644
index 00000000000..aa3aad0a740
--- /dev/null
+++ b/spec/support/helpers/docs_screenshot_helpers.rb
@@ -0,0 +1,39 @@
+# frozen_string_literal: true
+
+require 'fileutils'
+require 'mini_magick'
+
+module DocsScreenshotHelpers
+ extend ActiveSupport::Concern
+
+ def set_crop_data(element, padding)
+ @crop_element = element
+ @crop_padding = padding
+ end
+
+ def crop_image_screenshot(path)
+ element_rect = @crop_element.evaluate_script("this.getBoundingClientRect()")
+
+ width = element_rect['width'] + (@crop_padding * 2)
+ height = element_rect['height'] + (@crop_padding * 2)
+
+ x = element_rect['x'] - @crop_padding
+ y = element_rect['y'] - @crop_padding
+
+ image = MiniMagick::Image.new(path)
+ image.crop "#{width}x#{height}+#{x}+#{y}"
+ end
+
+ included do |base|
+ after do |example|
+ filename = "#{example.description}.png"
+ path = File.expand_path(filename, 'doc/')
+ page.save_screenshot(path)
+
+ if @crop_element
+ crop_image_screenshot(path)
+ set_crop_data(nil, nil)
+ end
+ end
+ end
+end
diff --git a/spec/support/shared_contexts/finders/users_finder_shared_contexts.rb b/spec/support/shared_contexts/finders/users_finder_shared_contexts.rb
index fc8f9d2f407..54022aeb494 100644
--- a/spec/support/shared_contexts/finders/users_finder_shared_contexts.rb
+++ b/spec/support/shared_contexts/finders/users_finder_shared_contexts.rb
@@ -5,4 +5,5 @@ RSpec.shared_context 'UsersFinder#execute filter by project context' do
let_it_be(:blocked_user) { create(:user, :blocked, username: 'notsorandom') }
let_it_be(:external_user) { create(:user, :external) }
let_it_be(:omniauth_user) { create(:omniauth_user, provider: 'twitter', extern_uid: '123456') }
+ let_it_be(:internal_user) { User.alert_bot }
end
diff --git a/spec/support/shared_examples/lib/gitlab/background_migration/mentions_migration_shared_examples.rb b/spec/support/shared_examples/lib/gitlab/background_migration/mentions_migration_shared_examples.rb
index 8cf6babe146..e93077c42e1 100644
--- a/spec/support/shared_examples/lib/gitlab/background_migration/mentions_migration_shared_examples.rb
+++ b/spec/support/shared_examples/lib/gitlab/background_migration/mentions_migration_shared_examples.rb
@@ -63,7 +63,7 @@ RSpec.shared_examples 'schedules resource mentions migration' do |resource_class
it 'schedules background migrations' do
Sidekiq::Testing.fake! do
- Timecop.freeze do
+ freeze_time do
resource_count = is_for_notes ? Note.count : resource_class.count
expect(resource_count).to eq 5
diff --git a/spec/support/shared_examples/models/relative_positioning_shared_examples.rb b/spec/support/shared_examples/models/relative_positioning_shared_examples.rb
index ebb91a2fbad..0ad8d8cbde1 100644
--- a/spec/support/shared_examples/models/relative_positioning_shared_examples.rb
+++ b/spec/support/shared_examples/models/relative_positioning_shared_examples.rb
@@ -568,6 +568,12 @@ RSpec.shared_examples 'a class that supports relative positioning' do
end
end
+ it 'places items at most IDEAL_DISTANCE from the start when the range is open' do
+ n = item1.send(:scoped_items).count
+
+ expect([item1, item2].map(&:relative_position)).to all(be >= (RelativePositioning::START_POSITION - (n * RelativePositioning::IDEAL_DISTANCE)))
+ end
+
it 'moves item to the end' do
new_item.move_to_start
@@ -613,6 +619,12 @@ RSpec.shared_examples 'a class that supports relative positioning' do
end
end
+ it 'places items at most IDEAL_DISTANCE from the start when the range is open' do
+ n = item1.send(:scoped_items).count
+
+ expect([item1, item2].map(&:relative_position)).to all(be <= (RelativePositioning::START_POSITION + (n * RelativePositioning::IDEAL_DISTANCE)))
+ end
+
it 'moves item to the end' do
new_item.move_to_end
diff --git a/spec/support/shared_examples/models/throttled_touch_shared_examples.rb b/spec/support/shared_examples/models/throttled_touch_shared_examples.rb
index fc4f6053bb9..14b851d2828 100644
--- a/spec/support/shared_examples/models/throttled_touch_shared_examples.rb
+++ b/spec/support/shared_examples/models/throttled_touch_shared_examples.rb
@@ -3,7 +3,7 @@
RSpec.shared_examples 'throttled touch' do
describe '#touch' do
it 'updates the updated_at timestamp' do
- Timecop.freeze do
+ freeze_time do
subject.touch
expect(subject.updated_at).to be_like_time(Time.zone.now)
end
diff --git a/spec/support/shared_examples/requests/api/graphql/mutations/snippets_shared_examples.rb b/spec/support/shared_examples/requests/api/graphql/mutations/snippets_shared_examples.rb
index 48824a4b0d2..62dbac3fd4d 100644
--- a/spec/support/shared_examples/requests/api/graphql/mutations/snippets_shared_examples.rb
+++ b/spec/support/shared_examples/requests/api/graphql/mutations/snippets_shared_examples.rb
@@ -8,3 +8,42 @@ RSpec.shared_examples 'when the snippet is not found' do
it_behaves_like 'a mutation that returns top-level errors',
errors: [Gitlab::Graphql::Authorize::AuthorizeResource::RESOURCE_ACCESS_ERROR]
end
+
+RSpec.shared_examples 'snippet edit usage data counters' do
+ context 'when user is sessionless' do
+ it 'does not track usage data actions' do
+ expect(::Gitlab::UsageDataCounters::EditorUniqueCounter).not_to receive(:track_snippet_editor_edit_action)
+
+ post_graphql_mutation(mutation, current_user: current_user)
+ end
+ end
+
+ context 'when user is not sessionless' do
+ before do
+ session_id = Rack::Session::SessionId.new('6919a6f1bb119dd7396fadc38fd18d0d')
+ session_hash = { 'warden.user.user.key' => [[current_user.id], current_user.encrypted_password[0, 29]] }
+
+ Gitlab::Redis::SharedState.with do |redis|
+ redis.set("session:gitlab:#{session_id.private_id}", Marshal.dump(session_hash))
+ end
+
+ cookies[Gitlab::Application.config.session_options[:key]] = session_id.public_id
+ end
+
+ it 'tracks usage data actions', :clean_gitlab_redis_shared_state do
+ expect(::Gitlab::UsageDataCounters::EditorUniqueCounter).to receive(:track_snippet_editor_edit_action)
+
+ post_graphql_mutation(mutation)
+ end
+
+ context 'when mutation result raises an error' do
+ it 'does not track usage data actions' do
+ mutation_vars[:title] = nil
+
+ expect(::Gitlab::UsageDataCounters::EditorUniqueCounter).not_to receive(:track_snippet_editor_edit_action)
+
+ post_graphql_mutation(mutation)
+ end
+ end
+ end
+end
diff --git a/spec/workers/cluster_update_app_worker_spec.rb b/spec/workers/cluster_update_app_worker_spec.rb
index c24f40024fd..8b8c1c82099 100644
--- a/spec/workers/cluster_update_app_worker_spec.rb
+++ b/spec/workers/cluster_update_app_worker_spec.rb
@@ -12,7 +12,7 @@ RSpec.describe ClusterUpdateAppWorker do
subject { described_class.new }
around do |example|
- Timecop.freeze(Time.current) { example.run }
+ freeze_time { example.run }
end
before do
diff --git a/spec/workers/repository_update_remote_mirror_worker_spec.rb b/spec/workers/repository_update_remote_mirror_worker_spec.rb
index c6e667097ec..858f5226c48 100644
--- a/spec/workers/repository_update_remote_mirror_worker_spec.rb
+++ b/spec/workers/repository_update_remote_mirror_worker_spec.rb
@@ -9,7 +9,7 @@ RSpec.describe RepositoryUpdateRemoteMirrorWorker, :clean_gitlab_redis_shared_st
let(:scheduled_time) { Time.current - 5.minutes }
around do |example|
- Timecop.freeze(Time.current) { example.run }
+ freeze_time { example.run }
end
def expect_mirror_service_to_return(mirror, result, tries = 0)
diff --git a/tooling/lib/tooling/images.rb b/tooling/lib/tooling/images.rb
new file mode 100644
index 00000000000..d0c464b983c
--- /dev/null
+++ b/tooling/lib/tooling/images.rb
@@ -0,0 +1,56 @@
+# frozen_string_literal: true
+
+module Tooling
+ module Image
+ # Determine the tolerance till when we run pngquant in a loop
+ TOLERANCE = 10000
+
+ def self.check_executables
+ unless system('pngquant --version', out: File::NULL)
+ warn(
+ 'Error: pngquant executable was not detected in the system.',
+ 'Download pngquant at https://pngquant.org/ and place the executable in /usr/local/bin'
+ )
+ abort
+ end
+
+ unless system('gm version', out: File::NULL)
+ warn(
+ 'Error: gm executable was not detected in the system.',
+ 'Please install imagemagick: brew install imagemagick or sudo apt install imagemagick'
+ )
+ abort
+ end
+ end
+
+ def self.compress_image(file, keep_original = false)
+ check_executables
+
+ compressed_file = "#{file}.compressed"
+ FileUtils.copy(file, compressed_file)
+
+ pngquant_file = PngQuantizator::Image.new(compressed_file)
+
+ # Run the image repeatedly through pngquant until
+ # the change in file size is within TOLERANCE
+ # or the loop count is above 1000
+ 1000.times do
+ before = File.size(compressed_file)
+ pngquant_file.quantize!
+ after = File.size(compressed_file)
+ break if before - after <= TOLERANCE
+ end
+
+ savings = File.size(file) - File.size(compressed_file)
+ is_uncompressed = savings > TOLERANCE
+
+ if is_uncompressed && !keep_original
+ FileUtils.copy(compressed_file, file)
+ end
+
+ FileUtils.remove(compressed_file)
+
+ [is_uncompressed, savings]
+ end
+ end
+end