Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2022-06-10 03:08:14 +00:00
parent edcd73e5fd
commit 55bd6d19a7
24 changed files with 865 additions and 38 deletions

View File

@ -0,0 +1,25 @@
---
Fips/MD5:
Exclude:
- 'app/experiments/application_experiment.rb'
- 'app/models/concerns/checksummable.rb'
- 'app/services/gravatar_service.rb'
- 'app/services/packages/debian/generate_distribution_service.rb'
- 'app/services/packages/go/create_package_service.rb'
- 'app/services/packages/maven/metadata/append_package_file_service.rb'
- 'app/services/packages/rubygems/create_gemspec_service.rb'
- 'config/application.rb'
- 'config/initializers/wikicloth_redos_patch.rb'
- 'ee/app/models/license.rb'
- 'ee/spec/lib/ee/gitlab/usage_data_spec.rb'
- 'lib/tasks/migrate/setup_postgresql.rake'
- 'qa/qa/specs/features/api/3_create/repository/project_archive_compare_spec.rb'
- 'spec/controllers/invites_controller_spec.rb'
- 'spec/lib/gitlab/ci/trace/archive_spec.rb'
- 'spec/lib/gitlab/ci/trace/remote_checksum_spec.rb'
- 'spec/models/concerns/checksummable_spec.rb'
- 'spec/services/gravatar_service_spec.rb'
- 'spec/support/matchers/match_file.rb'
- 'spec/support/shared_examples/services/packages/debian/generate_distribution_shared_examples.rb'
- 'spec/tooling/rspec_flaky/example_spec.rb'
- 'tooling/rspec_flaky/example.rb'

View File

@ -0,0 +1,222 @@
---
# Cop supports --auto-correct.
Fips/OpenSSL:
Exclude:
- 'app/controllers/application_controller.rb'
- 'app/controllers/concerns/authenticates_with_two_factor.rb'
- 'app/controllers/projects/merge_requests/diffs_controller.rb'
- 'app/controllers/projects/merge_requests_controller.rb'
- 'app/helpers/application_helper.rb'
- 'app/models/ci/artifact_blob.rb'
- 'app/models/concerns/analytics/cycle_analytics/stage.rb'
- 'app/models/concerns/checksummable.rb'
- 'app/models/concerns/token_authenticatable_strategies/encryption_helper.rb'
- 'app/models/diff_discussion.rb'
- 'app/models/discussion.rb'
- 'app/models/legacy_diff_note.rb'
- 'app/models/namespace.rb'
- 'app/models/note.rb'
- 'app/models/performance_monitoring/prometheus_panel.rb'
- 'app/models/protected_branch.rb'
- 'app/models/release_highlight.rb'
- 'app/models/repository.rb'
- 'app/models/resource_event.rb'
- 'app/models/snippet.rb'
- 'app/models/storage/hashed.rb'
- 'app/models/token_with_iv.rb'
- 'app/presenters/packages/composer/packages_presenter.rb'
- 'app/services/ci/build_report_result_service.rb'
- 'app/services/metrics/dashboard/transient_embed_service.rb'
- 'app/services/packages/debian/generate_distribution_service.rb'
- 'app/services/packages/go/create_package_service.rb'
- 'app/services/packages/maven/metadata/append_package_file_service.rb'
- 'app/services/packages/rubygems/create_gemspec_service.rb'
- 'app/services/pages/migrate_legacy_storage_to_deployment_service.rb'
- 'app/services/projects/lfs_pointers/lfs_download_service.rb'
- 'app/uploaders/ci/secure_file_uploader.rb'
- 'config/initializers/doorkeeper_openid_connect.rb'
- 'config/initializers/session_store.rb'
- 'config/settings.rb'
- 'db/post_migrate/20210731132939_backfill_stage_event_hash.rb'
- 'ee/app/models/storage_shard.rb'
- 'ee/app/services/elastic/bookkeeping_shard_service.rb'
- 'ee/app/services/security/track_scan_service.rb'
- 'ee/app/services/vulnerabilities/create_service_base.rb'
- 'ee/app/services/vulnerabilities/manually_create_service.rb'
- 'ee/app/services/vulnerabilities/starboard_vulnerability_create_service.rb'
- 'ee/lib/ee/gitlab/background_migration/populate_latest_pipeline_ids.rb'
- 'ee/lib/ee/gitlab/background_migration/populate_resolved_on_default_branch_column.rb'
- 'ee/lib/ee/gitlab/background_migration/recalculate_vulnerability_finding_signatures_for_findings.rb'
- 'ee/lib/gitlab/analytics/cycle_analytics/stage_events/label_based_stage_event.rb'
- 'ee/lib/gitlab/ci/reports/dependency_list/dependency.rb'
- 'ee/lib/gitlab/ci/reports/security/remediation.rb'
- 'ee/lib/gitlab/geo/replication/blob_downloader.rb'
- 'ee/spec/factories/vulnerabilities/feedback.rb'
- 'ee/spec/factories/vulnerabilities/finding_signatures.rb'
- 'ee/spec/factories/vulnerabilities/remediations.rb'
- 'ee/spec/finders/security/pipeline_vulnerabilities_finder_spec.rb'
- 'ee/spec/lib/ee/gitlab/alert_management/payload/generic_spec.rb'
- 'ee/spec/lib/ee/gitlab/background_migration/populate_uuids_for_security_findings_spec.rb'
- 'ee/spec/lib/ee/gitlab/background_migration/recalculate_vulnerability_finding_signatures_for_findings_spec.rb'
- 'ee/spec/lib/ee/gitlab/background_migration/update_vulnerability_occurrences_location_spec.rb'
- 'ee/spec/lib/gitlab/analytics/cycle_analytics/stage_events/issue_label_added_spec.rb'
- 'ee/spec/lib/gitlab/analytics/cycle_analytics/stage_events/issue_label_removed_spec.rb'
- 'ee/spec/lib/gitlab/analytics/cycle_analytics/stage_events/merge_request_label_added_spec.rb'
- 'ee/spec/lib/gitlab/analytics/cycle_analytics/stage_events/merge_request_label_removed_spec.rb'
- 'ee/spec/lib/gitlab/ci/reports/security/locations/cluster_image_scanning_spec.rb'
- 'ee/spec/lib/gitlab/ci/reports/security/locations/container_scanning_spec.rb'
- 'ee/spec/lib/gitlab/ci/reports/security/locations/dast_spec.rb'
- 'ee/spec/lib/gitlab/ci/reports/security/locations/dependency_scanning_spec.rb'
- 'ee/spec/migrations/update_vulnerability_occurrences_location_spec.rb'
- 'ee/spec/models/merge_train_spec.rb'
- 'ee/spec/models/resource_weight_event_spec.rb'
- 'ee/spec/models/vulnerabilities/finding_signature_spec.rb'
- 'ee/spec/models/vulnerabilities/finding_spec.rb'
- 'ee/spec/services/alert_management/process_prometheus_alert_service_spec.rb'
- 'ee/spec/services/merge_trains/check_status_service_spec.rb'
- 'ee/spec/services/projects/alerting/notify_service_spec.rb'
- 'ee/spec/services/security/ingestion/tasks/ingest_identifiers_spec.rb'
- 'ee/spec/services/security/ingestion/tasks/ingest_remediations_spec.rb'
- 'ee/spec/services/security/override_uuids_service_spec.rb'
- 'ee/spec/services/security/track_scan_service_spec.rb'
- 'ee/spec/services/vulnerabilities/manually_create_service_spec.rb'
- 'ee/spec/support/matchers/locked_schema.rb'
- 'lib/api/files.rb'
- 'lib/api/maven_packages.rb'
- 'lib/atlassian/jira_connect/serializers/branch_entity.rb'
- 'lib/container_registry/client.rb'
- 'lib/extracts_path.rb'
- 'lib/gitlab/alert_management/fingerprint.rb'
- 'lib/gitlab/analytics/cycle_analytics/stage_events/stage_event.rb'
- 'lib/gitlab/background_migration/backfill_note_discussion_id.rb'
- 'lib/gitlab/background_migration/backfill_project_repositories.rb'
- 'lib/gitlab/ci/pipeline/seed/build/cache.rb'
- 'lib/gitlab/ci/reports/security/finding.rb'
- 'lib/gitlab/ci/reports/security/finding_signature.rb'
- 'lib/gitlab/ci/reports/security/identifier.rb'
- 'lib/gitlab/ci/reports/security/locations/base.rb'
- 'lib/gitlab/ci/reports/test_case.rb'
- 'lib/gitlab/color.rb'
- 'lib/gitlab/composer/version_index.rb'
- 'lib/gitlab/crypto_helper.rb'
- 'lib/gitlab/database/migration_helpers.rb'
- 'lib/gitlab/database/migration_helpers/v2.rb'
- 'lib/gitlab/database/partitioning_migration_helpers/foreign_key_helpers.rb'
- 'lib/gitlab/database/schema_helpers.rb'
- 'lib/gitlab/database/schema_migrations/migrations.rb'
- 'lib/gitlab/database/unidirectional_copy_trigger.rb'
- 'lib/gitlab/diff/file.rb'
- 'lib/gitlab/diff/formatters/base_formatter.rb'
- 'lib/gitlab/diff/position.rb'
- 'lib/gitlab/experimentation/controller_concern.rb'
- 'lib/gitlab/git.rb'
- 'lib/gitlab/git/branch.rb'
- 'lib/gitlab/git/lfs_pointer_file.rb'
- 'lib/gitlab/git/tag.rb'
- 'lib/gitlab/hashed_path.rb'
- 'lib/gitlab/insecure_key_fingerprint.rb'
- 'lib/gitlab/sidekiq_middleware/duplicate_jobs/duplicate_job.rb'
- 'lib/gitlab/slug/environment.rb'
- 'lib/gitlab/verify/job_artifacts.rb'
- 'lib/json_web_token/rsa_token.rb'
- 'lib/tasks/gitlab/assets.rake'
- 'lib/tasks/tanuki_emoji.rake'
- 'qa/qa/service/praefect_manager.rb'
- 'qa/qa/specs/features/browser_ui/6_release/deploy_key/clone_using_deploy_key_spec.rb'
- 'qa/qa/specs/features/ee/browser_ui/1_manage/group/group_saml_non_enforced_sso_spec.rb'
- 'scripts/security-harness'
- 'spec/components/diffs/stats_component_spec.rb'
- 'spec/controllers/projects/blob_controller_spec.rb'
- 'spec/factories/ci/job_artifacts.rb'
- 'spec/factories/ci/reports/security/finding_keys.rb'
- 'spec/factories/ci/unit_test.rb'
- 'spec/factories/commit_signature/gpg_signature.rb'
- 'spec/factories/commit_signature/ssh_signature.rb'
- 'spec/factories/commit_signature/x509_commit_signature.rb'
- 'spec/factories/design_management/designs.rb'
- 'spec/factories/diff_position.rb'
- 'spec/factories/gitaly/commit.rb'
- 'spec/factories/merge_request_context_commit.rb'
- 'spec/factories/merge_request_context_commit_diff_file.rb'
- 'spec/factories/merge_request_diff_commits.rb'
- 'spec/factories/merge_request_diffs.rb'
- 'spec/factories/pages_deployments.rb'
- 'spec/factories/sequences.rb'
- 'spec/factories/token_with_ivs.rb'
- 'spec/features/file_uploads/git_lfs_spec.rb'
- 'spec/features/merge_request/user_sees_diff_spec.rb'
- 'spec/features/merge_request/user_suggests_changes_on_diff_spec.rb'
- 'spec/finders/merge_requests/oldest_per_commit_finder_spec.rb'
- 'spec/lib/gitlab/alert_management/fingerprint_spec.rb'
- 'spec/lib/gitlab/alert_management/payload/base_spec.rb'
- 'spec/lib/gitlab/alert_management/payload/generic_spec.rb'
- 'spec/lib/gitlab/alert_management/payload/prometheus_spec.rb'
- 'spec/lib/gitlab/background_migration/backfill_note_discussion_id_spec.rb'
- 'spec/lib/gitlab/background_migration/populate_vulnerability_reads_spec.rb'
- 'spec/lib/gitlab/ci/reports/security/finding_signature_spec.rb'
- 'spec/lib/gitlab/ci/reports/security/locations/sast_spec.rb'
- 'spec/lib/gitlab/ci/reports/security/locations/secret_detection_spec.rb'
- 'spec/lib/gitlab/ci/reports/test_case_spec.rb'
- 'spec/lib/gitlab/crypto_helper_spec.rb'
- 'spec/lib/gitlab/database/migration_helpers_spec.rb'
- 'spec/lib/gitlab/database/schema_migrations/migrations_spec.rb'
- 'spec/lib/gitlab/diff/file_spec.rb'
- 'spec/lib/gitlab/diff/position_spec.rb'
- 'spec/lib/gitlab/diff/position_tracer/image_strategy_spec.rb'
- 'spec/lib/gitlab/diff/position_tracer/line_strategy_spec.rb'
- 'spec/lib/gitlab/experimentation/controller_concern_spec.rb'
- 'spec/lib/gitlab/git/branch_spec.rb'
- 'spec/lib/gitlab/git/tag_spec.rb'
- 'spec/lib/gitlab/sidekiq_middleware/duplicate_jobs/duplicate_job_spec.rb'
- 'spec/lib/gitlab/slug/environment_spec.rb'
- 'spec/migrations/20220107064845_populate_vulnerability_reads_spec.rb'
- 'spec/migrations/20220524074947_finalize_backfill_null_note_discussion_ids_spec.rb'
- 'spec/migrations/delete_security_findings_without_uuid_spec.rb'
- 'spec/migrations/schedule_recalculate_vulnerability_finding_signatures_for_findings_spec.rb'
- 'spec/models/ci/artifact_blob_spec.rb'
- 'spec/models/ci/job_artifact_spec.rb'
- 'spec/models/ci/pipeline_spec.rb'
- 'spec/models/ci/secure_file_spec.rb'
- 'spec/models/ci/unit_test_spec.rb'
- 'spec/models/concerns/checksummable_spec.rb'
- 'spec/models/concerns/token_authenticatable_strategies/encryption_helper_spec.rb'
- 'spec/models/design_management/version_spec.rb'
- 'spec/models/diff_discussion_spec.rb'
- 'spec/models/discussion_spec.rb'
- 'spec/models/lfs_object_spec.rb'
- 'spec/models/merge_request_diff_spec.rb'
- 'spec/models/merge_request_spec.rb'
- 'spec/models/note_spec.rb'
- 'spec/models/pages_deployment_spec.rb'
- 'spec/models/performance_monitoring/prometheus_panel_spec.rb'
- 'spec/models/project_spec.rb'
- 'spec/models/release_highlight_spec.rb'
- 'spec/models/repository_spec.rb'
- 'spec/models/token_with_iv_spec.rb'
- 'spec/models/upload_spec.rb'
- 'spec/requests/api/ci/runner/jobs_artifacts_spec.rb'
- 'spec/requests/api/ci/secure_files_spec.rb'
- 'spec/requests/openid_connect_spec.rb'
- 'spec/services/dependency_proxy/find_cached_manifest_service_spec.rb'
- 'spec/services/dependency_proxy/head_manifest_service_spec.rb'
- 'spec/services/dependency_proxy/request_token_service_spec.rb'
- 'spec/services/import_export_clean_up_service_spec.rb'
- 'spec/services/pages/migrate_legacy_storage_to_deployment_service_spec.rb'
- 'spec/services/projects/after_rename_service_spec.rb'
- 'spec/services/projects/create_service_spec.rb'
- 'spec/services/projects/lfs_pointers/lfs_download_service_spec.rb'
- 'spec/support/helpers/workhorse_helpers.rb'
- 'spec/support/migrations_helpers/vulnerabilities_findings_helper.rb'
- 'spec/support/shared_examples/lib/gitlab/ci/ci_trace_shared_examples.rb'
- 'spec/support/shared_examples/lib/gitlab/cycle_analytics/event_shared_examples.rb'
- 'spec/support/shared_examples/lib/gitlab/position_formatters_shared_examples.rb'
- 'spec/support/shared_examples/services/alert_management/alert_processing/alert_firing_shared_examples.rb'
- 'spec/support/shared_examples/services/alert_management/alert_processing/alert_recovery_shared_examples.rb'
- 'spec/support/shared_examples/services/metrics/dashboard_shared_examples.rb'
- 'spec/support/shared_examples/services/packages/debian/generate_distribution_shared_examples.rb'
- 'spec/support/shared_examples/uploaders/object_storage_shared_examples.rb'
- 'spec/support/trace/trace_helpers.rb'
- 'spec/uploaders/ci/secure_file_uploader_spec.rb'
- 'spec/uploaders/job_artifact_uploader_spec.rb'
- 'spec/validators/sha_validator_spec.rb'
- 'spec/workers/update_head_pipeline_for_merge_request_worker_spec.rb'

111
.rubocop_todo/fips/sha1.yml Normal file
View File

@ -0,0 +1,111 @@
---
Fips/SHA1:
Exclude:
- 'app/controllers/application_controller.rb'
- 'app/helpers/application_helper.rb'
- 'app/models/ci/artifact_blob.rb'
- 'app/models/diff_discussion.rb'
- 'app/models/discussion.rb'
- 'app/models/legacy_diff_note.rb'
- 'app/models/note.rb'
- 'app/models/protected_branch.rb'
- 'app/models/repository.rb'
- 'app/models/resource_event.rb'
- 'app/services/packages/go/create_package_service.rb'
- 'app/services/packages/maven/metadata/append_package_file_service.rb'
- 'app/services/packages/rubygems/create_gemspec_service.rb'
- 'ee/app/models/storage_shard.rb'
- 'ee/app/services/vulnerabilities/create_service_base.rb'
- 'ee/app/services/vulnerabilities/manually_create_service.rb'
- 'ee/app/services/vulnerabilities/starboard_vulnerability_create_service.rb'
- 'ee/lib/ee/gitlab/background_migration/recalculate_vulnerability_finding_signatures_for_findings.rb'
- 'ee/spec/factories/vulnerabilities/feedback.rb'
- 'ee/spec/factories/vulnerabilities/finding_signatures.rb'
- 'ee/spec/finders/security/pipeline_vulnerabilities_finder_spec.rb'
- 'ee/spec/lib/ee/gitlab/alert_management/payload/generic_spec.rb'
- 'ee/spec/lib/ee/gitlab/background_migration/populate_uuids_for_security_findings_spec.rb'
- 'ee/spec/lib/ee/gitlab/background_migration/recalculate_vulnerability_finding_signatures_for_findings_spec.rb'
- 'ee/spec/lib/ee/gitlab/background_migration/update_vulnerability_occurrences_location_spec.rb'
- 'ee/spec/lib/gitlab/ci/reports/security/locations/cluster_image_scanning_spec.rb'
- 'ee/spec/lib/gitlab/ci/reports/security/locations/container_scanning_spec.rb'
- 'ee/spec/lib/gitlab/ci/reports/security/locations/dast_spec.rb'
- 'ee/spec/lib/gitlab/ci/reports/security/locations/dependency_scanning_spec.rb'
- 'ee/spec/migrations/update_vulnerability_occurrences_location_spec.rb'
- 'ee/spec/models/merge_train_spec.rb'
- 'ee/spec/models/resource_weight_event_spec.rb'
- 'ee/spec/models/vulnerabilities/finding_signature_spec.rb'
- 'ee/spec/models/vulnerabilities/finding_spec.rb'
- 'ee/spec/services/alert_management/process_prometheus_alert_service_spec.rb'
- 'ee/spec/services/merge_trains/check_status_service_spec.rb'
- 'ee/spec/services/projects/alerting/notify_service_spec.rb'
- 'ee/spec/services/security/ingestion/tasks/ingest_identifiers_spec.rb'
- 'ee/spec/services/security/override_uuids_service_spec.rb'
- 'ee/spec/services/vulnerabilities/manually_create_service_spec.rb'
- 'lib/extracts_path.rb'
- 'lib/gitlab/alert_management/fingerprint.rb'
- 'lib/gitlab/background_migration/backfill_note_discussion_id.rb'
- 'lib/gitlab/ci/pipeline/seed/build/cache.rb'
- 'lib/gitlab/ci/reports/security/finding.rb'
- 'lib/gitlab/ci/reports/security/finding_signature.rb'
- 'lib/gitlab/ci/reports/security/identifier.rb'
- 'lib/gitlab/ci/reports/security/locations/base.rb'
- 'lib/gitlab/diff/file.rb'
- 'lib/gitlab/diff/formatters/base_formatter.rb'
- 'lib/gitlab/diff/position.rb'
- 'lib/gitlab/git.rb'
- 'lib/gitlab/git/branch.rb'
- 'lib/gitlab/git/tag.rb'
- 'qa/qa/specs/features/browser_ui/6_release/deploy_key/clone_using_deploy_key_spec.rb'
- 'qa/qa/specs/features/ee/browser_ui/1_manage/group/group_saml_non_enforced_sso_spec.rb'
- 'spec/components/diffs/stats_component_spec.rb'
- 'spec/controllers/projects/blob_controller_spec.rb'
- 'spec/factories/ci/reports/security/finding_keys.rb'
- 'spec/factories/commit_signature/gpg_signature.rb'
- 'spec/factories/commit_signature/ssh_signature.rb'
- 'spec/factories/commit_signature/x509_commit_signature.rb'
- 'spec/factories/design_management/designs.rb'
- 'spec/factories/diff_position.rb'
- 'spec/factories/gitaly/commit.rb'
- 'spec/factories/merge_request_context_commit.rb'
- 'spec/factories/merge_request_context_commit_diff_file.rb'
- 'spec/factories/merge_request_diff_commits.rb'
- 'spec/factories/merge_request_diffs.rb'
- 'spec/factories/sequences.rb'
- 'spec/features/merge_request/user_sees_diff_spec.rb'
- 'spec/features/merge_request/user_suggests_changes_on_diff_spec.rb'
- 'spec/finders/merge_requests/oldest_per_commit_finder_spec.rb'
- 'spec/lib/gitlab/alert_management/fingerprint_spec.rb'
- 'spec/lib/gitlab/alert_management/payload/base_spec.rb'
- 'spec/lib/gitlab/alert_management/payload/generic_spec.rb'
- 'spec/lib/gitlab/alert_management/payload/prometheus_spec.rb'
- 'spec/lib/gitlab/background_migration/backfill_note_discussion_id_spec.rb'
- 'spec/lib/gitlab/background_migration/populate_vulnerability_reads_spec.rb'
- 'spec/lib/gitlab/ci/reports/security/finding_signature_spec.rb'
- 'spec/lib/gitlab/ci/reports/security/locations/sast_spec.rb'
- 'spec/lib/gitlab/ci/reports/security/locations/secret_detection_spec.rb'
- 'spec/lib/gitlab/diff/file_spec.rb'
- 'spec/lib/gitlab/diff/position_spec.rb'
- 'spec/lib/gitlab/diff/position_tracer/image_strategy_spec.rb'
- 'spec/lib/gitlab/diff/position_tracer/line_strategy_spec.rb'
- 'spec/lib/gitlab/git/branch_spec.rb'
- 'spec/lib/gitlab/git/tag_spec.rb'
- 'spec/migrations/20220107064845_populate_vulnerability_reads_spec.rb'
- 'spec/migrations/20220524074947_finalize_backfill_null_note_discussion_ids_spec.rb'
- 'spec/migrations/delete_security_findings_without_uuid_spec.rb'
- 'spec/migrations/schedule_recalculate_vulnerability_finding_signatures_for_findings_spec.rb'
- 'spec/models/ci/artifact_blob_spec.rb'
- 'spec/models/ci/job_artifact_spec.rb'
- 'spec/models/ci/pipeline_spec.rb'
- 'spec/models/design_management/version_spec.rb'
- 'spec/models/diff_discussion_spec.rb'
- 'spec/models/discussion_spec.rb'
- 'spec/models/merge_request_diff_spec.rb'
- 'spec/models/merge_request_spec.rb'
- 'spec/models/note_spec.rb'
- 'spec/models/repository_spec.rb'
- 'spec/support/migrations_helpers/vulnerabilities_findings_helper.rb'
- 'spec/support/shared_examples/lib/gitlab/position_formatters_shared_examples.rb'
- 'spec/support/shared_examples/services/alert_management/alert_processing/alert_firing_shared_examples.rb'
- 'spec/support/shared_examples/services/alert_management/alert_processing/alert_recovery_shared_examples.rb'
- 'spec/validators/sha_validator_spec.rb'
- 'spec/workers/update_head_pipeline_for_merge_request_worker_spec.rb'

View File

@ -381,7 +381,7 @@ group :development, :test do
gem 'spring', '~> 2.1.0'
gem 'spring-commands-rspec', '~> 1.0.4'
gem 'gitlab-styles', '~> 7.0.0', require: false
gem 'gitlab-styles', '~> 7.1.0', require: false
gem 'haml_lint', '~> 0.36.0', require: false
gem 'bundler-audit', '~> 0.7.0.1', require: false
@ -407,7 +407,7 @@ group :development, :test do
end
group :development, :test, :danger do
gem 'gitlab-dangerfiles', '~> 3.0', require: false
gem 'gitlab-dangerfiles', '~> 3.1.0', require: false
end
group :development, :test, :coverage do

View File

@ -224,7 +224,7 @@ GEM
css_parser (1.11.0)
addressable
daemons (1.3.1)
danger (8.5.0)
danger (8.6.1)
claide (~> 1.0)
claide-plugins (>= 0.9.2)
colored2 (~> 3.1)
@ -474,7 +474,7 @@ GEM
terminal-table (~> 1.5, >= 1.5.1)
gitlab-chronic (0.10.5)
numerizer (~> 0.2)
gitlab-dangerfiles (3.0.0)
gitlab-dangerfiles (3.1.0)
danger (>= 8.4.5)
danger-gitlab (>= 8.0.0)
rake
@ -513,7 +513,7 @@ GEM
openid_connect (~> 1.2)
gitlab-sidekiq-fetcher (0.8.0)
sidekiq (~> 6.1)
gitlab-styles (7.0.0)
gitlab-styles (7.1.0)
rubocop (~> 0.91, >= 0.91.1)
rubocop-gitlab-security (~> 0.1.1)
rubocop-graphql (~> 0.10)
@ -939,7 +939,7 @@ GEM
randexp (~> 0.1.7)
rspec (>= 2.14)
term-ansicolor (~> 1.0)
parallel (1.20.1)
parallel (1.22.1)
parser (3.1.2.0)
ast (~> 2.4.1)
parslet (1.8.2)
@ -1038,7 +1038,7 @@ GEM
method_source
rake (>= 0.13)
thor (~> 1.0)
rainbow (3.0.0)
rainbow (3.1.1)
rake (13.0.6)
randexp (0.1.7)
rb-fsevent (0.10.4)
@ -1067,7 +1067,7 @@ GEM
redis-store (>= 1.2, < 2)
redis-store (1.9.0)
redis (>= 4, < 5)
regexp_parser (2.2.1)
regexp_parser (2.5.0)
regexp_property_values (1.0.0)
representable (3.0.4)
declarative (< 0.1.0)
@ -1144,11 +1144,11 @@ GEM
rubocop-ast (>= 0.6.0)
ruby-progressbar (~> 1.7)
unicode-display_width (>= 1.4.0, < 2.0)
rubocop-ast (1.4.1)
parser (>= 2.7.1.5)
rubocop-ast (1.18.0)
parser (>= 3.1.1.0)
rubocop-gitlab-security (0.1.1)
rubocop (>= 0.51)
rubocop-graphql (0.13.0)
rubocop-graphql (0.14.3)
rubocop (>= 0.87, < 2)
rubocop-performance (1.9.2)
rubocop (>= 0.90.0, < 2.0)
@ -1378,7 +1378,7 @@ GEM
unf (0.1.4)
unf_ext
unf_ext (0.0.8)
unicode-display_width (1.7.0)
unicode-display_width (1.8.0)
unicode_utils (1.4.0)
uniform_notifier (1.13.0)
unleash (3.2.2)
@ -1532,7 +1532,7 @@ DEPENDENCIES
gitaly (~> 15.0.0.pre.rc3)
github-markup (~> 1.7.0)
gitlab-chronic (~> 0.10.5)
gitlab-dangerfiles (~> 3.0)
gitlab-dangerfiles (~> 3.1.0)
gitlab-experiment (~> 0.7.1)
gitlab-fog-azure-rm (~> 1.3.0)
gitlab-labkit (~> 0.22.0)
@ -1543,7 +1543,7 @@ DEPENDENCIES
gitlab-net-dns (~> 0.9.1)
gitlab-omniauth-openid-connect (~> 0.9.0)
gitlab-sidekiq-fetcher (= 0.8.0)
gitlab-styles (~> 7.0.0)
gitlab-styles (~> 7.1.0)
gitlab_chronic_duration (~> 0.10.6.2)
gitlab_omniauth-ldap (~> 2.1.1)
gon (~> 6.4.0)

View File

@ -75,6 +75,7 @@ export default class SourceEditor {
blobGlobalId,
instance,
isDiff,
language,
} = {}) {
if (!instance) {
return null;
@ -82,7 +83,7 @@ export default class SourceEditor {
const uriFilePath = joinPaths(URI_PREFIX, blobGlobalId, blobPath);
const uri = Uri.file(uriFilePath);
const existingModel = monacoEditor.getModel(uri);
const model = existingModel || monacoEditor.createModel(blobContent, undefined, uri);
const model = existingModel || monacoEditor.createModel(blobContent, language, uri);
if (!isDiff) {
instance.setModel(model);
return model;
@ -132,6 +133,7 @@ export default class SourceEditor {
});
let model;
const language = instanceOptions.language || getBlobLanguage(blobPath);
if (instanceOptions.model !== null) {
model = SourceEditor.createEditorModel({
blobGlobalId,
@ -140,6 +142,7 @@ export default class SourceEditor {
blobContent,
instance,
isDiff,
language,
});
}

View File

@ -1,19 +1,26 @@
<script>
import { GlLoadingIcon, GlModal } from '@gitlab/ui';
import createFlash from '~/flash';
import { HIDDEN_CLASS } from '~/lib/utils/constants';
import { mergeUrlParams, getParameterByName } from '~/lib/utils/url_utility';
import { HIDDEN_CLASS } from '~/lib/utils/constants';
import { __, s__, sprintf } from '~/locale';
import { COMMON_STR, CONTENT_LIST_CLASS } from '../constants';
import eventHub from '../event_hub';
import groupsComponent from './groups.vue';
import GroupsComponent from './groups.vue';
import EmptyState from './empty_state.vue';
export default {
components: {
groupsComponent,
GroupsComponent,
GlModal,
GlLoadingIcon,
EmptyState,
},
inject: {
renderEmptyState: {
default: false,
},
},
props: {
action: {
@ -47,6 +54,7 @@ export default {
searchEmptyMessage: '',
targetGroup: null,
targetParentGroup: null,
showEmptyState: false,
};
},
computed: {
@ -75,6 +83,9 @@ export default {
pageInfo() {
return this.store.getPaginationInfo();
},
filterGroupsBy() {
return getParameterByName('filter') || null;
},
},
created() {
this.searchEmptyMessage = this.hideProjects
@ -128,19 +139,18 @@ export default {
const page = getParameterByName('page') || null;
const sortBy = getParameterByName('sort') || null;
const archived = getParameterByName('archived') || null;
const filterGroupsBy = getParameterByName('filter') || null;
this.isLoading = true;
return this.fetchGroups({
page,
filterGroupsBy,
filterGroupsBy: this.filterGroupsBy,
sortBy,
archived,
updatePagination: true,
}).then((res) => {
this.isLoading = false;
this.updateGroups(res, Boolean(filterGroupsBy));
this.updateGroups(res, Boolean(this.filterGroupsBy));
});
},
fetchPage({ page, filterGroupsBy, sortBy, archived }) {
@ -212,7 +222,7 @@ export default {
this.targetGroup.isBeingRemoved = false;
});
},
showEmptyState() {
showLegacyEmptyState() {
const { containerEl } = this;
const contentListEl = containerEl.querySelector(CONTENT_LIST_CLASS);
const emptyStateEl = containerEl.querySelector('.empty-state');
@ -230,7 +240,12 @@ export default {
},
updateGroups(groups, fromSearch) {
const hasGroups = groups && groups.length > 0;
this.isSearchEmpty = !hasGroups;
if (this.renderEmptyState) {
this.isSearchEmpty = this.filterGroupsBy !== null && !hasGroups;
} else {
this.isSearchEmpty = !hasGroups;
}
if (fromSearch) {
this.store.setSearchedGroups(groups);
@ -239,7 +254,11 @@ export default {
}
if (this.action && !hasGroups && !fromSearch) {
this.showEmptyState();
if (this.renderEmptyState) {
this.showEmptyState = true;
} else {
this.showLegacyEmptyState();
}
}
},
},
@ -262,6 +281,7 @@ export default {
:page-info="pageInfo"
:action="action"
/>
<empty-state v-if="showEmptyState" />
<gl-modal
modal-id="leave-group-modal"
:visible="isModalVisible"

View File

@ -0,0 +1,91 @@
<script>
import { GlLink, GlEmptyState } from '@gitlab/ui';
import { s__ } from '~/locale';
export default {
components: { GlLink, GlEmptyState },
i18n: {
withLinks: {
subgroup: {
title: s__('GroupsEmptyState|Create new subgroup'),
description: s__(
'GroupsEmptyState|Groups are the best way to manage multiple projects and members.',
),
},
project: {
title: s__('GroupsEmptyState|Create new project'),
description: s__(
'GroupsEmptyState|Projects are where you can store your code, access issues, wiki, and other features of Gitlab.',
),
},
},
withoutLinks: {
title: s__('GroupsEmptyState|No subgroups or projects.'),
description: s__(
'GroupsEmptyState|You do not have necessary permissions to create a subgroup or project in this group. Please contact an owner of this group to create a new subgroup or project.',
),
},
},
linkClasses: [
'gl-border',
'gl-text-decoration-none!',
'gl-rounded-base',
'gl-p-7',
'gl-display-flex',
'gl-h-full',
'gl-align-items-center',
'gl-text-purple-600',
'gl-hover-bg-gray-50',
],
inject: [
'newSubgroupPath',
'newProjectPath',
'newSubgroupIllustration',
'newProjectIllustration',
'emptySubgroupIllustration',
'canCreateSubgroups',
'canCreateProjects',
],
};
</script>
<template>
<div v-if="canCreateSubgroups || canCreateProjects" class="gl-mt-5">
<div class="gl-display-flex gl-mx-n3 gl-my-n3 gl-flex-wrap">
<div v-if="canCreateSubgroups" class="gl-p-3 gl-w-full gl-sm-w-half">
<gl-link :href="newSubgroupPath" :class="$options.linkClasses">
<div class="svg-content gl-w-15 gl-flex-shrink-0 gl-mr-5">
<img :src="newSubgroupIllustration" :alt="$options.i18n.withLinks.subgroup.title" />
</div>
<div>
<h4 class="gl-reset-color">{{ $options.i18n.withLinks.subgroup.title }}</h4>
<p class="gl-text-body">
{{ $options.i18n.withLinks.subgroup.description }}
</p>
</div>
</gl-link>
</div>
<div v-if="canCreateProjects" class="gl-p-3 gl-w-full gl-sm-w-half">
<gl-link :href="newProjectPath" :class="$options.linkClasses">
<div class="svg-content gl-w-13 gl-flex-shrink-0 gl-mr-5">
<img :src="newProjectIllustration" :alt="$options.i18n.withLinks.project.title" />
</div>
<div>
<h4 class="gl-reset-color">{{ $options.i18n.withLinks.project.title }}</h4>
<p class="gl-text-body">
{{ $options.i18n.withLinks.project.description }}
</p>
</div>
</gl-link>
</div>
</div>
</div>
<gl-empty-state
v-else
class="gl-mt-5"
:title="$options.i18n.withoutLinks.title"
:svg-path="emptySubgroupIllustration"
:description="$options.i18n.withoutLinks.description"
/>
</template>

View File

@ -44,6 +44,31 @@ export default (containerId = 'js-groups-tree', endpoint, action = '') => {
components: {
groupsApp,
},
provide() {
const {
dataset: {
newSubgroupPath,
newProjectPath,
newSubgroupIllustration,
newProjectIllustration,
emptySubgroupIllustration,
renderEmptyState,
canCreateSubgroups,
canCreateProjects,
},
} = this.$options.el;
return {
newSubgroupPath,
newProjectPath,
newSubgroupIllustration,
newProjectIllustration,
emptySubgroupIllustration,
renderEmptyState: parseBoolean(renderEmptyState),
canCreateSubgroups: parseBoolean(canCreateSubgroups),
canCreateProjects: parseBoolean(canCreateProjects),
};
},
data() {
const { dataset } = dataEl || this.$options.el;
const hideProjects = parseBoolean(dataset.hideProjects);

View File

@ -153,6 +153,20 @@ module GroupsHelper
}
end
def subgroups_and_projects_list_app_data(group)
{
show_schema_markup: 'true',
new_subgroup_path: new_group_path(parent_id: group.id),
new_project_path: new_project_path(namespace_id: group.id),
new_subgroup_illustration: image_path('illustrations/subgroup-create-new-sm.svg'),
new_project_illustration: image_path('illustrations/project-create-new-sm.svg'),
empty_subgroup_illustration: image_path('illustrations/empty-state/empty-subgroup-md.svg'),
render_empty_state: 'true',
can_create_subgroups: can?(current_user, :create_subgroup, group).to_s,
can_create_projects: can?(current_user, :create_projects, group).to_s
}
end
private
def group_title_link(group, hidable: false, show_avatar: false, for_dropdown: false)

View File

@ -1963,6 +1963,10 @@ class MergeRequest < ApplicationRecord
end
end
def target_default_branch?
target_branch == project.default_branch
end
private
attr_accessor :skip_fetch_ref

View File

@ -1,7 +1,4 @@
#js-groups-subgroups_and_projects-tree
.empty-state.hidden
= render "shared/groups/empty_state"
%section{ data: { hide_projects: 'false', group_id: group.id, path: group_path(group) } }
.js-groups-list-holder{ data: { show_schema_markup: 'true'} }
.js-groups-list-holder{ data: subgroups_and_projects_list_app_data(group) }
= gl_loading_icon(size: 'md', css_class: 'gl-mt-6')

View File

@ -0,0 +1,30 @@
# frozen_string_literal: true
class AddVulnerabilityRelatedColumns < Gitlab::Database::Migration[2.0]
def change
add_column :approval_merge_request_rules,
:vulnerabilities_allowed,
:integer,
limit: 2,
null: false,
default: 0
add_column :approval_merge_request_rules,
:scanners,
:text,
array: true,
null: false,
default: []
add_column :approval_merge_request_rules,
:severity_levels,
:text,
array: true,
null: false,
default: []
add_column :approval_merge_request_rules,
:vulnerability_states,
:text,
array: true,
null: false,
default: ['newly_detected']
end
end

View File

@ -0,0 +1 @@
5012f2becb04485a67df5fa0acdf7c73a9410368493256f4774af297de5f86e8

View File

@ -11419,6 +11419,10 @@ CREATE TABLE approval_merge_request_rules (
section text,
modified_from_project_rule boolean DEFAULT false NOT NULL,
orchestration_policy_idx smallint,
vulnerabilities_allowed smallint DEFAULT 0 NOT NULL,
scanners text[] DEFAULT '{}'::text[] NOT NULL,
severity_levels text[] DEFAULT '{}'::text[] NOT NULL,
vulnerability_states text[] DEFAULT '{newly_detected}'::text[] NOT NULL,
CONSTRAINT check_6fca5928b2 CHECK ((char_length(section) <= 255))
);

View File

@ -198,7 +198,7 @@ Secret Detection can be customized by defining available CI/CD variables:
| `SECRET_DETECTION_EXCLUDED_PATHS` | "" | Exclude vulnerabilities from output based on the paths. This is a comma-separated list of patterns. Patterns can be globs, or file or folder paths (for example, `doc,spec` ). Parent directories also match patterns. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/225273) in GitLab 13.3. |
| `SECRET_DETECTION_HISTORIC_SCAN` | false | Flag to enable a historic Gitleaks scan. |
| `SECRET_DETECTION_IMAGE_SUFFIX` | "" | Suffix added to the image name. If set to `-fips`, `FIPS-enabled` images are used for scan. See [FIPS-enabled images](#fips-enabled-images) for more details. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/355519) in GitLab 14.10. |
| `SECRET_DETECTION_LOG_OPTS` | "" | [`git log`](https://git-scm.com/docs/git-log) options used to define commit ranges. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/350660) in GitLab 15.1.|
| `SECRET_DETECTION_LOG_OPTIONS` | "" | [`git log`](https://git-scm.com/docs/git-log) options used to define commit ranges. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/350660) in GitLab 15.1.|
In previous GitLab versions, the following variables were also available:

View File

@ -419,8 +419,13 @@ A new token is generated.
When you sign in to the main GitLab application, a `_gitlab_session` cookie is
set. When you close your browser, the cookie is cleared client-side
and it expires after "Application settings > Session duration (minutes)"/`session_expire_delay`
(defaults to `10080` minutes = 7 days) of no activity.
and it expires after a set duration. GitLab administrators can determine the duration:
1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Settings > General**.
1. Expand **Account and limit**. The set duration is in **Session duration (minutes)**.
The default is `10080`, which equals 7 days.
When you sign in to the main GitLab application, you can also check the
**Remember me** option. This sets the `remember_user_token`

View File

@ -18414,15 +18414,33 @@ msgstr ""
msgid "GroupsEmptyState|A group is a collection of several projects."
msgstr ""
msgid "GroupsEmptyState|Create new project"
msgstr ""
msgid "GroupsEmptyState|Create new subgroup"
msgstr ""
msgid "GroupsEmptyState|Groups are the best way to manage multiple projects and members."
msgstr ""
msgid "GroupsEmptyState|If you organize your projects under a group, it works like a folder."
msgstr ""
msgid "GroupsEmptyState|No groups found"
msgstr ""
msgid "GroupsEmptyState|No subgroups or projects."
msgstr ""
msgid "GroupsEmptyState|Projects are where you can store your code, access issues, wiki, and other features of Gitlab."
msgstr ""
msgid "GroupsEmptyState|You can manage your group members permissions and access to each project in the group."
msgstr ""
msgid "GroupsEmptyState|You do not have necessary permissions to create a subgroup or project in this group. Please contact an owner of this group to create a new subgroup or project."
msgstr ""
msgid "GroupsNew|%{linkStart}Groups%{linkEnd} allow you to manage and collaborate across multiple projects. Members of a group have access to all of its projects."
msgstr ""

View File

@ -72,6 +72,58 @@ RSpec.describe 'Group show page' do
end
end
end
context 'subgroups and projects empty state', :js do
context 'when user has permissions to create new subgroups or projects' do
before do
group.add_owner(user)
sign_in(user)
visit path
end
it 'shows `Create new subgroup` link' do
expect(page).to have_link(
s_('GroupsEmptyState|Create new subgroup'),
href: new_group_path(parent_id: group.id)
)
end
it 'shows `Create new project` link' do
expect(page).to have_link(
s_('GroupsEmptyState|Create new project'),
href: new_project_path(namespace_id: group.id)
)
end
end
end
context 'when user does not have permissions to create new subgroups or projects', :js do
before do
group.add_reporter(user)
sign_in(user)
visit path
end
it 'does not show `Create new subgroup` link' do
expect(page).not_to have_link(
s_('GroupsEmptyState|Create new subgroup'),
href: new_group_path(parent_id: group.id)
)
end
it 'does not show `Create new project` link' do
expect(page).not_to have_link(
s_('GroupsEmptyState|Create new project'),
href: new_project_path(namespace_id: group.id)
)
end
it 'shows empty state' do
expect(page).to have_content(s_('GroupsEmptyState|No subgroups or projects.'))
expect(page).to have_content(s_('GroupsEmptyState|You do not have necessary permissions to create a subgroup' \
' or project in this group. Please contact an owner of this group to create a new subgroup or project.'))
end
end
end
context 'when signed out' do

View File

@ -92,7 +92,7 @@ describe('Base editor', () => {
expect(monacoEditor.createModel).toHaveBeenCalledWith(
blobContent,
undefined,
'markdown',
expect.objectContaining({
path: uriFilePath,
}),
@ -117,7 +117,7 @@ describe('Base editor', () => {
expect(modelSpy).toHaveBeenCalledWith(
blobContent,
undefined,
'markdown',
expect.objectContaining({
path: uriFilePath,
}),
@ -177,6 +177,29 @@ describe('Base editor', () => {
expect(layoutSpy).toHaveBeenCalled();
});
it.each`
params | expectedLanguage
${{}} | ${'markdown'}
${{ blobPath: undefined }} | ${'plaintext'}
${{ blobPath: undefined, language: 'ruby' }} | ${'ruby'}
${{ language: 'go' }} | ${'go'}
${{ blobPath: undefined, language: undefined }} | ${'plaintext'}
`(
'correctly sets $expectedLanguage on the model when $params are passed',
({ params, expectedLanguage }) => {
jest.spyOn(monacoEditor, 'createModel');
editor.createInstance({
...defaultArguments,
...params,
});
expect(monacoEditor.createModel).toHaveBeenCalledWith(
expect.anything(),
expectedLanguage,
expect.anything(),
);
},
);
});
describe('instance of the Diff Editor', () => {
@ -210,7 +233,7 @@ describe('Base editor', () => {
expect(modelSpy).toHaveBeenCalledTimes(2);
expect(modelSpy.mock.calls[0]).toEqual([
blobContent,
undefined,
'markdown',
expect.objectContaining({
path: uriFilePath,
}),

View File

@ -10,8 +10,10 @@ import groupItemComponent from '~/groups/components/group_item.vue';
import eventHub from '~/groups/event_hub';
import GroupsService from '~/groups/service/groups_service';
import GroupsStore from '~/groups/store/groups_store';
import EmptyState from '~/groups/components/empty_state.vue';
import axios from '~/lib/utils/axios_utils';
import * as urlUtilities from '~/lib/utils/url_utility';
import setWindowLocation from 'helpers/set_window_location_helper';
import {
mockEndpoint,
@ -38,17 +40,23 @@ describe('AppComponent', () => {
const store = new GroupsStore({ hideProjects: false });
const service = new GroupsService(mockEndpoint);
const createShallowComponent = (hideProjects = false) => {
const createShallowComponent = ({ propsData = {}, provide = {} } = {}) => {
store.state.pageInfo = mockPageInfo;
wrapper = shallowMount(appComponent, {
propsData: {
store,
service,
hideProjects,
hideProjects: false,
containerId: 'js-groups-tree',
...propsData,
},
mocks: {
$toast,
},
provide: {
renderEmptyState: false,
...provide,
},
});
vm = wrapper.vm;
};
@ -64,6 +72,14 @@ describe('AppComponent', () => {
Vue.component('GroupFolder', groupFolderComponent);
Vue.component('GroupItem', groupItemComponent);
document.body.innerHTML = `
<div id="js-groups-tree">
<div class="empty-state hidden" data-testid="legacy-empty-state">
<p>There are no projects shared with this group yet</p>
</div>
</div>
`;
createShallowComponent();
getGroupsSpy = jest.spyOn(vm.service, 'getGroups');
await nextTick();
@ -386,7 +402,10 @@ describe('AppComponent', () => {
expect(vm.store.setSearchedGroups).toHaveBeenCalledWith(mockGroups);
});
it('should set `isSearchEmpty` prop based on groups count', () => {
it('should set `isSearchEmpty` prop based on groups count and `filter` query param', () => {
setWindowLocation('?filter=foobar');
createShallowComponent();
vm.updateGroups(mockGroups);
expect(vm.isSearchEmpty).toBe(false);
@ -395,6 +414,47 @@ describe('AppComponent', () => {
expect(vm.isSearchEmpty).toBe(true);
});
describe.each`
action | groups | fromSearch | renderEmptyState | expected
${'subgroups_and_projects'} | ${[]} | ${false} | ${true} | ${true}
${''} | ${[]} | ${false} | ${true} | ${false}
${'subgroups_and_projects'} | ${mockGroups} | ${false} | ${true} | ${false}
${'subgroups_and_projects'} | ${[]} | ${true} | ${true} | ${false}
`(
'when `action` is $action, `groups` is $groups, `fromSearch` is $fromSearch, and `renderEmptyState` is $renderEmptyState',
({ action, groups, fromSearch, renderEmptyState, expected }) => {
it(expected ? 'renders empty state' : 'does not render empty state', async () => {
createShallowComponent({
propsData: { action },
provide: { renderEmptyState },
});
vm.updateGroups(groups, fromSearch);
await nextTick();
expect(wrapper.findComponent(EmptyState).exists()).toBe(expected);
});
},
);
});
describe('when `action` is subgroups_and_projects, `groups` is [], `fromSearch` is `false`, and `renderEmptyState` is `false`', () => {
it('renders legacy empty state', async () => {
createShallowComponent({
propsData: { action: 'subgroups_and_projects' },
provide: { renderEmptyState: false },
});
vm.updateGroups([], false);
await nextTick();
expect(
document.querySelector('[data-testid="legacy-empty-state"]').classList.contains('hidden'),
).toBe(false);
});
});
});
@ -419,7 +479,7 @@ describe('AppComponent', () => {
});
it('should initialize `searchEmptyMessage` prop with correct string when `hideProjects` is `true`', async () => {
createShallowComponent(true);
createShallowComponent({ propsData: { hideProjects: true } });
await nextTick();
expect(vm.searchEmptyMessage).toBe('No groups matched your search');
});

View File

@ -0,0 +1,78 @@
import { GlEmptyState } from '@gitlab/ui';
import { mountExtended } from 'jest/__helpers__/vue_test_utils_helper';
import EmptyState from '~/groups/components/empty_state.vue';
let wrapper;
const defaultProvide = {
newProjectIllustration: '/assets/illustrations/project-create-new-sm.svg',
newProjectPath: '/projects/new?namespace_id=231',
newSubgroupIllustration: '/assets/illustrations/group-new.svg',
newSubgroupPath: '/groups/new?parent_id=231',
emptySubgroupIllustration: '/assets/illustrations/empty-state/empty-subgroup-md.svg',
canCreateSubgroups: true,
canCreateProjects: true,
};
const createComponent = ({ provide = {} } = {}) => {
wrapper = mountExtended(EmptyState, {
provide: {
...defaultProvide,
...provide,
},
});
};
afterEach(() => {
wrapper.destroy();
});
const findNewSubgroupLink = () =>
wrapper.findByRole('link', {
name: new RegExp(EmptyState.i18n.withLinks.subgroup.title),
});
const findNewProjectLink = () =>
wrapper.findByRole('link', {
name: new RegExp(EmptyState.i18n.withLinks.project.title),
});
const findNewSubgroupIllustration = () =>
wrapper.findByRole('img', { name: EmptyState.i18n.withLinks.subgroup.title });
const findNewProjectIllustration = () =>
wrapper.findByRole('img', { name: EmptyState.i18n.withLinks.project.title });
describe('EmptyState', () => {
describe('when user has permission to create a subgroup', () => {
it('renders `Create new subgroup` link', () => {
createComponent();
expect(findNewSubgroupLink().attributes('href')).toBe(defaultProvide.newSubgroupPath);
expect(findNewSubgroupIllustration().attributes('src')).toBe(
defaultProvide.newSubgroupIllustration,
);
});
});
describe('when user has permission to create a project', () => {
it('renders `Create new project` link', () => {
createComponent();
expect(findNewProjectLink().attributes('href')).toBe(defaultProvide.newProjectPath);
expect(findNewProjectIllustration().attributes('src')).toBe(
defaultProvide.newProjectIllustration,
);
});
});
describe('when user does not have permissions to create a project or a subgroup', () => {
it('renders empty state', () => {
createComponent({ provide: { canCreateSubgroups: false, canCreateProjects: false } });
expect(wrapper.find(GlEmptyState).props()).toMatchObject({
title: EmptyState.i18n.withoutLinks.title,
description: EmptyState.i18n.withoutLinks.description,
svgPath: defaultProvide.emptySubgroupIllustration,
});
});
});
});

View File

@ -446,4 +446,30 @@ RSpec.describe GroupsHelper do
end
end
end
describe '#subgroups_and_projects_list_app_data' do
let_it_be(:group) { create(:group) }
let_it_be(:user) { create(:user) }
before do
allow(helper).to receive(:current_user).and_return(user)
allow(helper).to receive(:can?).with(user, :create_subgroup, group) { true }
allow(helper).to receive(:can?).with(user, :create_projects, group) { true }
end
it 'returns expected hash' do
expect(helper.subgroups_and_projects_list_app_data(group)).to match({
show_schema_markup: 'true',
new_subgroup_path: including("groups/new?parent_id=#{group.id}"),
new_project_path: including("/projects/new?namespace_id=#{group.id}"),
new_subgroup_illustration: including('illustrations/subgroup-create-new-sm'),
new_project_illustration: including('illustrations/project-create-new-sm'),
empty_subgroup_illustration: including('illustrations/empty-state/empty-subgroup-md'),
render_empty_state: 'true',
can_create_subgroups: 'true',
can_create_projects: 'true'
})
end
end
end

View File

@ -5117,4 +5117,22 @@ RSpec.describe MergeRequest, factory_default: :keep do
end
end
end
describe '#target_default_branch?' do
let_it_be(:merge_request) { build(:merge_request, project: project) }
it 'returns false' do
expect(merge_request.target_default_branch?).to be false
end
context 'with target_branch equal project default branch' do
before do
merge_request.target_branch = "master"
end
it 'returns false' do
expect(merge_request.target_default_branch?).to be true
end
end
end
end