summaryrefslogtreecommitdiff
path: root/spec/services
diff options
context:
space:
mode:
Diffstat (limited to 'spec/services')
-rw-r--r--spec/services/access_token_validation_service_spec.rb2
-rw-r--r--spec/services/alert_management/alerts/todo/create_service_spec.rb84
-rw-r--r--spec/services/alert_management/alerts/update_service_spec.rb227
-rw-r--r--spec/services/alert_management/create_alert_issue_service_spec.rb47
-rw-r--r--spec/services/alert_management/process_prometheus_alert_service_spec.rb97
-rw-r--r--spec/services/alert_management/update_alert_status_service_spec.rb66
-rw-r--r--spec/services/application_settings/update_service_spec.rb2
-rw-r--r--spec/services/applications/create_service_spec.rb2
-rw-r--r--spec/services/audit_event_service_spec.rb5
-rw-r--r--spec/services/auth/container_registry_authentication_service_spec.rb2
-rw-r--r--spec/services/authorized_project_update/periodic_recalculate_service_spec.rb2
-rw-r--r--spec/services/authorized_project_update/project_create_service_spec.rb2
-rw-r--r--spec/services/authorized_project_update/project_group_link_create_service_spec.rb190
-rw-r--r--spec/services/authorized_project_update/recalculate_for_user_range_service_spec.rb2
-rw-r--r--spec/services/auto_merge/base_service_spec.rb4
-rw-r--r--spec/services/auto_merge/merge_when_pipeline_succeeds_service_spec.rb16
-rw-r--r--spec/services/auto_merge_service_spec.rb2
-rw-r--r--spec/services/award_emojis/add_service_spec.rb2
-rw-r--r--spec/services/award_emojis/collect_user_emoji_service_spec.rb2
-rw-r--r--spec/services/award_emojis/destroy_service_spec.rb2
-rw-r--r--spec/services/award_emojis/toggle_service_spec.rb2
-rw-r--r--spec/services/base_container_service_spec.rb2
-rw-r--r--spec/services/base_count_service_spec.rb2
-rw-r--r--spec/services/boards/create_service_spec.rb2
-rw-r--r--spec/services/boards/issues/create_service_spec.rb2
-rw-r--r--spec/services/boards/issues/list_service_spec.rb2
-rw-r--r--spec/services/boards/issues/move_service_spec.rb2
-rw-r--r--spec/services/boards/list_service_spec.rb2
-rw-r--r--spec/services/boards/lists/create_service_spec.rb2
-rw-r--r--spec/services/boards/lists/destroy_service_spec.rb2
-rw-r--r--spec/services/boards/lists/generate_service_spec.rb2
-rw-r--r--spec/services/boards/lists/list_service_spec.rb2
-rw-r--r--spec/services/boards/lists/move_service_spec.rb2
-rw-r--r--spec/services/boards/lists/update_service_spec.rb2
-rw-r--r--spec/services/boards/visits/create_service_spec.rb2
-rw-r--r--spec/services/branches/create_service_spec.rb2
-rw-r--r--spec/services/branches/delete_merged_service_spec.rb2
-rw-r--r--spec/services/branches/delete_service_spec.rb12
-rw-r--r--spec/services/branches/diverging_commit_counts_service_spec.rb2
-rw-r--r--spec/services/branches/validate_new_service_spec.rb2
-rw-r--r--spec/services/bulk_push_event_payload_service_spec.rb2
-rw-r--r--spec/services/chat_names/authorize_user_service_spec.rb2
-rw-r--r--spec/services/chat_names/find_user_service_spec.rb2
-rw-r--r--spec/services/ci/archive_trace_service_spec.rb2
-rw-r--r--spec/services/ci/build_report_result_service_spec.rb2
-rw-r--r--spec/services/ci/cancel_user_pipelines_service_spec.rb2
-rw-r--r--spec/services/ci/compare_accessibility_reports_service_spec.rb2
-rw-r--r--spec/services/ci/compare_test_reports_service_spec.rb2
-rw-r--r--spec/services/ci/create_cross_project_pipeline_service_spec.rb2
-rw-r--r--spec/services/ci/create_job_artifacts_service_spec.rb32
-rw-r--r--spec/services/ci/create_pipeline_service/cache_spec.rb2
-rw-r--r--spec/services/ci/create_pipeline_service/creation_errors_and_warnings_spec.rb114
-rw-r--r--spec/services/ci/create_pipeline_service/custom_config_content_spec.rb2
-rw-r--r--spec/services/ci/create_pipeline_service/needs_spec.rb2
-rw-r--r--spec/services/ci/create_pipeline_service/parameter_content_spec.rb62
-rw-r--r--spec/services/ci/create_pipeline_service/parent_child_pipeline_spec.rb2
-rw-r--r--spec/services/ci/create_pipeline_service/pre_post_stages_spec.rb2
-rw-r--r--spec/services/ci/create_pipeline_service/rules_spec.rb2
-rw-r--r--spec/services/ci/create_pipeline_service_spec.rb92
-rw-r--r--spec/services/ci/create_web_ide_terminal_service_spec.rb2
-rw-r--r--spec/services/ci/daily_build_group_report_result_service_spec.rb2
-rw-r--r--spec/services/ci/destroy_expired_job_artifacts_service_spec.rb6
-rw-r--r--spec/services/ci/destroy_pipeline_service_spec.rb2
-rw-r--r--spec/services/ci/ensure_stage_service_spec.rb2
-rw-r--r--spec/services/ci/expire_pipeline_cache_service_spec.rb2
-rw-r--r--spec/services/ci/external_pull_requests/create_pipeline_service_spec.rb2
-rw-r--r--spec/services/ci/extract_sections_from_build_trace_service_spec.rb2
-rw-r--r--spec/services/ci/find_exposed_artifacts_service_spec.rb2
-rw-r--r--spec/services/ci/generate_coverage_reports_service_spec.rb2
-rw-r--r--spec/services/ci/generate_terraform_reports_service_spec.rb25
-rw-r--r--spec/services/ci/parse_dotenv_artifact_service_spec.rb2
-rw-r--r--spec/services/ci/pipeline_bridge_status_service_spec.rb2
-rw-r--r--spec/services/ci/pipeline_processing/atomic_processing_service/status_collection_spec.rb2
-rw-r--r--spec/services/ci/pipeline_processing/atomic_processing_service_spec.rb2
-rw-r--r--spec/services/ci/pipeline_processing/legacy_processing_service_spec.rb2
-rw-r--r--spec/services/ci/pipeline_processing/shared_processing_service.rb2
-rw-r--r--spec/services/ci/pipeline_processing/shared_processing_service_tests_with_yaml.rb2
-rw-r--r--spec/services/ci/pipeline_schedule_service_spec.rb2
-rw-r--r--spec/services/ci/pipeline_trigger_service_spec.rb2
-rw-r--r--spec/services/ci/play_build_service_spec.rb2
-rw-r--r--spec/services/ci/play_manual_stage_service_spec.rb2
-rw-r--r--spec/services/ci/prepare_build_service_spec.rb2
-rw-r--r--spec/services/ci/process_build_service_spec.rb2
-rw-r--r--spec/services/ci/process_pipeline_service_spec.rb44
-rw-r--r--spec/services/ci/register_job_service_spec.rb17
-rw-r--r--spec/services/ci/resource_groups/assign_resource_from_resource_group_service_spec.rb2
-rw-r--r--spec/services/ci/retry_build_service_spec.rb29
-rw-r--r--spec/services/ci/retry_pipeline_service_spec.rb2
-rw-r--r--spec/services/ci/run_scheduled_build_service_spec.rb2
-rw-r--r--spec/services/ci/stop_environments_service_spec.rb2
-rw-r--r--spec/services/ci/unlock_artifacts_service_spec.rb97
-rw-r--r--spec/services/ci/update_build_queue_service_spec.rb2
-rw-r--r--spec/services/ci/update_instance_variables_service_spec.rb2
-rw-r--r--spec/services/ci/update_runner_service_spec.rb2
-rw-r--r--spec/services/ci/web_ide_config_service_spec.rb2
-rw-r--r--spec/services/clusters/applications/check_ingress_ip_address_service_spec.rb2
-rw-r--r--spec/services/clusters/applications/check_installation_progress_service_spec.rb2
-rw-r--r--spec/services/clusters/applications/check_uninstall_progress_service_spec.rb2
-rw-r--r--spec/services/clusters/applications/check_upgrade_progress_service_spec.rb2
-rw-r--r--spec/services/clusters/applications/create_service_spec.rb2
-rw-r--r--spec/services/clusters/applications/destroy_service_spec.rb2
-rw-r--r--spec/services/clusters/applications/install_service_spec.rb2
-rw-r--r--spec/services/clusters/applications/patch_service_spec.rb2
-rw-r--r--spec/services/clusters/applications/prometheus_config_service_spec.rb2
-rw-r--r--spec/services/clusters/applications/prometheus_health_check_service_spec.rb2
-rw-r--r--spec/services/clusters/applications/prometheus_update_service_spec.rb2
-rw-r--r--spec/services/clusters/applications/schedule_update_service_spec.rb2
-rw-r--r--spec/services/clusters/applications/uninstall_service_spec.rb2
-rw-r--r--spec/services/clusters/applications/update_service_spec.rb2
-rw-r--r--spec/services/clusters/applications/upgrade_service_spec.rb2
-rw-r--r--spec/services/clusters/aws/authorize_role_service_spec.rb2
-rw-r--r--spec/services/clusters/aws/fetch_credentials_service_spec.rb2
-rw-r--r--spec/services/clusters/aws/finalize_creation_service_spec.rb2
-rw-r--r--spec/services/clusters/aws/provision_service_spec.rb2
-rw-r--r--spec/services/clusters/aws/verify_provision_status_service_spec.rb2
-rw-r--r--spec/services/clusters/build_kubernetes_namespace_service_spec.rb2
-rw-r--r--spec/services/clusters/build_service_spec.rb2
-rw-r--r--spec/services/clusters/cleanup/app_service_spec.rb2
-rw-r--r--spec/services/clusters/cleanup/project_namespace_service_spec.rb2
-rw-r--r--spec/services/clusters/cleanup/service_account_service_spec.rb2
-rw-r--r--spec/services/clusters/create_service_spec.rb49
-rw-r--r--spec/services/clusters/destroy_service_spec.rb2
-rw-r--r--spec/services/clusters/gcp/fetch_operation_service_spec.rb2
-rw-r--r--spec/services/clusters/gcp/finalize_creation_service_spec.rb2
-rw-r--r--spec/services/clusters/gcp/provision_service_spec.rb2
-rw-r--r--spec/services/clusters/gcp/verify_provision_status_service_spec.rb2
-rw-r--r--spec/services/clusters/kubernetes/configure_istio_ingress_service_spec.rb2
-rw-r--r--spec/services/clusters/kubernetes/create_or_update_namespace_service_spec.rb2
-rw-r--r--spec/services/clusters/kubernetes/create_or_update_service_account_service_spec.rb2
-rw-r--r--spec/services/clusters/kubernetes/fetch_kubernetes_token_service_spec.rb2
-rw-r--r--spec/services/clusters/kubernetes_spec.rb2
-rw-r--r--spec/services/clusters/management/create_project_service_spec.rb2
-rw-r--r--spec/services/clusters/management/validate_management_project_permissions_service_spec.rb2
-rw-r--r--spec/services/clusters/parse_cluster_applications_artifact_service_spec.rb89
-rw-r--r--spec/services/clusters/update_service_spec.rb2
-rw-r--r--spec/services/cohorts_service_spec.rb2
-rw-r--r--spec/services/commits/cherry_pick_service_spec.rb2
-rw-r--r--spec/services/commits/commit_patch_service_spec.rb2
-rw-r--r--spec/services/commits/tag_service_spec.rb2
-rw-r--r--spec/services/compare_service_spec.rb2
-rw-r--r--spec/services/concerns/exclusive_lease_guard_spec.rb2
-rw-r--r--spec/services/concerns/merge_requests/assigns_merge_params_spec.rb2
-rw-r--r--spec/services/container_expiration_policies/update_service_spec.rb2
-rw-r--r--spec/services/container_expiration_policy_service_spec.rb2
-rw-r--r--spec/services/deploy_keys/collect_keys_service_spec.rb58
-rw-r--r--spec/services/deploy_keys/create_service_spec.rb2
-rw-r--r--spec/services/deployments/after_create_service_spec.rb2
-rw-r--r--spec/services/deployments/create_service_spec.rb2
-rw-r--r--spec/services/deployments/link_merge_requests_service_spec.rb2
-rw-r--r--spec/services/deployments/older_deployments_drop_service_spec.rb2
-rw-r--r--spec/services/deployments/update_service_spec.rb2
-rw-r--r--spec/services/design_management/delete_designs_service_spec.rb2
-rw-r--r--spec/services/design_management/design_user_notes_count_service_spec.rb2
-rw-r--r--spec/services/design_management/generate_image_versions_service_spec.rb2
-rw-r--r--spec/services/design_management/save_designs_service_spec.rb2
-rw-r--r--spec/services/discussions/capture_diff_note_position_service_spec.rb2
-rw-r--r--spec/services/discussions/capture_diff_note_positions_service_spec.rb2
-rw-r--r--spec/services/discussions/resolve_service_spec.rb2
-rw-r--r--spec/services/discussions/update_diff_position_service_spec.rb2
-rw-r--r--spec/services/draft_notes/create_service_spec.rb2
-rw-r--r--spec/services/draft_notes/destroy_service_spec.rb2
-rw-r--r--spec/services/draft_notes/publish_service_spec.rb5
-rw-r--r--spec/services/emails/confirm_service_spec.rb2
-rw-r--r--spec/services/emails/create_service_spec.rb2
-rw-r--r--spec/services/emails/destroy_service_spec.rb2
-rw-r--r--spec/services/environments/auto_stop_service_spec.rb2
-rw-r--r--spec/services/environments/reset_auto_stop_service_spec.rb2
-rw-r--r--spec/services/error_tracking/base_service_spec.rb2
-rw-r--r--spec/services/error_tracking/issue_details_service_spec.rb2
-rw-r--r--spec/services/error_tracking/issue_latest_event_service_spec.rb2
-rw-r--r--spec/services/error_tracking/issue_update_service_spec.rb2
-rw-r--r--spec/services/error_tracking/list_issues_service_spec.rb2
-rw-r--r--spec/services/error_tracking/list_projects_service_spec.rb2
-rw-r--r--spec/services/event_create_service_spec.rb106
-rw-r--r--spec/services/events/render_service_spec.rb2
-rw-r--r--spec/services/files/create_service_spec.rb2
-rw-r--r--spec/services/files/delete_service_spec.rb2
-rw-r--r--spec/services/files/multi_service_spec.rb2
-rw-r--r--spec/services/files/update_service_spec.rb2
-rw-r--r--spec/services/git/base_hooks_service_spec.rb2
-rw-r--r--spec/services/git/branch_hooks_service_spec.rb2
-rw-r--r--spec/services/git/branch_push_service_spec.rb33
-rw-r--r--spec/services/git/process_ref_changes_service_spec.rb2
-rw-r--r--spec/services/git/tag_hooks_service_spec.rb2
-rw-r--r--spec/services/git/tag_push_service_spec.rb39
-rw-r--r--spec/services/git/wiki_push_service/change_spec.rb2
-rw-r--r--spec/services/git/wiki_push_service_spec.rb10
-rw-r--r--spec/services/gpg_keys/create_service_spec.rb2
-rw-r--r--spec/services/gpg_keys/destroy_service_spec.rb15
-rw-r--r--spec/services/grafana/proxy_service_spec.rb2
-rw-r--r--spec/services/gravatar_service_spec.rb2
-rw-r--r--spec/services/groups/auto_devops_service_spec.rb2
-rw-r--r--spec/services/groups/create_service_spec.rb11
-rw-r--r--spec/services/groups/deploy_tokens/create_service_spec.rb2
-rw-r--r--spec/services/groups/deploy_tokens/destroy_service_spec.rb2
-rw-r--r--spec/services/groups/destroy_service_spec.rb2
-rw-r--r--spec/services/groups/group_links/create_service_spec.rb2
-rw-r--r--spec/services/groups/group_links/destroy_service_spec.rb2
-rw-r--r--spec/services/groups/group_links/update_service_spec.rb2
-rw-r--r--spec/services/groups/import_export/export_service_spec.rb2
-rw-r--r--spec/services/groups/import_export/import_service_spec.rb2
-rw-r--r--spec/services/groups/nested_create_service_spec.rb2
-rw-r--r--spec/services/groups/transfer_service_spec.rb2
-rw-r--r--spec/services/groups/update_service_spec.rb2
-rw-r--r--spec/services/groups/update_shared_runners_service_spec.rb230
-rw-r--r--spec/services/import/bitbucket_server_service_spec.rb113
-rw-r--r--spec/services/import/github_service_spec.rb2
-rw-r--r--spec/services/import_export_clean_up_service_spec.rb2
-rw-r--r--spec/services/incident_management/create_incident_label_service_spec.rb58
-rw-r--r--spec/services/incident_management/create_issue_service_spec.rb97
-rw-r--r--spec/services/incident_management/pager_duty/create_incident_issue_service_spec.rb104
-rw-r--r--spec/services/incident_management/pager_duty/process_webhook_service_spec.rb148
-rw-r--r--spec/services/integrations/test/project_service_spec.rb2
-rw-r--r--spec/services/issuable/bulk_update_service_spec.rb30
-rw-r--r--spec/services/issuable/clone/attributes_rewriter_spec.rb2
-rw-r--r--spec/services/issuable/clone/content_rewriter_spec.rb2
-rw-r--r--spec/services/issuable/common_system_notes_service_spec.rb18
-rw-r--r--spec/services/issuable/destroy_service_spec.rb2
-rw-r--r--spec/services/issues/build_service_spec.rb2
-rw-r--r--spec/services/issues/close_service_spec.rb2
-rw-r--r--spec/services/issues/create_service_spec.rb6
-rw-r--r--spec/services/issues/duplicate_service_spec.rb2
-rw-r--r--spec/services/issues/export_csv_service_spec.rb2
-rw-r--r--spec/services/issues/import_csv_service_spec.rb2
-rw-r--r--spec/services/issues/move_service_spec.rb47
-rw-r--r--spec/services/issues/referenced_merge_requests_service_spec.rb2
-rw-r--r--spec/services/issues/related_branches_service_spec.rb2
-rw-r--r--spec/services/issues/reopen_service_spec.rb2
-rw-r--r--spec/services/issues/reorder_service_spec.rb2
-rw-r--r--spec/services/issues/resolve_discussions_spec.rb2
-rw-r--r--spec/services/issues/update_service_spec.rb7
-rw-r--r--spec/services/issues/zoom_link_service_spec.rb2
-rw-r--r--spec/services/jira/requests/projects/list_service_spec.rb (renamed from spec/services/jira/requests/projects_spec.rb)22
-rw-r--r--spec/services/jira_import/start_import_service_spec.rb86
-rw-r--r--spec/services/jira_import/users_importer_spec.rb2
-rw-r--r--spec/services/jira_import/users_mapper_spec.rb8
-rw-r--r--spec/services/keys/create_service_spec.rb2
-rw-r--r--spec/services/keys/destroy_service_spec.rb2
-rw-r--r--spec/services/keys/last_used_service_spec.rb2
-rw-r--r--spec/services/labels/available_labels_service_spec.rb2
-rw-r--r--spec/services/labels/create_service_spec.rb2
-rw-r--r--spec/services/labels/find_or_create_service_spec.rb2
-rw-r--r--spec/services/labels/promote_service_spec.rb2
-rw-r--r--spec/services/labels/transfer_service_spec.rb2
-rw-r--r--spec/services/labels/update_service_spec.rb2
-rw-r--r--spec/services/lfs/file_transformer_spec.rb2
-rw-r--r--spec/services/lfs/lock_file_service_spec.rb2
-rw-r--r--spec/services/lfs/locks_finder_service_spec.rb2
-rw-r--r--spec/services/lfs/unlock_file_service_spec.rb2
-rw-r--r--spec/services/members/approve_access_request_service_spec.rb2
-rw-r--r--spec/services/members/create_service_spec.rb2
-rw-r--r--spec/services/members/destroy_service_spec.rb51
-rw-r--r--spec/services/members/request_access_service_spec.rb2
-rw-r--r--spec/services/members/unassign_issuables_service_spec.rb66
-rw-r--r--spec/services/members/update_service_spec.rb2
-rw-r--r--spec/services/merge_requests/add_context_service_spec.rb2
-rw-r--r--spec/services/merge_requests/add_todo_when_build_fails_service_spec.rb2
-rw-r--r--spec/services/merge_requests/after_create_service_spec.rb2
-rw-r--r--spec/services/merge_requests/approval_service_spec.rb74
-rw-r--r--spec/services/merge_requests/assign_issues_service_spec.rb2
-rw-r--r--spec/services/merge_requests/build_service_spec.rb6
-rw-r--r--spec/services/merge_requests/close_service_spec.rb2
-rw-r--r--spec/services/merge_requests/conflicts/list_service_spec.rb3
-rw-r--r--spec/services/merge_requests/conflicts/resolve_service_spec.rb2
-rw-r--r--spec/services/merge_requests/create_from_issue_service_spec.rb10
-rw-r--r--spec/services/merge_requests/create_pipeline_service_spec.rb55
-rw-r--r--spec/services/merge_requests/create_service_spec.rb12
-rw-r--r--spec/services/merge_requests/delete_non_latest_diffs_service_spec.rb2
-rw-r--r--spec/services/merge_requests/ff_merge_service_spec.rb2
-rw-r--r--spec/services/merge_requests/get_urls_service_spec.rb2
-rw-r--r--spec/services/merge_requests/link_lfs_objects_service_spec.rb2
-rw-r--r--spec/services/merge_requests/merge_orchestration_service_spec.rb2
-rw-r--r--spec/services/merge_requests/merge_service_spec.rb21
-rw-r--r--spec/services/merge_requests/merge_to_ref_service_spec.rb2
-rw-r--r--spec/services/merge_requests/mergeability_check_service_spec.rb2
-rw-r--r--spec/services/merge_requests/migrate_external_diffs_service_spec.rb2
-rw-r--r--spec/services/merge_requests/post_merge_service_spec.rb67
-rw-r--r--spec/services/merge_requests/push_options_handler_service_spec.rb2
-rw-r--r--spec/services/merge_requests/pushed_branches_service_spec.rb2
-rw-r--r--spec/services/merge_requests/rebase_service_spec.rb2
-rw-r--r--spec/services/merge_requests/refresh_service_spec.rb9
-rw-r--r--spec/services/merge_requests/reload_diffs_service_spec.rb8
-rw-r--r--spec/services/merge_requests/remove_approval_service_spec.rb46
-rw-r--r--spec/services/merge_requests/reopen_service_spec.rb2
-rw-r--r--spec/services/merge_requests/resolved_discussion_notification_service_spec.rb2
-rw-r--r--spec/services/merge_requests/squash_service_spec.rb38
-rw-r--r--spec/services/merge_requests/update_service_spec.rb7
-rw-r--r--spec/services/metrics/dashboard/annotations/create_service_spec.rb2
-rw-r--r--spec/services/metrics/dashboard/annotations/delete_service_spec.rb2
-rw-r--r--spec/services/metrics/dashboard/clone_dashboard_service_spec.rb19
-rw-r--r--spec/services/metrics/dashboard/cluster_dashboard_service_spec.rb59
-rw-r--r--spec/services/metrics/dashboard/cluster_metrics_embed_service_spec.rb72
-rw-r--r--spec/services/metrics/dashboard/custom_dashboard_service_spec.rb20
-rw-r--r--spec/services/metrics/dashboard/custom_metric_embed_service_spec.rb2
-rw-r--r--spec/services/metrics/dashboard/default_embed_service_spec.rb2
-rw-r--r--spec/services/metrics/dashboard/dynamic_embed_service_spec.rb2
-rw-r--r--spec/services/metrics/dashboard/gitlab_alert_embed_service_spec.rb2
-rw-r--r--spec/services/metrics/dashboard/grafana_metric_embed_service_spec.rb6
-rw-r--r--spec/services/metrics/dashboard/pod_dashboard_service_spec.rb20
-rw-r--r--spec/services/metrics/dashboard/self_monitoring_dashboard_service_spec.rb22
-rw-r--r--spec/services/metrics/dashboard/system_dashboard_service_spec.rb23
-rw-r--r--spec/services/metrics/dashboard/transient_embed_service_spec.rb2
-rw-r--r--spec/services/metrics/dashboard/update_dashboard_service_spec.rb2
-rw-r--r--spec/services/metrics/sample_metrics_service_spec.rb2
-rw-r--r--spec/services/metrics/users_starred_dashboards/create_service_spec.rb2
-rw-r--r--spec/services/metrics/users_starred_dashboards/delete_service_spec.rb2
-rw-r--r--spec/services/milestones/close_service_spec.rb2
-rw-r--r--spec/services/milestones/closed_issues_count_service_spec.rb2
-rw-r--r--spec/services/milestones/create_service_spec.rb2
-rw-r--r--spec/services/milestones/destroy_service_spec.rb2
-rw-r--r--spec/services/milestones/find_or_create_service_spec.rb2
-rw-r--r--spec/services/milestones/issues_count_service_spec.rb2
-rw-r--r--spec/services/milestones/promote_service_spec.rb2
-rw-r--r--spec/services/milestones/transfer_service_spec.rb2
-rw-r--r--spec/services/milestones/update_service_spec.rb2
-rw-r--r--spec/services/namespaces/check_storage_size_service_spec.rb165
-rw-r--r--spec/services/namespaces/statistics_refresher_service_spec.rb2
-rw-r--r--spec/services/note_summary_spec.rb2
-rw-r--r--spec/services/notes/build_service_spec.rb2
-rw-r--r--spec/services/notes/create_service_spec.rb4
-rw-r--r--spec/services/notes/destroy_service_spec.rb2
-rw-r--r--spec/services/notes/post_process_service_spec.rb2
-rw-r--r--spec/services/notes/quick_actions_service_spec.rb2
-rw-r--r--spec/services/notes/render_service_spec.rb2
-rw-r--r--spec/services/notes/resolve_service_spec.rb2
-rw-r--r--spec/services/notes/update_service_spec.rb41
-rw-r--r--spec/services/notification_recipients/build_service_spec.rb2
-rw-r--r--spec/services/notification_recipients/builder/default_spec.rb2
-rw-r--r--spec/services/notification_recipients/builder/new_note_spec.rb2
-rw-r--r--spec/services/notification_service_spec.rb95
-rw-r--r--spec/services/packages/composer/composer_json_service_spec.rb39
-rw-r--r--spec/services/packages/composer/create_package_service_spec.rb97
-rw-r--r--spec/services/packages/composer/version_parser_service_spec.rb31
-rw-r--r--spec/services/packages/conan/create_package_file_service_spec.rb130
-rw-r--r--spec/services/packages/conan/create_package_service_spec.rb48
-rw-r--r--spec/services/packages/conan/search_service_spec.rb74
-rw-r--r--spec/services/packages/create_dependency_service_spec.rb113
-rw-r--r--spec/services/packages/create_package_file_service_spec.rb38
-rw-r--r--spec/services/packages/maven/create_package_service_spec.rb77
-rw-r--r--spec/services/packages/maven/find_or_create_package_service_spec.rb38
-rw-r--r--spec/services/packages/npm/create_package_service_spec.rb96
-rw-r--r--spec/services/packages/npm/create_tag_service_spec.rb53
-rw-r--r--spec/services/packages/nuget/create_dependency_service_spec.rb76
-rw-r--r--spec/services/packages/nuget/create_package_service_spec.rb34
-rw-r--r--spec/services/packages/nuget/metadata_extraction_service_spec.rb106
-rw-r--r--spec/services/packages/nuget/search_service_spec.rb116
-rw-r--r--spec/services/packages/nuget/sync_metadatum_service_spec.rb57
-rw-r--r--spec/services/packages/nuget/update_package_from_metadata_service_spec.rb237
-rw-r--r--spec/services/packages/pypi/create_package_service_spec.rb83
-rw-r--r--spec/services/packages/remove_tag_service_spec.rb20
-rw-r--r--spec/services/packages/update_tags_service_spec.rb59
-rw-r--r--spec/services/pages/delete_services_spec.rb2
-rw-r--r--spec/services/pages_domains/create_acme_order_service_spec.rb2
-rw-r--r--spec/services/pages_domains/obtain_lets_encrypt_certificate_service_spec.rb2
-rw-r--r--spec/services/pages_domains/retry_acme_order_service_spec.rb2
-rw-r--r--spec/services/personal_access_tokens/create_service_spec.rb2
-rw-r--r--spec/services/personal_access_tokens/last_used_service_spec.rb47
-rw-r--r--spec/services/pod_logs/base_service_spec.rb2
-rw-r--r--spec/services/pod_logs/elasticsearch_service_spec.rb2
-rw-r--r--spec/services/pod_logs/kubernetes_service_spec.rb2
-rw-r--r--spec/services/post_receive_service_spec.rb37
-rw-r--r--spec/services/preview_markdown_service_spec.rb2
-rw-r--r--spec/services/projects/after_import_service_spec.rb22
-rw-r--r--spec/services/projects/after_rename_service_spec.rb2
-rw-r--r--spec/services/projects/alerting/notify_service_spec.rb110
-rw-r--r--spec/services/projects/auto_devops/disable_service_spec.rb2
-rw-r--r--spec/services/projects/autocomplete_service_spec.rb2
-rw-r--r--spec/services/projects/batch_open_issues_count_service_spec.rb2
-rw-r--r--spec/services/projects/cleanup_service_spec.rb2
-rw-r--r--spec/services/projects/container_repository/cleanup_tags_service_spec.rb2
-rw-r--r--spec/services/projects/container_repository/delete_tags_service_spec.rb118
-rw-r--r--spec/services/projects/container_repository/destroy_service_spec.rb2
-rw-r--r--spec/services/projects/count_service_spec.rb2
-rw-r--r--spec/services/projects/create_from_template_service_spec.rb2
-rw-r--r--spec/services/projects/create_service_spec.rb61
-rw-r--r--spec/services/projects/deploy_tokens/create_service_spec.rb2
-rw-r--r--spec/services/projects/deploy_tokens/destroy_service_spec.rb2
-rw-r--r--spec/services/projects/destroy_rollback_service_spec.rb2
-rw-r--r--spec/services/projects/destroy_service_spec.rb2
-rw-r--r--spec/services/projects/detect_repository_languages_service_spec.rb2
-rw-r--r--spec/services/projects/download_service_spec.rb2
-rw-r--r--spec/services/projects/enable_deploy_key_service_spec.rb2
-rw-r--r--spec/services/projects/fetch_statistics_increment_service_spec.rb2
-rw-r--r--spec/services/projects/fork_service_spec.rb6
-rw-r--r--spec/services/projects/forks_count_service_spec.rb2
-rw-r--r--spec/services/projects/git_deduplication_service_spec.rb4
-rw-r--r--spec/services/projects/gitlab_projects_import_service_spec.rb2
-rw-r--r--spec/services/projects/group_links/create_service_spec.rb50
-rw-r--r--spec/services/projects/group_links/destroy_service_spec.rb2
-rw-r--r--spec/services/projects/group_links/update_service_spec.rb2
-rw-r--r--spec/services/projects/hashed_storage/base_attachment_service_spec.rb2
-rw-r--r--spec/services/projects/hashed_storage/migrate_attachments_service_spec.rb2
-rw-r--r--spec/services/projects/hashed_storage/migrate_repository_service_spec.rb2
-rw-r--r--spec/services/projects/hashed_storage/migration_service_spec.rb2
-rw-r--r--spec/services/projects/hashed_storage/rollback_attachments_service_spec.rb2
-rw-r--r--spec/services/projects/hashed_storage/rollback_repository_service_spec.rb2
-rw-r--r--spec/services/projects/hashed_storage/rollback_service_spec.rb2
-rw-r--r--spec/services/projects/housekeeping_service_spec.rb2
-rw-r--r--spec/services/projects/import_error_filter_spec.rb2
-rw-r--r--spec/services/projects/import_export/export_service_spec.rb2
-rw-r--r--spec/services/projects/import_service_spec.rb2
-rw-r--r--spec/services/projects/lfs_pointers/lfs_download_link_list_service_spec.rb2
-rw-r--r--spec/services/projects/lfs_pointers/lfs_download_service_spec.rb2
-rw-r--r--spec/services/projects/lfs_pointers/lfs_import_service_spec.rb2
-rw-r--r--spec/services/projects/lfs_pointers/lfs_link_service_spec.rb2
-rw-r--r--spec/services/projects/lfs_pointers/lfs_object_download_list_service_spec.rb2
-rw-r--r--spec/services/projects/move_access_service_spec.rb2
-rw-r--r--spec/services/projects/move_deploy_keys_projects_service_spec.rb2
-rw-r--r--spec/services/projects/move_forks_service_spec.rb2
-rw-r--r--spec/services/projects/move_lfs_objects_projects_service_spec.rb2
-rw-r--r--spec/services/projects/move_notification_settings_service_spec.rb2
-rw-r--r--spec/services/projects/move_project_authorizations_service_spec.rb2
-rw-r--r--spec/services/projects/move_project_group_links_service_spec.rb2
-rw-r--r--spec/services/projects/move_project_members_service_spec.rb2
-rw-r--r--spec/services/projects/move_users_star_projects_service_spec.rb2
-rw-r--r--spec/services/projects/open_issues_count_service_spec.rb2
-rw-r--r--spec/services/projects/open_merge_requests_count_service_spec.rb2
-rw-r--r--spec/services/projects/operations/update_service_spec.rb2
-rw-r--r--spec/services/projects/overwrite_project_service_spec.rb2
-rw-r--r--spec/services/projects/participants_service_spec.rb2
-rw-r--r--spec/services/projects/prometheus/alerts/create_events_service_spec.rb312
-rw-r--r--spec/services/projects/prometheus/alerts/create_service_spec.rb2
-rw-r--r--spec/services/projects/prometheus/alerts/destroy_service_spec.rb2
-rw-r--r--spec/services/projects/prometheus/alerts/notify_service_spec.rb127
-rw-r--r--spec/services/projects/prometheus/alerts/update_service_spec.rb2
-rw-r--r--spec/services/projects/prometheus/metrics/destroy_service_spec.rb2
-rw-r--r--spec/services/projects/prometheus/metrics/update_service_spec.rb2
-rw-r--r--spec/services/projects/propagate_service_template_spec.rb2
-rw-r--r--spec/services/projects/protect_default_branch_service_spec.rb2
-rw-r--r--spec/services/projects/repository_languages_service_spec.rb2
-rw-r--r--spec/services/projects/transfer_service_spec.rb2
-rw-r--r--spec/services/projects/unlink_fork_service_spec.rb5
-rw-r--r--spec/services/projects/update_pages_configuration_service_spec.rb2
-rw-r--r--spec/services/projects/update_pages_service_spec.rb2
-rw-r--r--spec/services/projects/update_remote_mirror_service_spec.rb2
-rw-r--r--spec/services/projects/update_repository_storage_service_spec.rb38
-rw-r--r--spec/services/projects/update_service_spec.rb2
-rw-r--r--spec/services/projects/update_statistics_service_spec.rb2
-rw-r--r--spec/services/prometheus/create_default_alerts_service_spec.rb2
-rw-r--r--spec/services/prometheus/proxy_service_spec.rb2
-rw-r--r--spec/services/prometheus/proxy_variable_substitution_service_spec.rb2
-rw-r--r--spec/services/protected_branches/create_service_spec.rb2
-rw-r--r--spec/services/protected_branches/destroy_service_spec.rb2
-rw-r--r--spec/services/protected_branches/update_service_spec.rb2
-rw-r--r--spec/services/protected_tags/create_service_spec.rb2
-rw-r--r--spec/services/protected_tags/destroy_service_spec.rb2
-rw-r--r--spec/services/protected_tags/update_service_spec.rb2
-rw-r--r--spec/services/push_event_payload_service_spec.rb2
-rw-r--r--spec/services/quick_actions/interpret_service_spec.rb4
-rw-r--r--spec/services/quick_actions/target_service_spec.rb2
-rw-r--r--spec/services/releases/create_evidence_service_spec.rb2
-rw-r--r--spec/services/releases/create_service_spec.rb2
-rw-r--r--spec/services/releases/destroy_service_spec.rb2
-rw-r--r--spec/services/releases/update_service_spec.rb2
-rw-r--r--spec/services/repositories/destroy_rollback_service_spec.rb2
-rw-r--r--spec/services/repositories/destroy_service_spec.rb17
-rw-r--r--spec/services/repositories/shell_destroy_service_spec.rb2
-rw-r--r--spec/services/repository_archive_clean_up_service_spec.rb2
-rw-r--r--spec/services/reset_project_cache_service_spec.rb2
-rw-r--r--spec/services/resource_access_tokens/create_service_spec.rb23
-rw-r--r--spec/services/resource_access_tokens/revoke_service_spec.rb2
-rw-r--r--spec/services/resource_events/change_labels_service_spec.rb2
-rw-r--r--spec/services/resource_events/change_milestone_service_spec.rb2
-rw-r--r--spec/services/resource_events/change_state_service_spec.rb91
-rw-r--r--spec/services/resource_events/merge_into_notes_service_spec.rb4
-rw-r--r--spec/services/resource_events/synthetic_label_notes_builder_service_spec.rb2
-rw-r--r--spec/services/resource_events/synthetic_milestone_notes_builder_service_spec.rb2
-rw-r--r--spec/services/search/global_service_spec.rb2
-rw-r--r--spec/services/search/group_service_spec.rb2
-rw-r--r--spec/services/search/snippet_service_spec.rb2
-rw-r--r--spec/services/search_service_spec.rb2
-rw-r--r--spec/services/serverless/associate_domain_service_spec.rb2
-rw-r--r--spec/services/service_desk_settings/update_service_spec.rb46
-rw-r--r--spec/services/service_response_spec.rb2
-rw-r--r--spec/services/snippets/bulk_destroy_service_spec.rb2
-rw-r--r--spec/services/snippets/count_service_spec.rb2
-rw-r--r--spec/services/snippets/create_service_spec.rb54
-rw-r--r--spec/services/snippets/destroy_service_spec.rb28
-rw-r--r--spec/services/snippets/repository_validation_service_spec.rb2
-rw-r--r--spec/services/snippets/update_service_spec.rb256
-rw-r--r--spec/services/snippets/update_statistics_service_spec.rb86
-rw-r--r--spec/services/spam/akismet_service_spec.rb2
-rw-r--r--spec/services/spam/ham_service_spec.rb2
-rw-r--r--spec/services/spam/mark_as_spam_service_spec.rb2
-rw-r--r--spec/services/spam/spam_action_service_spec.rb2
-rw-r--r--spec/services/spam/spam_verdict_service_spec.rb31
-rw-r--r--spec/services/submit_usage_ping_service_spec.rb2
-rw-r--r--spec/services/submodules/update_service_spec.rb2
-rw-r--r--spec/services/suggestions/apply_service_spec.rb2
-rw-r--r--spec/services/suggestions/create_service_spec.rb2
-rw-r--r--spec/services/suggestions/outdate_service_spec.rb2
-rw-r--r--spec/services/system_hooks_service_spec.rb2
-rw-r--r--spec/services/system_note_service_spec.rb46
-rw-r--r--spec/services/system_notes/alert_management_service_spec.rb35
-rw-r--r--spec/services/system_notes/base_service_spec.rb2
-rw-r--r--spec/services/system_notes/commit_service_spec.rb2
-rw-r--r--spec/services/system_notes/design_management_service_spec.rb2
-rw-r--r--spec/services/system_notes/issuables_service_spec.rb64
-rw-r--r--spec/services/system_notes/merge_requests_service_spec.rb20
-rw-r--r--spec/services/system_notes/time_tracking_service_spec.rb2
-rw-r--r--spec/services/system_notes/zoom_service_spec.rb2
-rw-r--r--spec/services/tags/create_service_spec.rb2
-rw-r--r--spec/services/tags/destroy_service_spec.rb12
-rw-r--r--spec/services/task_list_toggle_service_spec.rb2
-rw-r--r--spec/services/terraform/remote_state_handler_spec.rb123
-rw-r--r--spec/services/test_hooks/project_service_spec.rb2
-rw-r--r--spec/services/test_hooks/system_service_spec.rb2
-rw-r--r--spec/services/todo_service_spec.rb2
-rw-r--r--spec/services/todos/destroy/confidential_issue_service_spec.rb2
-rw-r--r--spec/services/todos/destroy/entity_leave_service_spec.rb2
-rw-r--r--spec/services/todos/destroy/group_private_service_spec.rb2
-rw-r--r--spec/services/todos/destroy/private_features_service_spec.rb2
-rw-r--r--spec/services/todos/destroy/project_private_service_spec.rb2
-rw-r--r--spec/services/update_container_registry_info_service_spec.rb115
-rw-r--r--spec/services/update_merge_request_metrics_service_spec.rb2
-rw-r--r--spec/services/upload_service_spec.rb2
-rw-r--r--spec/services/user_project_access_changed_service_spec.rb2
-rw-r--r--spec/services/users/activity_service_spec.rb2
-rw-r--r--spec/services/users/block_service_spec.rb2
-rw-r--r--spec/services/users/build_service_spec.rb2
-rw-r--r--spec/services/users/create_service_spec.rb2
-rw-r--r--spec/services/users/destroy_service_spec.rb2
-rw-r--r--spec/services/users/keys_count_service_spec.rb2
-rw-r--r--spec/services/users/last_push_event_service_spec.rb2
-rw-r--r--spec/services/users/migrate_to_ghost_user_service_spec.rb2
-rw-r--r--spec/services/users/refresh_authorized_projects_service_spec.rb2
-rw-r--r--spec/services/users/repair_ldap_blocked_service_spec.rb2
-rw-r--r--spec/services/users/respond_to_terms_service_spec.rb2
-rw-r--r--spec/services/users/set_status_service_spec.rb2
-rw-r--r--spec/services/users/signup_service_spec.rb2
-rw-r--r--spec/services/users/update_canonical_email_service_spec.rb2
-rw-r--r--spec/services/users/update_highest_member_role_service_spec.rb2
-rw-r--r--spec/services/users/update_service_spec.rb2
-rw-r--r--spec/services/verify_pages_domain_service_spec.rb2
-rw-r--r--spec/services/web_hook_service_spec.rb2
-rw-r--r--spec/services/wiki_pages/base_service_spec.rb2
-rw-r--r--spec/services/wiki_pages/create_service_spec.rb2
-rw-r--r--spec/services/wiki_pages/destroy_service_spec.rb2
-rw-r--r--spec/services/wiki_pages/event_create_service_spec.rb17
-rw-r--r--spec/services/wiki_pages/update_service_spec.rb2
-rw-r--r--spec/services/wikis/create_attachment_service_spec.rb2
-rw-r--r--spec/services/x509_certificate_revoke_service_spec.rb2
542 files changed, 6201 insertions, 1940 deletions
diff --git a/spec/services/access_token_validation_service_spec.rb b/spec/services/access_token_validation_service_spec.rb
index b2a8da6c4c6..2bf74d64dc9 100644
--- a/spec/services/access_token_validation_service_spec.rb
+++ b/spec/services/access_token_validation_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe AccessTokenValidationService do
+RSpec.describe AccessTokenValidationService do
describe ".include_any_scope?" do
let(:request) { double("request") }
diff --git a/spec/services/alert_management/alerts/todo/create_service_spec.rb b/spec/services/alert_management/alerts/todo/create_service_spec.rb
new file mode 100644
index 00000000000..e3d9de8b4df
--- /dev/null
+++ b/spec/services/alert_management/alerts/todo/create_service_spec.rb
@@ -0,0 +1,84 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe AlertManagement::Alerts::Todo::CreateService do
+ let_it_be(:user) { create(:user) }
+ let_it_be(:alert) { create(:alert_management_alert) }
+
+ let(:current_user) { user }
+
+ describe '#execute' do
+ subject(:result) { AlertManagement::Alerts::Todo::CreateService.new(alert, current_user).execute }
+
+ shared_examples 'permissions error' do
+ it 'returns an error', :aggregate_failures do
+ expect(result.error?).to be(true)
+ expect(result.message).to eq('You have insufficient permissions to create a Todo for this alert')
+ expect(result.payload[:todo]).to be(nil)
+ expect(result.payload[:alert]).to be(alert)
+ end
+ end
+
+ context 'when the user is anonymous' do
+ let(:current_user) { nil }
+
+ it_behaves_like 'permissions error'
+ end
+
+ context 'when the user does not have permission' do
+ it_behaves_like 'permissions error'
+ end
+
+ context 'when user has permission' do
+ before do
+ alert.project.add_developer(user)
+ end
+
+ it 'creates a todo' do
+ expect { result }.to change { Todo.count }.by(1)
+ end
+
+ it 'returns the alert and todo in the payload', :aggregate_failures do
+ expect(result.success?).to be(true)
+ expect(result.payload[:alert][:id]).to be(alert.id)
+ expect(result.payload[:todo][:id]).to be(Todo.last.id)
+ end
+
+ context 'when the user has a marked todo for the alert' do
+ let_it_be(:todo_params) do
+ { project: alert.project,
+ target: alert,
+ user: user,
+ action: Todo::MARKED }
+ end
+
+ context 'when todo is pending' do
+ before_all do
+ create(:todo, :pending, **todo_params)
+ end
+
+ it 'does not create a todo' do
+ expect { result }.not_to change { Todo.count }
+ end
+
+ it 'returns an error', :aggregate_failures do
+ expect(result.error?).to be(true)
+ expect(result.message).to be('You already have pending todo for this alert')
+ expect(result.payload[:todo]).to be(nil)
+ expect(result.payload[:alert]).to be(alert)
+ end
+ end
+
+ context 'when todo is done' do
+ before do
+ create(:todo, :done, **todo_params)
+ end
+
+ it { expect(result.success?).to be(true) }
+ it { expect { result }.to change { Todo.count }.by(1) }
+ end
+ end
+ end
+ end
+end
diff --git a/spec/services/alert_management/alerts/update_service_spec.rb b/spec/services/alert_management/alerts/update_service_spec.rb
index e185e67c5cf..91b02325bad 100644
--- a/spec/services/alert_management/alerts/update_service_spec.rb
+++ b/spec/services/alert_management/alerts/update_service_spec.rb
@@ -2,11 +2,12 @@
require 'spec_helper'
-describe AlertManagement::Alerts::UpdateService do
+RSpec.describe AlertManagement::Alerts::UpdateService do
let_it_be(:user_with_permissions) { create(:user) }
+ let_it_be(:other_user_with_permissions) { create(:user) }
let_it_be(:user_without_permissions) { create(:user) }
- let_it_be(:alert, reload: true) { create(:alert_management_alert) }
- let_it_be(:project) { alert.project }
+ let_it_be(:project) { create(:project) }
+ let_it_be(:alert, reload: true) { create(:alert_management_alert, :triggered, project: project) }
let(:current_user) { user_with_permissions }
let(:params) { {} }
@@ -15,119 +16,225 @@ describe AlertManagement::Alerts::UpdateService do
before_all do
project.add_developer(user_with_permissions)
+ project.add_developer(other_user_with_permissions)
end
describe '#execute' do
+ shared_examples 'does not add a todo' do
+ specify { expect { response }.not_to change(Todo, :count) }
+ end
+
+ shared_examples 'does not add a system note' do
+ specify { expect { response }.not_to change(Note, :count) }
+ end
+
+ shared_examples 'adds a system note' do
+ specify { expect { response }.to change { alert.reload.notes.count }.by(1) }
+ end
+
+ shared_examples 'error response' do |message|
+ it_behaves_like 'does not add a todo'
+ it_behaves_like 'does not add a system note'
+
+ it 'has an informative message' do
+ expect(response).to be_error
+ expect(response.message).to eq(message)
+ end
+ end
+
subject(:response) { service.execute }
context 'when the current_user is nil' do
let(:current_user) { nil }
- it 'results in an error' do
- expect(response).to be_error
- expect(response.message).to eq('You have no permissions')
- end
+ it_behaves_like 'error response', 'You have no permissions'
end
- context 'when user does not have permission to update alerts' do
+ context 'when current_user does not have permission to update alerts' do
let(:current_user) { user_without_permissions }
- it 'results in an error' do
- expect(response).to be_error
- expect(response.message).to eq('You have no permissions')
- end
+ it_behaves_like 'error response', 'You have no permissions'
end
context 'when no parameters are included' do
- it 'results in an error' do
- expect(response).to be_error
- expect(response.message).to eq('Please provide attributes to update')
- end
+ it_behaves_like 'error response', 'Please provide attributes to update'
end
- context 'when an error occures during update' do
+ context 'when an error occurs during update' do
let(:params) { { title: nil } }
- it 'results in an error' do
- expect { response }.not_to change { alert.reload.notes.count }
- expect(response).to be_error
- expect(response.message).to eq("Title can't be blank")
- end
+ it_behaves_like 'error response', "Title can't be blank"
end
- context 'when a model attribute is included without assignees' do
- let(:params) { { title: 'This is an updated alert.' } }
+ shared_examples 'title update' do
+ it_behaves_like 'does not add a todo'
+ it_behaves_like 'does not add a system note'
it 'updates the attribute' do
original_title = alert.title
- expect { response }.to change { alert.title }.from(original_title).to(params[:title])
+ expect { response }.to change { alert.title }.from(original_title).to(expected_title)
expect(response).to be_success
end
+ end
- it 'skips adding a todo' do
- expect { response }.not_to change(Todo, :count)
- end
+ context 'when a model attribute is included without assignees' do
+ let(:params) { { title: 'This is an updated alert.' } }
+ let(:expected_title) { params[:title] }
+
+ it_behaves_like 'title update'
+ end
+
+ context 'when alert is resolved and another existing open alert' do
+ let!(:alert) { create(:alert_management_alert, :resolved, project: project) }
+ let!(:existing_alert) { create(:alert_management_alert, :triggered, project: project) }
+
+ let(:params) { { title: 'This is an updated alert.' } }
+ let(:expected_title) { params[:title] }
+
+ it_behaves_like 'title update'
end
context 'when assignees are included' do
- let(:params) { { assignees: [user_with_permissions] } }
+ shared_examples 'adds a todo' do
+ let(:assignee) { expected_assignees.first }
- after do
- alert.assignees = []
+ specify do
+ expect { response }.to change { assignee.reload.todos.count }.by(1)
+ expect(assignee.todos.last.author).to eq(current_user)
+ end
end
- it 'assigns the user' do
- expect { response }.to change { alert.reload.assignees }.from([]).to(params[:assignees])
- expect(response).to be_success
+ shared_examples 'successful assignment' do
+ it_behaves_like 'adds a system note'
+ it_behaves_like 'adds a todo'
+
+ after do
+ alert.assignees = []
+ end
+
+ specify do
+ expect { response }.to change { alert.reload.assignees }.from([]).to(expected_assignees)
+ expect(response).to be_success
+ end
+ end
+
+ let(:expected_assignees) { params[:assignees] }
+
+ context 'when the assignee is the current user' do
+ let(:params) { { assignees: [current_user] } }
+
+ it_behaves_like 'successful assignment'
end
- it 'creates a system note for the assignment' do
- expect { response }.to change { alert.reload.notes.count }.by(1)
+ context 'when the assignee has read permissions' do
+ let(:params) { { assignees: [other_user_with_permissions] } }
+
+ it_behaves_like 'successful assignment'
end
- it 'adds a todo' do
- expect { response }.to change { Todo.where(user: user_with_permissions).count }.by(1)
+ context 'when the assignee does not have read permissions' do
+ let(:params) { { assignees: [user_without_permissions] } }
+
+ it_behaves_like 'error response', 'Assignee has no permissions'
end
- context 'when current user is not the assignee' do
- let(:assignee_user) { create(:user) }
- let(:params) { { assignees: [assignee_user] } }
+ context 'when user is already assigned' do
+ let(:params) { { assignees: [user_with_permissions] } }
- it 'skips adding todo for assignee without permission to read alert' do
- expect { response }.not_to change(Todo, :count)
+ before do
+ alert.assignees << user_with_permissions
end
- context 'when assignee has read permission' do
- before do
- project.add_developer(assignee_user)
- end
+ it_behaves_like 'does not add a system note'
+ # TODO: We should not add another todo in this scenario
+ it_behaves_like 'adds a todo'
+ end
- it 'adds a todo' do
- response
+ context 'with multiple users included' do
+ let(:params) { { assignees: [user_with_permissions, user_without_permissions] } }
+ let(:expected_assignees) { [user_with_permissions] }
- expect(Todo.first.author).to eq(current_user)
- end
+ it_behaves_like 'successful assignment'
+ end
+ end
+
+ context 'when a status is included' do
+ let(:params) { { status: new_status } }
+ let(:new_status) { AlertManagement::Alert::STATUSES[:acknowledged] }
+
+ it 'successfully changes the status' do
+ expect { response }.to change { alert.acknowledged? }.to(true)
+ expect(response).to be_success
+ expect(response.payload[:alert]).to eq(alert)
+ end
+
+ it_behaves_like 'adds a system note'
+
+ context 'with unknown status' do
+ let(:new_status) { -1 }
+
+ it_behaves_like 'error response', 'Invalid status'
+ end
+
+ context 'with resolving status' do
+ let(:new_status) { AlertManagement::Alert::STATUSES[:resolved] }
+
+ it 'changes the status' do
+ expect { response }.to change { alert.resolved? }.to(true)
+ end
+
+ it "resolves the current user's related todos" do
+ todo = create(:todo, :pending, target: alert, user: current_user, project: alert.project)
+
+ expect { response }.to change { todo.reload.state }.from('pending').to('done')
+ end
+ end
+
+ context 'with an opening status and existing open alert' do
+ let_it_be(:alert) { create(:alert_management_alert, :resolved, :with_fingerprint, project: project) }
+ let_it_be(:existing_alert) { create(:alert_management_alert, :triggered, fingerprint: alert.fingerprint, project: project) }
+ let_it_be(:url) { Gitlab::Routing.url_helpers.details_project_alert_management_path(project, existing_alert) }
+ let_it_be(:link) { ActionController::Base.helpers.link_to(_('alert'), url) }
+
+ let(:message) do
+ "An #{link} with the same fingerprint is already open. " \
+ 'To change the status of this alert, resolve the linked alert.'
end
- context 'when current_user is nil' do
- let(:current_user) { nil }
+ it_behaves_like 'does not add a todo'
+ it_behaves_like 'does not add a system note'
+
+ it 'has an informative message' do
+ expect(response).to be_error
+ expect(response.message).to eq(message)
+ end
- it 'skips adding todo if current_user is nil' do
- project.add_developer(assignee_user)
+ context 'fingerprints are blank' do
+ let_it_be(:alert) { create(:alert_management_alert, :resolved, project: project, fingerprint: nil) }
+ let_it_be(:existing_alert) { create(:alert_management_alert, :triggered, fingerprint: alert.fingerprint, project: project) }
- expect { response }.not_to change(Todo, :count)
+ it 'successfully changes the status' do
+ expect { response }.to change { alert.acknowledged? }.to(true)
+ expect(response).to be_success
+ expect(response.payload[:alert]).to eq(alert)
end
+
+ it_behaves_like 'adds a system note'
end
end
- context 'with multiple users included' do
- let(:params) { { assignees: [user_with_permissions, user_without_permissions] } }
+ context 'two existing closed alerts' do
+ let_it_be(:alert) { create(:alert_management_alert, :resolved, :with_fingerprint, project: project) }
+ let_it_be(:existing_alert) { create(:alert_management_alert, :resolved, fingerprint: alert.fingerprint, project: project) }
- it 'assigns the first permissioned user' do
- expect { response }.to change { alert.reload.assignees }.from([]).to([user_with_permissions])
+ it 'successfully changes the status' do
+ expect { response }.to change { alert.acknowledged? }.to(true)
expect(response).to be_success
+ expect(response.payload[:alert]).to eq(alert)
end
+
+ it_behaves_like 'adds a system note'
end
end
end
diff --git a/spec/services/alert_management/create_alert_issue_service_spec.rb b/spec/services/alert_management/create_alert_issue_service_spec.rb
index 9bc8b731dc1..a8f2b4ee09c 100644
--- a/spec/services/alert_management/create_alert_issue_service_spec.rb
+++ b/spec/services/alert_management/create_alert_issue_service_spec.rb
@@ -4,19 +4,18 @@ require 'spec_helper'
RSpec.describe AlertManagement::CreateAlertIssueService do
let_it_be(:user) { create(:user) }
- let_it_be(:project) { create(:project) }
+ let_it_be(:group) { create(:group) }
+ let_it_be(:project) { create(:project, group: group) }
let_it_be(:payload) do
{
- 'annotations' => {
- 'title' => 'Alert title'
- },
'startsAt' => '2020-04-27T10:10:22.265949279Z',
'generatorURL' => 'http://8d467bd4607a:9090/graph?g0.expr=vector%281%29&g0.tab=1'
}
end
let_it_be(:generic_alert, reload: true) { create(:alert_management_alert, :triggered, project: project, payload: payload) }
- let_it_be(:prometheus_alert) { create(:alert_management_alert, :triggered, :prometheus, project: project, payload: payload) }
+ let_it_be(:prometheus_alert, reload: true) { create(:alert_management_alert, :triggered, :prometheus, project: project, payload: payload) }
let(:alert) { generic_alert }
+ let(:alert_presenter) { alert.present }
let(:created_issue) { Issue.last! }
describe '#execute' do
@@ -29,7 +28,7 @@ RSpec.describe AlertManagement::CreateAlertIssueService do
.and_return(can_create)
end
- shared_examples 'creating an alert' do
+ shared_examples 'creating an alert issue' do
it 'creates an issue' do
expect { execute }.to change { project.issues.count }.by(1)
end
@@ -48,11 +47,27 @@ RSpec.describe AlertManagement::CreateAlertIssueService do
expect(alert.reload.issue_id).to eq(created_issue.id)
end
- it 'sets issue author to the current user' do
+ it 'creates a system note' do
+ expect { execute }.to change { alert.reload.notes.count }.by(1)
+ end
+ end
+
+ shared_examples 'setting an issue attributes' do
+ before do
execute
+ end
+ it 'sets issue author to the current user' do
expect(created_issue.author).to eq(user)
end
+
+ it 'sets the issue title' do
+ expect(created_issue.title).to eq(alert.title)
+ end
+
+ it 'sets the issue description' do
+ expect(created_issue.description).to include(alert_presenter.issue_summary_markdown.strip)
+ end
end
context 'when a user is allowed to create an issue' do
@@ -69,27 +84,33 @@ RSpec.describe AlertManagement::CreateAlertIssueService do
context 'when the alert is prometheus alert' do
let(:alert) { prometheus_alert }
+ let(:issue) { subject.payload[:issue] }
- it_behaves_like 'creating an alert'
+ it_behaves_like 'creating an alert issue'
+ it_behaves_like 'setting an issue attributes'
+ it_behaves_like 'create alert issue sets issue labels'
end
context 'when the alert is generic' do
let(:alert) { generic_alert }
+ let(:issue) { subject.payload[:issue] }
- it_behaves_like 'creating an alert'
+ it_behaves_like 'creating an alert issue'
+ it_behaves_like 'setting an issue attributes'
+ it_behaves_like 'create alert issue sets issue labels'
end
context 'when issue cannot be created' do
- let(:alert) { prometheus_alert }
+ let(:alert) { generic_alert }
before do
- # set invalid payload for Prometheus alert
- alert.update!(payload: {})
+ # Invalid alert
+ alert.update_columns(title: '')
end
it 'has an unsuccessful status' do
expect(execute).to be_error
- expect(execute.message).to eq('invalid alert')
+ expect(execute.message).to eq("Title can't be blank")
end
end
diff --git a/spec/services/alert_management/process_prometheus_alert_service_spec.rb b/spec/services/alert_management/process_prometheus_alert_service_spec.rb
index 5b4da5e9077..0ce88f6b5b7 100644
--- a/spec/services/alert_management/process_prometheus_alert_service_spec.rb
+++ b/spec/services/alert_management/process_prometheus_alert_service_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
RSpec.describe AlertManagement::ProcessPrometheusAlertService do
- let_it_be(:project) { create(:project) }
+ let_it_be(:project) { create(:project, :repository) }
before do
allow(ProjectServiceWorker).to receive(:perform_async)
@@ -35,26 +35,31 @@ RSpec.describe AlertManagement::ProcessPrometheusAlertService do
}
end
- context 'when Prometheus alert status is firing' do
- let(:status) { 'firing' }
+ let(:status) { 'firing' }
+ context 'when Prometheus alert status is firing' do
context 'when alert with the same fingerprint already exists' do
- let!(:alert) { create(:alert_management_alert, :resolved, project: project, fingerprint: parsed_alert.gitlab_fingerprint) }
+ let!(:alert) { create(:alert_management_alert, project: project, fingerprint: parsed_alert.gitlab_fingerprint) }
+
+ it_behaves_like 'adds an alert management alert event'
+
+ context 'existing alert is resolved' do
+ let!(:alert) { create(:alert_management_alert, :resolved, project: project, fingerprint: parsed_alert.gitlab_fingerprint) }
- it 'increases alert events count' do
- expect { execute }.to change { alert.reload.events }.by(1)
+ it_behaves_like 'creates an alert management alert'
end
- context 'when status can be changed' do
- it 'changes status to triggered' do
- expect { execute }.to change { alert.reload.triggered? }.to(true)
- end
+ context 'existing alert is ignored' do
+ let!(:alert) { create(:alert_management_alert, :ignored, project: project, fingerprint: parsed_alert.gitlab_fingerprint) }
+
+ it_behaves_like 'adds an alert management alert event'
end
- it 'does not executes the alert service hooks' do
- expect(alert).not_to receive(:execute_services)
+ context 'two existing alerts, one resolved one open' do
+ let!(:resolved_alert) { create(:alert_management_alert, :resolved, project: project, fingerprint: parsed_alert.gitlab_fingerprint) }
+ let!(:alert) { create(:alert_management_alert, project: project, fingerprint: parsed_alert.gitlab_fingerprint) }
- subject
+ it_behaves_like 'adds an alert management alert event'
end
context 'when status change did not succeed' do
@@ -73,23 +78,11 @@ RSpec.describe AlertManagement::ProcessPrometheusAlertService do
execute
end
end
-
- it { is_expected.to be_success }
end
context 'when alert does not exist' do
context 'when alert can be created' do
- it 'creates a new alert' do
- expect { execute }.to change { AlertManagement::Alert.where(project: project).count }.by(1)
- end
-
- it 'executes the alert service hooks' do
- slack_service = create(:service, type: 'SlackService', project: project, alert_events: true, active: true)
-
- subject
-
- expect(ProjectServiceWorker).to have_received(:perform_async).with(slack_service.id, an_instance_of(Hash))
- end
+ it_behaves_like 'creates an alert management alert'
end
context 'when alert cannot be created' do
@@ -123,6 +116,31 @@ RSpec.describe AlertManagement::ProcessPrometheusAlertService do
it 'resolves an existing alert' do
expect { execute }.to change { alert.reload.resolved? }.to(true)
end
+
+ [true, false].each do |state_tracking_enabled|
+ context 'existing issue' do
+ before do
+ stub_feature_flags(track_resource_state_change_events: state_tracking_enabled)
+ end
+
+ let!(:alert) { create(:alert_management_alert, :with_issue, project: project, fingerprint: parsed_alert.gitlab_fingerprint) }
+
+ it 'closes the issue' do
+ issue = alert.issue
+
+ expect { execute }
+ .to change { issue.reload.state }
+ .from('opened')
+ .to('closed')
+ end
+
+ if state_tracking_enabled
+ specify { expect { execute }.to change(ResourceStateEvent, :count).by(1) }
+ else
+ specify { expect { execute }.to change(Note, :count).by(1) }
+ end
+ end
+ end
end
context 'when status change did not succeed' do
@@ -144,6 +162,33 @@ RSpec.describe AlertManagement::ProcessPrometheusAlertService do
it { is_expected.to be_success }
end
+
+ context 'environment given' do
+ let(:environment) { create(:environment, project: project) }
+
+ it 'sets the environment' do
+ payload['labels']['gitlab_environment_name'] = environment.name
+ execute
+
+ alert = project.alert_management_alerts.last
+
+ expect(alert.environment).to eq(environment)
+ end
+ end
+
+ context 'prometheus alert given' do
+ let(:prometheus_alert) { create(:prometheus_alert, project: project) }
+
+ it 'sets the prometheus alert and environment' do
+ payload['labels']['gitlab_alert_id'] = prometheus_alert.prometheus_metric_id
+ execute
+
+ alert = project.alert_management_alerts.last
+
+ expect(alert.prometheus_alert).to eq(prometheus_alert)
+ expect(alert.environment).to eq(prometheus_alert.environment)
+ end
+ end
end
context 'when alert payload is invalid' do
diff --git a/spec/services/alert_management/update_alert_status_service_spec.rb b/spec/services/alert_management/update_alert_status_service_spec.rb
deleted file mode 100644
index b287d0d1614..00000000000
--- a/spec/services/alert_management/update_alert_status_service_spec.rb
+++ /dev/null
@@ -1,66 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-describe AlertManagement::UpdateAlertStatusService do
- let(:project) { alert.project }
- let_it_be(:user) { build(:user) }
-
- let_it_be(:alert, reload: true) do
- create(:alert_management_alert, :triggered)
- end
-
- let(:service) { described_class.new(alert, user, new_status) }
-
- describe '#execute' do
- shared_examples 'update failure' do |error_message|
- it 'returns an error' do
- expect(response).to be_error
- expect(response.message).to eq(error_message)
- expect(response.payload[:alert]).to eq(alert)
- end
-
- it 'does not update the status' do
- expect { response }.not_to change { alert.status }
- end
- end
-
- let(:new_status) { Types::AlertManagement::StatusEnum.values['ACKNOWLEDGED'].value }
- let(:can_update) { true }
-
- subject(:response) { service.execute }
-
- before do
- allow(user).to receive(:can?)
- .with(:update_alert_management_alert, project)
- .and_return(can_update)
- end
-
- it 'returns success' do
- expect(response).to be_success
- expect(response.payload[:alert]).to eq(alert)
- end
-
- it 'updates the status' do
- expect { response }.to change { alert.acknowledged? }.to(true)
- end
-
- context 'when user has no permissions' do
- let(:can_update) { false }
-
- include_examples 'update failure', _('You have no permissions')
- end
-
- context 'with no status' do
- let(:new_status) { nil }
-
- include_examples 'update failure', _('Invalid status')
- end
-
- context 'with unknown status' do
- let(:new_status) { -1 }
-
- include_examples 'update failure', _('Invalid status')
- end
- end
-end
diff --git a/spec/services/application_settings/update_service_spec.rb b/spec/services/application_settings/update_service_spec.rb
index 3a37cbc3522..e5060fa2eeb 100644
--- a/spec/services/application_settings/update_service_spec.rb
+++ b/spec/services/application_settings/update_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe ApplicationSettings::UpdateService do
+RSpec.describe ApplicationSettings::UpdateService do
include ExternalAuthorizationServiceHelpers
let(:application_settings) { create(:application_setting) }
diff --git a/spec/services/applications/create_service_spec.rb b/spec/services/applications/create_service_spec.rb
index c8134087fa1..58ac723ee55 100644
--- a/spec/services/applications/create_service_spec.rb
+++ b/spec/services/applications/create_service_spec.rb
@@ -2,7 +2,7 @@
require "spec_helper"
-describe ::Applications::CreateService do
+RSpec.describe ::Applications::CreateService do
include TestRequestHelpers
let(:user) { create(:user) }
diff --git a/spec/services/audit_event_service_spec.rb b/spec/services/audit_event_service_spec.rb
index dc86735805c..530d3469481 100644
--- a/spec/services/audit_event_service_spec.rb
+++ b/spec/services/audit_event_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe AuditEventService do
+RSpec.describe AuditEventService do
let(:project) { create(:project) }
let(:user) { create(:user, :with_sign_ins) }
let(:project_member) { create(:project_member, user: user) }
@@ -17,6 +17,7 @@ describe AuditEventService do
it 'creates an event and logs to a file' do
expect(service).to receive(:file_logger).and_return(logger)
expect(logger).to receive(:info).with(author_id: user.id,
+ author_name: user.name,
entity_id: project.id,
entity_type: "Project",
action: :destroy)
@@ -35,6 +36,7 @@ describe AuditEventService do
})
expect(service).to receive(:file_logger).and_return(logger)
expect(logger).to receive(:info).with(author_id: user.id,
+ author_name: user.name,
entity_type: 'Project',
entity_id: project.id,
from: 'true',
@@ -56,6 +58,7 @@ describe AuditEventService do
it 'logs security event to file' do
expect(service).to receive(:file_logger).and_return(logger)
expect(logger).to receive(:info).with(author_id: user.id,
+ author_name: user.name,
entity_type: 'Project',
entity_id: project.id,
action: :destroy)
diff --git a/spec/services/auth/container_registry_authentication_service_spec.rb b/spec/services/auth/container_registry_authentication_service_spec.rb
index 70eb35f0826..8d58c4b27e1 100644
--- a/spec/services/auth/container_registry_authentication_service_spec.rb
+++ b/spec/services/auth/container_registry_authentication_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Auth::ContainerRegistryAuthenticationService do
+RSpec.describe Auth::ContainerRegistryAuthenticationService do
let(:current_project) { nil }
let(:current_user) { nil }
let(:current_params) { {} }
diff --git a/spec/services/authorized_project_update/periodic_recalculate_service_spec.rb b/spec/services/authorized_project_update/periodic_recalculate_service_spec.rb
index 020056da36e..c776e013fdf 100644
--- a/spec/services/authorized_project_update/periodic_recalculate_service_spec.rb
+++ b/spec/services/authorized_project_update/periodic_recalculate_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe AuthorizedProjectUpdate::PeriodicRecalculateService do
+RSpec.describe AuthorizedProjectUpdate::PeriodicRecalculateService do
subject(:service) { described_class.new }
describe '#execute' do
diff --git a/spec/services/authorized_project_update/project_create_service_spec.rb b/spec/services/authorized_project_update/project_create_service_spec.rb
index 5b3e36af766..891800bfb87 100644
--- a/spec/services/authorized_project_update/project_create_service_spec.rb
+++ b/spec/services/authorized_project_update/project_create_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe AuthorizedProjectUpdate::ProjectCreateService do
+RSpec.describe AuthorizedProjectUpdate::ProjectCreateService do
let_it_be(:group_parent) { create(:group, :private) }
let_it_be(:group) { create(:group, :private, parent: group_parent) }
let_it_be(:group_child) { create(:group, :private, parent: group) }
diff --git a/spec/services/authorized_project_update/project_group_link_create_service_spec.rb b/spec/services/authorized_project_update/project_group_link_create_service_spec.rb
new file mode 100644
index 00000000000..d30d9f1e766
--- /dev/null
+++ b/spec/services/authorized_project_update/project_group_link_create_service_spec.rb
@@ -0,0 +1,190 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe AuthorizedProjectUpdate::ProjectGroupLinkCreateService do
+ let_it_be(:group_parent) { create(:group, :private) }
+ let_it_be(:group) { create(:group, :private, parent: group_parent) }
+ let_it_be(:group_child) { create(:group, :private, parent: group) }
+
+ let_it_be(:parent_group_user) { create(:user) }
+ let_it_be(:group_user) { create(:user) }
+
+ let_it_be(:project) { create(:project, :private, group: create(:group, :private)) }
+
+ let(:access_level) { Gitlab::Access::MAINTAINER }
+
+ subject(:service) { described_class.new(project, group) }
+
+ describe '#perform' do
+ context 'direct group members' do
+ before do
+ create(:group_member, access_level: access_level, group: group, user: group_user)
+ ProjectAuthorization.delete_all
+ end
+
+ it 'creates project authorization' do
+ expect { service.execute }.to(
+ change { ProjectAuthorization.count }.from(0).to(1))
+
+ project_authorization = ProjectAuthorization.where(
+ project_id: project.id,
+ user_id: group_user.id,
+ access_level: access_level)
+
+ expect(project_authorization).to exist
+ end
+ end
+
+ context 'inherited group members' do
+ before do
+ create(:group_member, access_level: access_level, group: group_parent, user: parent_group_user)
+ ProjectAuthorization.delete_all
+ end
+
+ it 'creates project authorization' do
+ expect { service.execute }.to(
+ change { ProjectAuthorization.count }.from(0).to(1))
+
+ project_authorization = ProjectAuthorization.where(
+ project_id: project.id,
+ user_id: parent_group_user.id,
+ access_level: access_level)
+ expect(project_authorization).to exist
+ end
+ end
+
+ context 'membership overrides' do
+ before do
+ create(:group_member, access_level: Gitlab::Access::REPORTER, group: group_parent, user: group_user)
+ create(:group_member, access_level: Gitlab::Access::DEVELOPER, group: group, user: group_user)
+ ProjectAuthorization.delete_all
+ end
+
+ it 'creates project authorization' do
+ expect { service.execute }.to(
+ change { ProjectAuthorization.count }.from(0).to(1))
+
+ project_authorization = ProjectAuthorization.where(
+ project_id: project.id,
+ user_id: group_user.id,
+ access_level: Gitlab::Access::DEVELOPER)
+ expect(project_authorization).to exist
+ end
+ end
+
+ context 'no group member' do
+ it 'does not create project authorization' do
+ expect { service.execute }.not_to(
+ change { ProjectAuthorization.count }.from(0))
+ end
+ end
+
+ context 'unapproved access requests' do
+ before do
+ create(:group_member, :guest, :access_request, user: group_user, group: group)
+ end
+
+ it 'does not create project authorization' do
+ expect { service.execute }.not_to(
+ change { ProjectAuthorization.count }.from(0))
+ end
+ end
+
+ context 'project has more users than BATCH_SIZE' do
+ let(:batch_size) { 2 }
+ let(:users) { create_list(:user, batch_size + 1 ) }
+
+ before do
+ stub_const("#{described_class.name}::BATCH_SIZE", batch_size)
+
+ users.each do |user|
+ create(:group_member, access_level: access_level, group: group_parent, user: user)
+ end
+
+ ProjectAuthorization.delete_all
+ end
+
+ it 'bulk creates project authorizations in batches' do
+ users.each_slice(batch_size) do |batch|
+ attributes = batch.map do |user|
+ { user_id: user.id, project_id: project.id, access_level: access_level }
+ end
+
+ expect(ProjectAuthorization).to(
+ receive(:insert_all).with(array_including(attributes)).and_call_original)
+ end
+
+ expect { service.execute }.to(
+ change { ProjectAuthorization.count }.from(0).to(batch_size + 1))
+ end
+ end
+
+ context 'users have existing project authorizations' do
+ before do
+ create(:group_member, access_level: access_level, group: group, user: group_user)
+ ProjectAuthorization.delete_all
+
+ create(:project_authorization, user_id: group_user.id,
+ project_id: project.id,
+ access_level: existing_access_level)
+ end
+
+ context 'when access level is the same' do
+ let(:existing_access_level) { access_level }
+
+ it 'does not create project authorization' do
+ project_authorization = ProjectAuthorization.where(
+ project_id: project.id,
+ user_id: group_user.id,
+ access_level: existing_access_level)
+
+ expect(ProjectAuthorization).not_to receive(:insert_all)
+
+ expect { service.execute }.not_to(
+ change { project_authorization.reload.exists? }.from(true))
+ end
+ end
+
+ context 'when existing access level is lower' do
+ let(:existing_access_level) { Gitlab::Access::DEVELOPER }
+
+ it 'creates new project authorization' do
+ project_authorization = ProjectAuthorization.where(
+ project_id: project.id,
+ user_id: group_user.id,
+ access_level: access_level)
+
+ expect { service.execute }.to(
+ change { project_authorization.reload.exists? }.from(false).to(true))
+ end
+
+ it 'deletes previous project authorization' do
+ project_authorization = ProjectAuthorization.where(
+ project_id: project.id,
+ user_id: group_user.id,
+ access_level: existing_access_level)
+
+ expect { service.execute }.to(
+ change { project_authorization.reload.exists? }.from(true).to(false))
+ end
+ end
+
+ context 'when existing access level is higher' do
+ let(:existing_access_level) { Gitlab::Access::OWNER }
+
+ it 'does not create project authorization' do
+ project_authorization = ProjectAuthorization.where(
+ project_id: project.id,
+ user_id: group_user.id,
+ access_level: existing_access_level)
+
+ expect(ProjectAuthorization).not_to receive(:insert_all)
+
+ expect { service.execute }.not_to(
+ change { project_authorization.reload.exists? }.from(true))
+ end
+ end
+ end
+ end
+end
diff --git a/spec/services/authorized_project_update/recalculate_for_user_range_service_spec.rb b/spec/services/authorized_project_update/recalculate_for_user_range_service_spec.rb
index 28cbda6f4fd..a4637b6ba1c 100644
--- a/spec/services/authorized_project_update/recalculate_for_user_range_service_spec.rb
+++ b/spec/services/authorized_project_update/recalculate_for_user_range_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe AuthorizedProjectUpdate::RecalculateForUserRangeService do
+RSpec.describe AuthorizedProjectUpdate::RecalculateForUserRangeService do
describe '#execute' do
let_it_be(:users) { create_list(:user, 2) }
diff --git a/spec/services/auto_merge/base_service_spec.rb b/spec/services/auto_merge/base_service_spec.rb
index e08e1d670bf..98fa6012089 100644
--- a/spec/services/auto_merge/base_service_spec.rb
+++ b/spec/services/auto_merge/base_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe AutoMerge::BaseService do
+RSpec.describe AutoMerge::BaseService do
let(:project) { create(:project) }
let(:user) { create(:user) }
let(:service) { described_class.new(project, user, params) }
@@ -51,7 +51,7 @@ describe AutoMerge::BaseService do
expect(merge_request.merge_params['commit_message']).to eq("Merge branch 'patch-12' into 'master'")
expect(merge_request.merge_params['sha']).to eq('200fcc9c260f7219eaf0daba87d818f0922c5b18')
expect(merge_request.merge_params['should_remove_source_branch']).to eq(false)
- expect(merge_request.squash).to eq(false)
+ expect(merge_request.squash_on_merge?).to eq(false)
expect(merge_request.merge_params['squash_commit_message']).to eq('Update README.md')
end
end
diff --git a/spec/services/auto_merge/merge_when_pipeline_succeeds_service_spec.rb b/spec/services/auto_merge/merge_when_pipeline_succeeds_service_spec.rb
index b6e8d3c636a..3bf59f6a2d1 100644
--- a/spec/services/auto_merge/merge_when_pipeline_succeeds_service_spec.rb
+++ b/spec/services/auto_merge/merge_when_pipeline_succeeds_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe AutoMerge::MergeWhenPipelineSucceedsService do
+RSpec.describe AutoMerge::MergeWhenPipelineSucceedsService do
let_it_be(:user) { create(:user) }
let_it_be(:project) { create(:project, :repository) }
@@ -69,6 +69,7 @@ describe AutoMerge::MergeWhenPipelineSucceedsService do
before do
allow(merge_request)
.to receive_messages(head_pipeline: pipeline, actual_head_pipeline: pipeline)
+ expect(MailScheduler::NotificationServiceWorker).to receive(:perform_async).with('merge_when_pipeline_succeeds', merge_request, user).once
service.execute(merge_request)
end
@@ -90,6 +91,18 @@ describe AutoMerge::MergeWhenPipelineSucceedsService do
end
end
+ context 'without feature enabled' do
+ it 'does not send notification' do
+ stub_feature_flags(mwps_notification: false)
+
+ allow(merge_request)
+ .to receive_messages(head_pipeline: pipeline, actual_head_pipeline: pipeline)
+ expect(MailScheduler::NotificationServiceWorker).not_to receive(:perform_async)
+
+ service.execute(merge_request)
+ end
+ end
+
context 'already approved' do
let(:service) { described_class.new(project, user, should_remove_source_branch: true) }
let(:build) { create(:ci_build, ref: mr_merge_if_green_enabled.source_branch) }
@@ -106,6 +119,7 @@ describe AutoMerge::MergeWhenPipelineSucceedsService do
it 'updates the merge params' do
expect(SystemNoteService).not_to receive(:merge_when_pipeline_succeeds)
+ expect(MailScheduler::NotificationServiceWorker).not_to receive(:perform_async).with('merge_when_pipeline_succeeds', any_args)
service.execute(mr_merge_if_green_enabled)
expect(mr_merge_if_green_enabled.merge_params).to have_key('should_remove_source_branch')
diff --git a/spec/services/auto_merge_service_spec.rb b/spec/services/auto_merge_service_spec.rb
index bab69fb4aa3..eab95973e1b 100644
--- a/spec/services/auto_merge_service_spec.rb
+++ b/spec/services/auto_merge_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe AutoMergeService do
+RSpec.describe AutoMergeService do
let_it_be(:project) { create(:project, :repository) }
let_it_be(:user) { create(:user) }
let(:service) { described_class.new(project, user) }
diff --git a/spec/services/award_emojis/add_service_spec.rb b/spec/services/award_emojis/add_service_spec.rb
index 4bcb5fa039f..85c39015614 100644
--- a/spec/services/award_emojis/add_service_spec.rb
+++ b/spec/services/award_emojis/add_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe AwardEmojis::AddService do
+RSpec.describe AwardEmojis::AddService do
let_it_be(:user) { create(:user) }
let_it_be(:project) { create(:project) }
let_it_be(:awardable) { create(:note, project: project) }
diff --git a/spec/services/award_emojis/collect_user_emoji_service_spec.rb b/spec/services/award_emojis/collect_user_emoji_service_spec.rb
index a0dea31b403..bf5aa0eb9ef 100644
--- a/spec/services/award_emojis/collect_user_emoji_service_spec.rb
+++ b/spec/services/award_emojis/collect_user_emoji_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe AwardEmojis::CollectUserEmojiService do
+RSpec.describe AwardEmojis::CollectUserEmojiService do
describe '#execute' do
it 'returns an Array containing the awarded emoji names' do
user = create(:user)
diff --git a/spec/services/award_emojis/destroy_service_spec.rb b/spec/services/award_emojis/destroy_service_spec.rb
index f411345560e..2aba078b638 100644
--- a/spec/services/award_emojis/destroy_service_spec.rb
+++ b/spec/services/award_emojis/destroy_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe AwardEmojis::DestroyService do
+RSpec.describe AwardEmojis::DestroyService do
let_it_be(:user) { create(:user) }
let_it_be(:awardable) { create(:note) }
let_it_be(:project) { awardable.project }
diff --git a/spec/services/award_emojis/toggle_service_spec.rb b/spec/services/award_emojis/toggle_service_spec.rb
index 069bdfcb99f..a7feeed50c6 100644
--- a/spec/services/award_emojis/toggle_service_spec.rb
+++ b/spec/services/award_emojis/toggle_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe AwardEmojis::ToggleService do
+RSpec.describe AwardEmojis::ToggleService do
let_it_be(:user) { create(:user) }
let_it_be(:project) { create(:project, :public) }
let_it_be(:awardable) { create(:note, project: project) }
diff --git a/spec/services/base_container_service_spec.rb b/spec/services/base_container_service_spec.rb
index 47cfb387e25..1de79eec702 100644
--- a/spec/services/base_container_service_spec.rb
+++ b/spec/services/base_container_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe BaseContainerService do
+RSpec.describe BaseContainerService do
let(:project) { Project.new }
let(:user) { User.new }
diff --git a/spec/services/base_count_service_spec.rb b/spec/services/base_count_service_spec.rb
index 275bec9982d..18cab2e8e9a 100644
--- a/spec/services/base_count_service_spec.rb
+++ b/spec/services/base_count_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe BaseCountService, :use_clean_rails_memory_store_caching do
+RSpec.describe BaseCountService, :use_clean_rails_memory_store_caching do
let(:service) { described_class.new }
describe '#relation_for_count' do
diff --git a/spec/services/boards/create_service_spec.rb b/spec/services/boards/create_service_spec.rb
index 7d4fb04c6c0..f6a9f0903ce 100644
--- a/spec/services/boards/create_service_spec.rb
+++ b/spec/services/boards/create_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Boards::CreateService do
+RSpec.describe Boards::CreateService do
describe '#execute' do
context 'when board parent is a project' do
let(:parent) { create(:project) }
diff --git a/spec/services/boards/issues/create_service_spec.rb b/spec/services/boards/issues/create_service_spec.rb
index 3520630dd83..9a6b48c13bf 100644
--- a/spec/services/boards/issues/create_service_spec.rb
+++ b/spec/services/boards/issues/create_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Boards::Issues::CreateService do
+RSpec.describe Boards::Issues::CreateService do
describe '#execute' do
let(:project) { create(:project) }
let(:board) { create(:board, project: project) }
diff --git a/spec/services/boards/issues/list_service_spec.rb b/spec/services/boards/issues/list_service_spec.rb
index c46ab004af6..29b49db42f9 100644
--- a/spec/services/boards/issues/list_service_spec.rb
+++ b/spec/services/boards/issues/list_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Boards::Issues::ListService do
+RSpec.describe Boards::Issues::ListService do
describe '#execute' do
context 'when parent is a project' do
let(:user) { create(:user) }
diff --git a/spec/services/boards/issues/move_service_spec.rb b/spec/services/boards/issues/move_service_spec.rb
index b9ebbc30c1a..01a3ec72987 100644
--- a/spec/services/boards/issues/move_service_spec.rb
+++ b/spec/services/boards/issues/move_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Boards::Issues::MoveService do
+RSpec.describe Boards::Issues::MoveService do
describe '#execute' do
context 'when parent is a project' do
let(:user) { create(:user) }
diff --git a/spec/services/boards/list_service_spec.rb b/spec/services/boards/list_service_spec.rb
index 4eb023907fa..7c94332a78d 100644
--- a/spec/services/boards/list_service_spec.rb
+++ b/spec/services/boards/list_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Boards::ListService do
+RSpec.describe Boards::ListService do
describe '#execute' do
context 'when board parent is a project' do
let(:parent) { create(:project) }
diff --git a/spec/services/boards/lists/create_service_spec.rb b/spec/services/boards/lists/create_service_spec.rb
index 295ec2c8156..f3d4e62eeca 100644
--- a/spec/services/boards/lists/create_service_spec.rb
+++ b/spec/services/boards/lists/create_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Boards::Lists::CreateService do
+RSpec.describe Boards::Lists::CreateService do
describe '#execute' do
shared_examples 'creating board lists' do
let(:user) { create(:user) }
diff --git a/spec/services/boards/lists/destroy_service_spec.rb b/spec/services/boards/lists/destroy_service_spec.rb
index b936ef3837f..4c512b96065 100644
--- a/spec/services/boards/lists/destroy_service_spec.rb
+++ b/spec/services/boards/lists/destroy_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Boards::Lists::DestroyService do
+RSpec.describe Boards::Lists::DestroyService do
describe '#execute' do
context 'when board parent is a project' do
let(:project) { create(:project) }
diff --git a/spec/services/boards/lists/generate_service_spec.rb b/spec/services/boards/lists/generate_service_spec.rb
index 77b42392470..9597c8e0f54 100644
--- a/spec/services/boards/lists/generate_service_spec.rb
+++ b/spec/services/boards/lists/generate_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Boards::Lists::GenerateService do
+RSpec.describe Boards::Lists::GenerateService do
describe '#execute' do
let(:project) { create(:project) }
let(:board) { create(:board, project: project) }
diff --git a/spec/services/boards/lists/list_service_spec.rb b/spec/services/boards/lists/list_service_spec.rb
index 2535f339495..3d71c467e96 100644
--- a/spec/services/boards/lists/list_service_spec.rb
+++ b/spec/services/boards/lists/list_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Boards::Lists::ListService do
+RSpec.describe Boards::Lists::ListService do
let(:user) { create(:user) }
describe '#execute' do
diff --git a/spec/services/boards/lists/move_service_spec.rb b/spec/services/boards/lists/move_service_spec.rb
index f8fc70ef2d6..2861fc48b4d 100644
--- a/spec/services/boards/lists/move_service_spec.rb
+++ b/spec/services/boards/lists/move_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Boards::Lists::MoveService do
+RSpec.describe Boards::Lists::MoveService do
describe '#execute' do
context 'when board parent is a project' do
let(:project) { create(:project) }
diff --git a/spec/services/boards/lists/update_service_spec.rb b/spec/services/boards/lists/update_service_spec.rb
index 243e0fc50ad..cdc7784469a 100644
--- a/spec/services/boards/lists/update_service_spec.rb
+++ b/spec/services/boards/lists/update_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Boards::Lists::UpdateService do
+RSpec.describe Boards::Lists::UpdateService do
let(:user) { create(:user) }
let!(:list) { create(:list, board: board, position: 0) }
diff --git a/spec/services/boards/visits/create_service_spec.rb b/spec/services/boards/visits/create_service_spec.rb
index 203c287f396..a9a8754825b 100644
--- a/spec/services/boards/visits/create_service_spec.rb
+++ b/spec/services/boards/visits/create_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Boards::Visits::CreateService do
+RSpec.describe Boards::Visits::CreateService do
describe '#execute' do
let(:user) { create(:user) }
diff --git a/spec/services/branches/create_service_spec.rb b/spec/services/branches/create_service_spec.rb
index 072a86d17fc..b682a3f26ec 100644
--- a/spec/services/branches/create_service_spec.rb
+++ b/spec/services/branches/create_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Branches::CreateService do
+RSpec.describe Branches::CreateService do
subject(:service) { described_class.new(project, user) }
let_it_be(:project) { create(:project_empty_repo) }
diff --git a/spec/services/branches/delete_merged_service_spec.rb b/spec/services/branches/delete_merged_service_spec.rb
index 5c87f156ec7..2cf0f53c8c3 100644
--- a/spec/services/branches/delete_merged_service_spec.rb
+++ b/spec/services/branches/delete_merged_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Branches::DeleteMergedService do
+RSpec.describe Branches::DeleteMergedService do
include ProjectForksHelper
subject(:service) { described_class.new(project, project.owner) }
diff --git a/spec/services/branches/delete_service_spec.rb b/spec/services/branches/delete_service_spec.rb
index 2219416d94d..f1e7c9340b1 100644
--- a/spec/services/branches/delete_service_spec.rb
+++ b/spec/services/branches/delete_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Branches::DeleteService do
+RSpec.describe Branches::DeleteService do
let(:project) { create(:project, :repository) }
let(:repository) { project.repository }
let(:user) { create(:user) }
@@ -10,6 +10,10 @@ describe Branches::DeleteService do
subject(:service) { described_class.new(project, user) }
shared_examples 'a deleted branch' do |branch_name|
+ before do
+ allow(Ci::RefDeleteUnlockArtifactsWorker).to receive(:perform_async)
+ end
+
it 'removes the branch' do
expect(branch_exists?(branch_name)).to be true
@@ -18,6 +22,12 @@ describe Branches::DeleteService do
expect(result.status).to eq :success
expect(branch_exists?(branch_name)).to be false
end
+
+ it 'calls the RefDeleteUnlockArtifactsWorker' do
+ expect(Ci::RefDeleteUnlockArtifactsWorker).to receive(:perform_async).with(project.id, user.id, "refs/heads/#{branch_name}")
+
+ service.execute(branch_name)
+ end
end
describe '#execute' do
diff --git a/spec/services/branches/diverging_commit_counts_service_spec.rb b/spec/services/branches/diverging_commit_counts_service_spec.rb
index 370da773ab2..34a2b81c831 100644
--- a/spec/services/branches/diverging_commit_counts_service_spec.rb
+++ b/spec/services/branches/diverging_commit_counts_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Branches::DivergingCommitCountsService do
+RSpec.describe Branches::DivergingCommitCountsService do
let(:project) { create(:project, :repository) }
let(:repository) { project.repository }
diff --git a/spec/services/branches/validate_new_service_spec.rb b/spec/services/branches/validate_new_service_spec.rb
index 6d5078d3ccb..02127c8c10d 100644
--- a/spec/services/branches/validate_new_service_spec.rb
+++ b/spec/services/branches/validate_new_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Branches::ValidateNewService do
+RSpec.describe Branches::ValidateNewService do
let(:project) { create(:project, :repository) }
subject(:service) { described_class.new(project) }
diff --git a/spec/services/bulk_push_event_payload_service_spec.rb b/spec/services/bulk_push_event_payload_service_spec.rb
index 661c3540aa0..381c735c003 100644
--- a/spec/services/bulk_push_event_payload_service_spec.rb
+++ b/spec/services/bulk_push_event_payload_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe BulkPushEventPayloadService do
+RSpec.describe BulkPushEventPayloadService do
let(:event) { create(:push_event) }
let(:push_data) do
diff --git a/spec/services/chat_names/authorize_user_service_spec.rb b/spec/services/chat_names/authorize_user_service_spec.rb
index 7f32948daad..b0bb741564d 100644
--- a/spec/services/chat_names/authorize_user_service_spec.rb
+++ b/spec/services/chat_names/authorize_user_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe ChatNames::AuthorizeUserService do
+RSpec.describe ChatNames::AuthorizeUserService do
describe '#execute' do
subject { described_class.new(service, params) }
diff --git a/spec/services/chat_names/find_user_service_spec.rb b/spec/services/chat_names/find_user_service_spec.rb
index 9d26f98cd56..a29b243ad2c 100644
--- a/spec/services/chat_names/find_user_service_spec.rb
+++ b/spec/services/chat_names/find_user_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe ChatNames::FindUserService, :clean_gitlab_redis_shared_state do
+RSpec.describe ChatNames::FindUserService, :clean_gitlab_redis_shared_state do
describe '#execute' do
let(:service) { create(:service) }
diff --git a/spec/services/ci/archive_trace_service_spec.rb b/spec/services/ci/archive_trace_service_spec.rb
index ba94013b574..07ea314debc 100644
--- a/spec/services/ci/archive_trace_service_spec.rb
+++ b/spec/services/ci/archive_trace_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Ci::ArchiveTraceService, '#execute' do
+RSpec.describe Ci::ArchiveTraceService, '#execute' do
subject { described_class.new.execute(job, worker_name: ArchiveTraceWorker.name) }
context 'when job is finished' do
diff --git a/spec/services/ci/build_report_result_service_spec.rb b/spec/services/ci/build_report_result_service_spec.rb
index dbdfc774314..3c1ef5301fc 100644
--- a/spec/services/ci/build_report_result_service_spec.rb
+++ b/spec/services/ci/build_report_result_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Ci::BuildReportResultService do
+RSpec.describe Ci::BuildReportResultService do
describe "#execute" do
subject(:build_report_result) { described_class.new.execute(build) }
diff --git a/spec/services/ci/cancel_user_pipelines_service_spec.rb b/spec/services/ci/cancel_user_pipelines_service_spec.rb
index b18bf48a50a..12117051b64 100644
--- a/spec/services/ci/cancel_user_pipelines_service_spec.rb
+++ b/spec/services/ci/cancel_user_pipelines_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Ci::CancelUserPipelinesService do
+RSpec.describe Ci::CancelUserPipelinesService do
describe '#execute' do
let(:user) { create(:user) }
diff --git a/spec/services/ci/compare_accessibility_reports_service_spec.rb b/spec/services/ci/compare_accessibility_reports_service_spec.rb
index aee1fd14bc5..6903a633eeb 100644
--- a/spec/services/ci/compare_accessibility_reports_service_spec.rb
+++ b/spec/services/ci/compare_accessibility_reports_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Ci::CompareAccessibilityReportsService do
+RSpec.describe Ci::CompareAccessibilityReportsService do
let(:service) { described_class.new(project) }
let(:project) { create(:project, :repository) }
diff --git a/spec/services/ci/compare_test_reports_service_spec.rb b/spec/services/ci/compare_test_reports_service_spec.rb
index 46f4d2d42ff..7d31db73b6a 100644
--- a/spec/services/ci/compare_test_reports_service_spec.rb
+++ b/spec/services/ci/compare_test_reports_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Ci::CompareTestReportsService do
+RSpec.describe Ci::CompareTestReportsService do
let(:service) { described_class.new(project) }
let(:project) { create(:project, :repository) }
diff --git a/spec/services/ci/create_cross_project_pipeline_service_spec.rb b/spec/services/ci/create_cross_project_pipeline_service_spec.rb
index 9e2497854bc..1aabdb85afd 100644
--- a/spec/services/ci/create_cross_project_pipeline_service_spec.rb
+++ b/spec/services/ci/create_cross_project_pipeline_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Ci::CreateCrossProjectPipelineService, '#execute' do
+RSpec.describe Ci::CreateCrossProjectPipelineService, '#execute' do
let_it_be(:user) { create(:user) }
let(:upstream_project) { create(:project, :repository) }
let_it_be(:downstream_project) { create(:project, :repository) }
diff --git a/spec/services/ci/create_job_artifacts_service_spec.rb b/spec/services/ci/create_job_artifacts_service_spec.rb
index 4d49923a184..3f5cf079025 100644
--- a/spec/services/ci/create_job_artifacts_service_spec.rb
+++ b/spec/services/ci/create_job_artifacts_service_spec.rb
@@ -2,9 +2,9 @@
require 'spec_helper'
-describe Ci::CreateJobArtifactsService do
+RSpec.describe Ci::CreateJobArtifactsService do
let_it_be(:project) { create(:project) }
- let(:service) { described_class.new(project) }
+ let(:service) { described_class.new(job) }
let(:job) { create(:ci_build, project: project) }
let(:artifacts_sha256) { '0' * 64 }
let(:metadata_file) { nil }
@@ -17,7 +17,7 @@ describe Ci::CreateJobArtifactsService do
{
'artifact_type' => 'archive',
'artifact_format' => 'zip'
- }
+ }.with_indifferent_access
end
def file_to_upload(path, params = {})
@@ -28,27 +28,7 @@ describe Ci::CreateJobArtifactsService do
end
describe '#execute' do
- subject { service.execute(job, artifacts_file, params, metadata_file: metadata_file) }
-
- context 'locking' do
- let(:old_job) { create(:ci_build, pipeline: create(:ci_pipeline, project: job.project, ref: job.ref)) }
- let!(:latest_artifact) { create(:ci_job_artifact, job: old_job, locked: true) }
- let!(:other_artifact) { create(:ci_job_artifact, locked: true) }
-
- it 'locks the new artifact' do
- subject
-
- expect(Ci::JobArtifact.last).to have_attributes(locked: true)
- end
-
- it 'unlocks all other artifacts for the same ref' do
- expect { subject }.to change { latest_artifact.reload.locked }.from(true).to(false)
- end
-
- it 'does not unlock artifacts for other refs' do
- expect { subject }.not_to change { other_artifact.reload.locked }.from(true)
- end
- end
+ subject { service.execute(artifacts_file, params, metadata_file: metadata_file) }
context 'when artifacts file is uploaded' do
it 'saves artifact for the given type' do
@@ -150,7 +130,7 @@ describe Ci::CreateJobArtifactsService do
{
'artifact_type' => 'dotenv',
'artifact_format' => 'gzip'
- }
+ }.with_indifferent_access
end
it 'calls parse service' do
@@ -186,7 +166,7 @@ describe Ci::CreateJobArtifactsService do
{
'artifact_type' => 'cluster_applications',
'artifact_format' => 'gzip'
- }
+ }.with_indifferent_access
end
it 'calls cluster applications parse service' do
diff --git a/spec/services/ci/create_pipeline_service/cache_spec.rb b/spec/services/ci/create_pipeline_service/cache_spec.rb
index 4e0567132ff..614e46f1b1a 100644
--- a/spec/services/ci/create_pipeline_service/cache_spec.rb
+++ b/spec/services/ci/create_pipeline_service/cache_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Ci::CreatePipelineService do
+RSpec.describe Ci::CreatePipelineService do
context 'cache' do
let(:user) { create(:admin) }
let(:ref) { 'refs/heads/master' }
diff --git a/spec/services/ci/create_pipeline_service/creation_errors_and_warnings_spec.rb b/spec/services/ci/create_pipeline_service/creation_errors_and_warnings_spec.rb
new file mode 100644
index 00000000000..16205529f1c
--- /dev/null
+++ b/spec/services/ci/create_pipeline_service/creation_errors_and_warnings_spec.rb
@@ -0,0 +1,114 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Ci::CreatePipelineService do
+ describe 'creation errors and warnings' do
+ let_it_be(:user) { create(:admin) }
+ let_it_be(:project) { create(:project, :repository, creator: user) }
+
+ let(:ref) { 'refs/heads/master' }
+ let(:source) { :push }
+ let(:service) { described_class.new(project, user, { ref: ref }) }
+ let(:pipeline) { service.execute(source) }
+
+ before do
+ stub_ci_pipeline_yaml_file(config)
+ stub_feature_flags(ci_raise_job_rules_without_workflow_rules_warning: true)
+ end
+
+ context 'when created successfully' do
+ context 'when warnings are raised' do
+ let(:config) do
+ <<~YAML
+ test:
+ script: rspec
+ rules:
+ - if: '$CI_COMMIT_BRANCH'
+ YAML
+ end
+
+ it 'contains only warnings' do
+ expect(pipeline.error_messages.map(&:content)).to be_empty
+
+ expect(pipeline.warning_messages.map(&:content)).to contain_exactly(
+ 'jobs:test uses `rules` without defining `workflow:rules`'
+ )
+ end
+
+ context 'when feature flag is disabled for the particular warning' do
+ before do
+ stub_feature_flags(ci_raise_job_rules_without_workflow_rules_warning: false)
+ end
+
+ it 'does not contain warnings' do
+ expect(pipeline.error_messages.map(&:content)).to be_empty
+
+ expect(pipeline.warning_messages.map(&:content)).to be_empty
+ end
+ end
+ end
+
+ context 'when no warnings are raised' do
+ let(:config) do
+ <<~YAML
+ test:
+ script: rspec
+ YAML
+ end
+
+ it 'contains no warnings' do
+ expect(pipeline.error_messages).to be_empty
+
+ expect(pipeline.warning_messages).to be_empty
+ end
+ end
+ end
+
+ context 'when failed to create the pipeline' do
+ context 'when warnings are raised' do
+ let(:config) do
+ <<~YAML
+ build:
+ stage: build
+ script: echo
+ needs: [test]
+ test:
+ stage: test
+ script: echo
+ rules:
+ - if: '$CI_COMMIT_BRANCH'
+ YAML
+ end
+
+ it 'contains both errors and warnings' do
+ error_message = 'build job: need test is not defined in prior stages'
+ warning_message = 'jobs:test uses `rules` without defining `workflow:rules`'
+
+ expect(pipeline.yaml_errors).to eq(error_message)
+ expect(pipeline.error_messages.map(&:content)).to contain_exactly(error_message)
+ expect(pipeline.errors.full_messages).to contain_exactly(error_message)
+
+ expect(pipeline.warning_messages.map(&:content)).to contain_exactly(warning_message)
+ end
+ end
+
+ context 'when no warnings are raised' do
+ let(:config) do
+ <<~YAML
+ invalid: yaml
+ YAML
+ end
+
+ it 'contains only errors' do
+ error_message = 'root config contains unknown keys: invalid'
+ expect(pipeline.yaml_errors).to eq(error_message)
+ expect(pipeline.error_messages.map(&:content)).to contain_exactly(error_message)
+ expect(pipeline.errors.full_messages).to contain_exactly(error_message)
+
+ expect(pipeline.warning_messages).to be_empty
+ end
+ end
+ end
+ end
+end
diff --git a/spec/services/ci/create_pipeline_service/custom_config_content_spec.rb b/spec/services/ci/create_pipeline_service/custom_config_content_spec.rb
index 5980260a08a..122870e0f3a 100644
--- a/spec/services/ci/create_pipeline_service/custom_config_content_spec.rb
+++ b/spec/services/ci/create_pipeline_service/custom_config_content_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
require 'spec_helper'
-describe Ci::CreatePipelineService do
+RSpec.describe Ci::CreatePipelineService do
let_it_be(:project) { create(:project, :repository) }
let_it_be(:user) { create(:admin) }
let(:ref) { 'refs/heads/master' }
diff --git a/spec/services/ci/create_pipeline_service/needs_spec.rb b/spec/services/ci/create_pipeline_service/needs_spec.rb
index 17b9cf80cc1..915dc46d664 100644
--- a/spec/services/ci/create_pipeline_service/needs_spec.rb
+++ b/spec/services/ci/create_pipeline_service/needs_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Ci::CreatePipelineService do
+RSpec.describe Ci::CreatePipelineService do
context 'needs' do
let_it_be(:user) { create(:admin) }
let_it_be(:project) { create(:project, :repository, creator: user) }
diff --git a/spec/services/ci/create_pipeline_service/parameter_content_spec.rb b/spec/services/ci/create_pipeline_service/parameter_content_spec.rb
new file mode 100644
index 00000000000..5157574ea04
--- /dev/null
+++ b/spec/services/ci/create_pipeline_service/parameter_content_spec.rb
@@ -0,0 +1,62 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Ci::CreatePipelineService do
+ let_it_be(:project) { create(:project, :repository) }
+ let_it_be(:user) { create(:admin) }
+ let(:service) { described_class.new(project, user, { ref: 'refs/heads/master' }) }
+ let(:content) do
+ <<~EOY
+ ---
+ stages:
+ - dast
+
+ variables:
+ DAST_VERSION: 1
+ SECURE_ANALYZERS_PREFIX: "registry.gitlab.com/gitlab-org/security-products/analyzers"
+
+ dast:
+ stage: dast
+ image:
+ name: "$SECURE_ANALYZERS_PREFIX/dast:$DAST_VERSION"
+ variables:
+ GIT_STRATEGY: none
+ script:
+ - /analyze
+ EOY
+ end
+
+ describe '#execute' do
+ context 'when source is a dangling build' do
+ subject { service.execute(:ondemand_dast_scan, content: content) }
+
+ context 'parameter config content' do
+ it 'creates a pipeline' do
+ expect(subject).to be_persisted
+ end
+
+ it 'creates builds with the correct names' do
+ expect(subject.builds.pluck(:name)).to match_array %w[dast]
+ end
+
+ it 'creates stages with the correct names' do
+ expect(subject.stages.pluck(:name)).to match_array %w[dast]
+ end
+
+ it 'sets the correct config source' do
+ expect(subject.config_source).to eq 'parameter_source'
+ end
+ end
+ end
+
+ context 'when source is not a dangling build' do
+ subject { service.execute(:web, content: content) }
+
+ it 'raises an exception' do
+ klass = Gitlab::Ci::Pipeline::Chain::Config::Content::Parameter::UnsupportedSourceError
+ expect { subject }.to raise_error(klass)
+ end
+ end
+ end
+end
diff --git a/spec/services/ci/create_pipeline_service/parent_child_pipeline_spec.rb b/spec/services/ci/create_pipeline_service/parent_child_pipeline_spec.rb
index a76e83f2d60..016a5dfd18b 100644
--- a/spec/services/ci/create_pipeline_service/parent_child_pipeline_spec.rb
+++ b/spec/services/ci/create_pipeline_service/parent_child_pipeline_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Ci::CreatePipelineService, '#execute' do
+RSpec.describe Ci::CreatePipelineService, '#execute' do
let_it_be(:project) { create(:project, :repository) }
let_it_be(:user) { create(:user) }
let(:ref_name) { 'master' }
diff --git a/spec/services/ci/create_pipeline_service/pre_post_stages_spec.rb b/spec/services/ci/create_pipeline_service/pre_post_stages_spec.rb
index 2b11b98f58c..00a2dd74968 100644
--- a/spec/services/ci/create_pipeline_service/pre_post_stages_spec.rb
+++ b/spec/services/ci/create_pipeline_service/pre_post_stages_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
require 'spec_helper'
-describe Ci::CreatePipelineService do
+RSpec.describe Ci::CreatePipelineService do
describe '.pre/.post stages' do
let_it_be(:user) { create(:admin) }
let_it_be(:project) { create(:project, :repository, creator: user) }
diff --git a/spec/services/ci/create_pipeline_service/rules_spec.rb b/spec/services/ci/create_pipeline_service/rules_spec.rb
index 713d230731b..1a1fa6e8f5d 100644
--- a/spec/services/ci/create_pipeline_service/rules_spec.rb
+++ b/spec/services/ci/create_pipeline_service/rules_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
require 'spec_helper'
-describe Ci::CreatePipelineService do
+RSpec.describe Ci::CreatePipelineService do
let(:user) { create(:admin) }
let(:ref) { 'refs/heads/master' }
let(:source) { :push }
diff --git a/spec/services/ci/create_pipeline_service_spec.rb b/spec/services/ci/create_pipeline_service_spec.rb
index b9456d5fcd4..9dc518be996 100644
--- a/spec/services/ci/create_pipeline_service_spec.rb
+++ b/spec/services/ci/create_pipeline_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Ci::CreatePipelineService do
+RSpec.describe Ci::CreatePipelineService do
include ProjectForksHelper
let_it_be(:project, reload: true) { create(:project, :repository) }
@@ -80,7 +80,7 @@ describe Ci::CreatePipelineService do
it 'records pipeline size in a prometheus histogram' do
histogram = spy('pipeline size histogram')
- allow(Gitlab::Ci::Pipeline::Chain::Metrics)
+ allow(Gitlab::Ci::Pipeline::Metrics)
.to receive(:new).and_return(histogram)
execute_service
@@ -194,6 +194,7 @@ describe Ci::CreatePipelineService do
expect(head_pipeline).to be_persisted
expect(head_pipeline.yaml_errors).to be_present
+ expect(head_pipeline.messages).to be_present
expect(merge_request.reload.head_pipeline).to eq head_pipeline
end
end
@@ -511,7 +512,7 @@ describe Ci::CreatePipelineService do
it 'pull it from Auto-DevOps' do
pipeline = execute_service
expect(pipeline).to be_auto_devops_source
- expect(pipeline.builds.map(&:name)).to match_array(%w[test code_quality build])
+ expect(pipeline.builds.map(&:name)).to match_array(%w[build code_quality eslint-sast test])
end
end
@@ -1683,6 +1684,12 @@ describe Ci::CreatePipelineService do
expect(pipeline).to be_persisted
expect(pipeline.builds.pluck(:name)).to contain_exactly("build_a", "test_a")
end
+
+ it 'bulk inserts all needs' do
+ expect(Ci::BuildNeed).to receive(:bulk_insert!).and_call_original
+
+ expect(pipeline).to be_persisted
+ end
end
context 'when pipeline on feature is created' do
@@ -1695,6 +1702,7 @@ describe Ci::CreatePipelineService do
expect(pipeline).to be_persisted
expect(pipeline.builds).to be_empty
expect(pipeline.yaml_errors).to eq("test_a: needs 'build_a'")
+ expect(pipeline.messages.pluck(:content)).to contain_exactly("test_a: needs 'build_a'")
expect(pipeline.errors[:base]).to contain_exactly("test_a: needs 'build_a'")
end
end
@@ -1706,6 +1714,7 @@ describe Ci::CreatePipelineService do
expect(pipeline).not_to be_persisted
expect(pipeline.builds).to be_empty
expect(pipeline.yaml_errors).to be_nil
+ expect(pipeline.messages).not_to be_empty
expect(pipeline.errors[:base]).to contain_exactly("test_a: needs 'build_a'")
end
end
@@ -2205,6 +2214,83 @@ describe Ci::CreatePipelineService do
expect(find_job('job-7').when).to eq('on_failure')
end
end
+
+ context 'with deploy freeze period `if:` clause' do
+ # '0 23 * * 5' == "At 23:00 on Friday."", '0 7 * * 1' == "At 07:00 on Monday.""
+ let!(:freeze_period) { create(:ci_freeze_period, project: project, freeze_start: '0 23 * * 5', freeze_end: '0 7 * * 1') }
+
+ context 'with 2 jobs' do
+ let(:config) do
+ <<-EOY
+ stages:
+ - test
+ - deploy
+
+ test-job:
+ script:
+ - echo 'running TEST stage'
+
+ deploy-job:
+ stage: deploy
+ script:
+ - echo 'running DEPLOY stage'
+ rules:
+ - if: $CI_DEPLOY_FREEZE == null
+ EOY
+ end
+
+ context 'when outside freeze period' do
+ it 'creates two jobs' do
+ Timecop.freeze(2020, 4, 10, 22, 59) do
+ expect(pipeline).to be_persisted
+ expect(build_names).to contain_exactly('test-job', 'deploy-job')
+ end
+ end
+ end
+
+ context 'when inside freeze period' do
+ it 'creates one job' do
+ Timecop.freeze(2020, 4, 10, 23, 1) do
+ expect(pipeline).to be_persisted
+ expect(build_names).to contain_exactly('test-job')
+ end
+ end
+ end
+ end
+
+ context 'with 1 job' do
+ let(:config) do
+ <<-EOY
+ stages:
+ - deploy
+
+ deploy-job:
+ stage: deploy
+ script:
+ - echo 'running DEPLOY stage'
+ rules:
+ - if: $CI_DEPLOY_FREEZE == null
+ EOY
+ end
+
+ context 'when outside freeze period' do
+ it 'creates two jobs' do
+ Timecop.freeze(2020, 4, 10, 22, 59) do
+ expect(pipeline).to be_persisted
+ expect(build_names).to contain_exactly('deploy-job')
+ end
+ end
+ end
+
+ context 'when inside freeze period' do
+ it 'does not create the pipeline' do
+ Timecop.freeze(2020, 4, 10, 23, 1) do
+ expect(pipeline).not_to be_persisted
+ end
+ end
+ end
+ end
+ end
end
end
diff --git a/spec/services/ci/create_web_ide_terminal_service_spec.rb b/spec/services/ci/create_web_ide_terminal_service_spec.rb
index 2cc67c7cd1d..c1c94e30018 100644
--- a/spec/services/ci/create_web_ide_terminal_service_spec.rb
+++ b/spec/services/ci/create_web_ide_terminal_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Ci::CreateWebIdeTerminalService do
+RSpec.describe Ci::CreateWebIdeTerminalService do
let_it_be(:project) { create(:project, :repository) }
let_it_be(:user) { create(:user) }
let(:ref) { 'master' }
diff --git a/spec/services/ci/daily_build_group_report_result_service_spec.rb b/spec/services/ci/daily_build_group_report_result_service_spec.rb
index f0b72b8fd86..7d181a5c2ba 100644
--- a/spec/services/ci/daily_build_group_report_result_service_spec.rb
+++ b/spec/services/ci/daily_build_group_report_result_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Ci::DailyBuildGroupReportResultService, '#execute' do
+RSpec.describe Ci::DailyBuildGroupReportResultService, '#execute' do
let!(:pipeline) { create(:ci_pipeline, created_at: '2020-02-06 00:01:10') }
let!(:rspec_job) { create(:ci_build, pipeline: pipeline, name: '3/3 rspec', coverage: 80) }
let!(:karma_job) { create(:ci_build, pipeline: pipeline, name: '2/2 karma', coverage: 90) }
diff --git a/spec/services/ci/destroy_expired_job_artifacts_service_spec.rb b/spec/services/ci/destroy_expired_job_artifacts_service_spec.rb
index 4b9f12d8fdf..79443f16276 100644
--- a/spec/services/ci/destroy_expired_job_artifacts_service_spec.rb
+++ b/spec/services/ci/destroy_expired_job_artifacts_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Ci::DestroyExpiredJobArtifactsService, :clean_gitlab_redis_shared_state do
+RSpec.describe Ci::DestroyExpiredJobArtifactsService, :clean_gitlab_redis_shared_state do
include ExclusiveLeaseHelpers
describe '.execute' do
@@ -14,7 +14,7 @@ describe Ci::DestroyExpiredJobArtifactsService, :clean_gitlab_redis_shared_state
context 'when artifact is expired' do
context 'when artifact is not locked' do
before do
- artifact.update!(locked: false)
+ artifact.job.pipeline.unlocked!
end
it 'destroys job artifact' do
@@ -24,7 +24,7 @@ describe Ci::DestroyExpiredJobArtifactsService, :clean_gitlab_redis_shared_state
context 'when artifact is locked' do
before do
- artifact.update!(locked: true)
+ artifact.job.pipeline.artifacts_locked!
end
it 'does not destroy job artifact' do
diff --git a/spec/services/ci/destroy_pipeline_service_spec.rb b/spec/services/ci/destroy_pipeline_service_spec.rb
index bff2b3179fb..23cbe683d2f 100644
--- a/spec/services/ci/destroy_pipeline_service_spec.rb
+++ b/spec/services/ci/destroy_pipeline_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe ::Ci::DestroyPipelineService do
+RSpec.describe ::Ci::DestroyPipelineService do
let(:project) { create(:project, :repository) }
let!(:pipeline) { create(:ci_pipeline, :success, project: project, sha: project.commit.id) }
diff --git a/spec/services/ci/ensure_stage_service_spec.rb b/spec/services/ci/ensure_stage_service_spec.rb
index 8a270d77bae..3ede214cdd4 100644
--- a/spec/services/ci/ensure_stage_service_spec.rb
+++ b/spec/services/ci/ensure_stage_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Ci::EnsureStageService, '#execute' do
+RSpec.describe Ci::EnsureStageService, '#execute' do
let_it_be(:project) { create(:project) }
let_it_be(:user) { create(:user) }
diff --git a/spec/services/ci/expire_pipeline_cache_service_spec.rb b/spec/services/ci/expire_pipeline_cache_service_spec.rb
index 2962e9dd31e..b5d664947de 100644
--- a/spec/services/ci/expire_pipeline_cache_service_spec.rb
+++ b/spec/services/ci/expire_pipeline_cache_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Ci::ExpirePipelineCacheService do
+RSpec.describe Ci::ExpirePipelineCacheService do
let_it_be(:user) { create(:user) }
let_it_be(:project) { create(:project) }
let_it_be(:pipeline) { create(:ci_pipeline, project: project) }
diff --git a/spec/services/ci/external_pull_requests/create_pipeline_service_spec.rb b/spec/services/ci/external_pull_requests/create_pipeline_service_spec.rb
index 5048f2b71b3..e2bdfae27f0 100644
--- a/spec/services/ci/external_pull_requests/create_pipeline_service_spec.rb
+++ b/spec/services/ci/external_pull_requests/create_pipeline_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Ci::ExternalPullRequests::CreatePipelineService do
+RSpec.describe Ci::ExternalPullRequests::CreatePipelineService do
describe '#execute' do
let_it_be(:project) { create(:project, :auto_devops, :repository) }
let_it_be(:user) { create(:user) }
diff --git a/spec/services/ci/extract_sections_from_build_trace_service_spec.rb b/spec/services/ci/extract_sections_from_build_trace_service_spec.rb
index 03c67c611fe..c6ffcdcc6a8 100644
--- a/spec/services/ci/extract_sections_from_build_trace_service_spec.rb
+++ b/spec/services/ci/extract_sections_from_build_trace_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Ci::ExtractSectionsFromBuildTraceService, '#execute' do
+RSpec.describe Ci::ExtractSectionsFromBuildTraceService, '#execute' do
let(:user) { create(:user) }
let(:project) { create(:project) }
let(:build) { create(:ci_build, project: project) }
diff --git a/spec/services/ci/find_exposed_artifacts_service_spec.rb b/spec/services/ci/find_exposed_artifacts_service_spec.rb
index 16e23253c34..287f5c4b929 100644
--- a/spec/services/ci/find_exposed_artifacts_service_spec.rb
+++ b/spec/services/ci/find_exposed_artifacts_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Ci::FindExposedArtifactsService do
+RSpec.describe Ci::FindExposedArtifactsService do
include Gitlab::Routing
let(:metadata) do
diff --git a/spec/services/ci/generate_coverage_reports_service_spec.rb b/spec/services/ci/generate_coverage_reports_service_spec.rb
index b64b682a00b..a3ed2eec713 100644
--- a/spec/services/ci/generate_coverage_reports_service_spec.rb
+++ b/spec/services/ci/generate_coverage_reports_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Ci::GenerateCoverageReportsService do
+RSpec.describe Ci::GenerateCoverageReportsService do
let(:service) { described_class.new(project) }
let(:project) { create(:project, :repository) }
diff --git a/spec/services/ci/generate_terraform_reports_service_spec.rb b/spec/services/ci/generate_terraform_reports_service_spec.rb
index 008ecf17b3e..25bf96035b2 100644
--- a/spec/services/ci/generate_terraform_reports_service_spec.rb
+++ b/spec/services/ci/generate_terraform_reports_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Ci::GenerateTerraformReportsService do
+RSpec.describe Ci::GenerateTerraformReportsService do
let_it_be(:project) { create(:project, :repository) }
describe '#execute' do
@@ -33,19 +33,36 @@ describe Ci::GenerateTerraformReportsService do
end
context 'when head pipeline has corrupted terraform reports' do
- it 'returns status and error message' do
+ it 'returns a report with error messages' do
build = create(:ci_build, pipeline: merge_request.head_pipeline, project: project)
create(:ci_job_artifact, :terraform_with_corrupted_data, job: build, project: project)
result = subject.execute(nil, merge_request.head_pipeline)
expect(result).to match(
- status: :error,
- status_reason: 'An error occurred while fetching terraform reports.',
+ status: :parsed,
+ data: match(
+ a_hash_including(build.id.to_s => hash_including(
+ 'tf_report_error' => :invalid_json_format
+ ))
+ ),
key: an_instance_of(Array)
)
end
end
+
+ context 'when head pipeline is corrupted' do
+ it 'returns status and error message' do
+ result = subject.execute(nil, nil)
+
+ expect(result).to match(
+ a_hash_including(
+ status: :error,
+ status_reason: 'An error occurred while fetching terraform reports.'
+ )
+ )
+ end
+ end
end
describe '#latest?' do
diff --git a/spec/services/ci/parse_dotenv_artifact_service_spec.rb b/spec/services/ci/parse_dotenv_artifact_service_spec.rb
index fc4131d262b..a5f01187a83 100644
--- a/spec/services/ci/parse_dotenv_artifact_service_spec.rb
+++ b/spec/services/ci/parse_dotenv_artifact_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Ci::ParseDotenvArtifactService do
+RSpec.describe Ci::ParseDotenvArtifactService do
let_it_be(:project) { create(:project) }
let_it_be(:pipeline) { create(:ci_pipeline, project: project) }
let(:build) { create(:ci_build, pipeline: pipeline, project: project) }
diff --git a/spec/services/ci/pipeline_bridge_status_service_spec.rb b/spec/services/ci/pipeline_bridge_status_service_spec.rb
index 7e79d222349..584b23bb3aa 100644
--- a/spec/services/ci/pipeline_bridge_status_service_spec.rb
+++ b/spec/services/ci/pipeline_bridge_status_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Ci::PipelineBridgeStatusService do
+RSpec.describe Ci::PipelineBridgeStatusService do
let(:user) { build(:user) }
let_it_be(:project) { create(:project) }
let(:pipeline) { build(:ci_pipeline, project: project) }
diff --git a/spec/services/ci/pipeline_processing/atomic_processing_service/status_collection_spec.rb b/spec/services/ci/pipeline_processing/atomic_processing_service/status_collection_spec.rb
index de3c7713ac8..7868629d34d 100644
--- a/spec/services/ci/pipeline_processing/atomic_processing_service/status_collection_spec.rb
+++ b/spec/services/ci/pipeline_processing/atomic_processing_service/status_collection_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Ci::PipelineProcessing::AtomicProcessingService::StatusCollection do
+RSpec.describe Ci::PipelineProcessing::AtomicProcessingService::StatusCollection do
using RSpec::Parameterized::TableSyntax
let_it_be(:pipeline) { create(:ci_pipeline) }
diff --git a/spec/services/ci/pipeline_processing/atomic_processing_service_spec.rb b/spec/services/ci/pipeline_processing/atomic_processing_service_spec.rb
index 3b66ecff196..a10a333b462 100644
--- a/spec/services/ci/pipeline_processing/atomic_processing_service_spec.rb
+++ b/spec/services/ci/pipeline_processing/atomic_processing_service_spec.rb
@@ -4,7 +4,7 @@ require 'spec_helper'
require_relative 'shared_processing_service.rb'
require_relative 'shared_processing_service_tests_with_yaml.rb'
-describe Ci::PipelineProcessing::AtomicProcessingService do
+RSpec.describe Ci::PipelineProcessing::AtomicProcessingService do
before do
stub_feature_flags(ci_atomic_processing: true)
diff --git a/spec/services/ci/pipeline_processing/legacy_processing_service_spec.rb b/spec/services/ci/pipeline_processing/legacy_processing_service_spec.rb
index fd491bf461b..569a6d62dc1 100644
--- a/spec/services/ci/pipeline_processing/legacy_processing_service_spec.rb
+++ b/spec/services/ci/pipeline_processing/legacy_processing_service_spec.rb
@@ -4,7 +4,7 @@ require 'spec_helper'
require_relative 'shared_processing_service.rb'
require_relative 'shared_processing_service_tests_with_yaml.rb'
-describe Ci::PipelineProcessing::LegacyProcessingService do
+RSpec.describe Ci::PipelineProcessing::LegacyProcessingService do
before do
stub_feature_flags(ci_atomic_processing: false)
end
diff --git a/spec/services/ci/pipeline_processing/shared_processing_service.rb b/spec/services/ci/pipeline_processing/shared_processing_service.rb
index 29fa43001ae..224066885b6 100644
--- a/spec/services/ci/pipeline_processing/shared_processing_service.rb
+++ b/spec/services/ci/pipeline_processing/shared_processing_service.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-shared_examples 'Pipeline Processing Service' do
+RSpec.shared_examples 'Pipeline Processing Service' do
let(:user) { create(:user) }
let(:project) { create(:project) }
diff --git a/spec/services/ci/pipeline_processing/shared_processing_service_tests_with_yaml.rb b/spec/services/ci/pipeline_processing/shared_processing_service_tests_with_yaml.rb
index 93f83f0ea3b..17d254ba48e 100644
--- a/spec/services/ci/pipeline_processing/shared_processing_service_tests_with_yaml.rb
+++ b/spec/services/ci/pipeline_processing/shared_processing_service_tests_with_yaml.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-shared_context 'Pipeline Processing Service Tests With Yaml' do
+RSpec.shared_context 'Pipeline Processing Service Tests With Yaml' do
where(:test_file_path) do
Dir.glob(Rails.root.join('spec/services/ci/pipeline_processing/test_cases/*.yml'))
end
diff --git a/spec/services/ci/pipeline_schedule_service_spec.rb b/spec/services/ci/pipeline_schedule_service_spec.rb
index 867ed0acc0d..65bbd13c5e7 100644
--- a/spec/services/ci/pipeline_schedule_service_spec.rb
+++ b/spec/services/ci/pipeline_schedule_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Ci::PipelineScheduleService do
+RSpec.describe Ci::PipelineScheduleService do
let(:project) { create(:project) }
let(:user) { create(:user) }
let(:service) { described_class.new(project, user) }
diff --git a/spec/services/ci/pipeline_trigger_service_spec.rb b/spec/services/ci/pipeline_trigger_service_spec.rb
index 44ce1ff699b..18fab9623ec 100644
--- a/spec/services/ci/pipeline_trigger_service_spec.rb
+++ b/spec/services/ci/pipeline_trigger_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Ci::PipelineTriggerService do
+RSpec.describe Ci::PipelineTriggerService do
let(:project) { create(:project, :repository) }
before do
diff --git a/spec/services/ci/play_build_service_spec.rb b/spec/services/ci/play_build_service_spec.rb
index cf39f3da4fe..c9ecbad3167 100644
--- a/spec/services/ci/play_build_service_spec.rb
+++ b/spec/services/ci/play_build_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Ci::PlayBuildService, '#execute' do
+RSpec.describe Ci::PlayBuildService, '#execute' do
let(:user) { create(:user, developer_projects: [project]) }
let(:project) { create(:project) }
let(:pipeline) { create(:ci_pipeline, project: project) }
diff --git a/spec/services/ci/play_manual_stage_service_spec.rb b/spec/services/ci/play_manual_stage_service_spec.rb
index e2946111a13..e30ec8bfda5 100644
--- a/spec/services/ci/play_manual_stage_service_spec.rb
+++ b/spec/services/ci/play_manual_stage_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Ci::PlayManualStageService, '#execute' do
+RSpec.describe Ci::PlayManualStageService, '#execute' do
let(:current_user) { create(:user) }
let(:pipeline) { create(:ci_pipeline, user: current_user) }
let(:project) { pipeline.project }
diff --git a/spec/services/ci/prepare_build_service_spec.rb b/spec/services/ci/prepare_build_service_spec.rb
index 02928b58ff8..f75cb322fe9 100644
--- a/spec/services/ci/prepare_build_service_spec.rb
+++ b/spec/services/ci/prepare_build_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Ci::PrepareBuildService do
+RSpec.describe Ci::PrepareBuildService do
describe '#execute' do
let(:build) { create(:ci_build, :preparing) }
diff --git a/spec/services/ci/process_build_service_spec.rb b/spec/services/ci/process_build_service_spec.rb
index abc5c18a523..a6e8732f5ff 100644
--- a/spec/services/ci/process_build_service_spec.rb
+++ b/spec/services/ci/process_build_service_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
require 'spec_helper'
-describe Ci::ProcessBuildService, '#execute' do
+RSpec.describe Ci::ProcessBuildService, '#execute' do
let(:user) { create(:user) }
let(:project) { create(:project) }
diff --git a/spec/services/ci/process_pipeline_service_spec.rb b/spec/services/ci/process_pipeline_service_spec.rb
index 40ae1c4029b..a7889f0644d 100644
--- a/spec/services/ci/process_pipeline_service_spec.rb
+++ b/spec/services/ci/process_pipeline_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Ci::ProcessPipelineService do
+RSpec.describe Ci::ProcessPipelineService do
let(:user) { create(:user) }
let(:project) { create(:project) }
@@ -10,38 +10,52 @@ describe Ci::ProcessPipelineService do
create(:ci_empty_pipeline, ref: 'master', project: project)
end
+ subject { described_class.new(pipeline) }
+
before do
stub_ci_pipeline_to_return_yaml_file
-
stub_not_protect_default_branch
project.add_developer(user)
end
- context 'updates a list of retried builds' do
- subject { described_class.retried.order(:id) }
+ describe 'processing events counter' do
+ let(:metrics) { double('pipeline metrics') }
+ let(:counter) { double('events counter') }
+
+ before do
+ allow(subject)
+ .to receive(:metrics).and_return(metrics)
+ allow(metrics)
+ .to receive(:pipeline_processing_events_counter)
+ .and_return(counter)
+ end
+
+ it 'increments processing events counter' do
+ expect(counter).to receive(:increment)
+
+ subject.execute
+ end
+ end
+ describe 'updating a list of retried builds' do
let!(:build_retried) { create_build('build') }
let!(:build) { create_build('build') }
let!(:test) { create_build('test') }
it 'returns unique statuses' do
- process_pipeline
+ subject.execute
expect(all_builds.latest).to contain_exactly(build, test)
expect(all_builds.retried).to contain_exactly(build_retried)
end
- end
-
- def process_pipeline
- described_class.new(pipeline).execute
- end
- def create_build(name, **opts)
- create(:ci_build, :created, pipeline: pipeline, name: name, **opts)
- end
+ def create_build(name, **opts)
+ create(:ci_build, :created, pipeline: pipeline, name: name, **opts)
+ end
- def all_builds
- pipeline.builds.order(:stage_idx, :id)
+ def all_builds
+ pipeline.builds.order(:stage_idx, :id)
+ end
end
end
diff --git a/spec/services/ci/register_job_service_spec.rb b/spec/services/ci/register_job_service_spec.rb
index c0f854df9b7..921f5ba4c7e 100644
--- a/spec/services/ci/register_job_service_spec.rb
+++ b/spec/services/ci/register_job_service_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
module Ci
- describe RegisterJobService do
+ RSpec.describe RegisterJobService do
let_it_be(:group) { create(:group) }
let_it_be(:project, reload: true) { create(:project, group: group, shared_runners_enabled: false, group_runners_enabled: false) }
let_it_be(:pipeline) { create(:ci_pipeline, project: project) }
@@ -109,12 +109,14 @@ module Ci
end
context 'shared runner' do
- let(:build) { execute(shared_runner) }
+ let(:response) { described_class.new(shared_runner).execute }
+ let(:build) { response.build }
it { expect(build).to be_kind_of(Build) }
it { expect(build).to be_valid }
it { expect(build).to be_running }
it { expect(build.runner).to eq(shared_runner) }
+ it { expect(Gitlab::Json.parse(response.build_json)['id']).to eq(build.id) }
end
context 'specific runner' do
@@ -356,13 +358,8 @@ module Ci
end
context 'runner feature set is verified' do
- let!(:pending_job) { create(:ci_build, :pending, pipeline: pipeline) }
-
- before do
- expect_any_instance_of(Ci::Build).to receive(:runner_required_feature_names) do
- [:runner_required_feature]
- end
- end
+ let(:options) { { artifacts: { reports: { junit: "junit.xml" } } } }
+ let!(:pending_job) { create(:ci_build, :pending, pipeline: pipeline, options: options) }
subject { execute(specific_runner, params) }
@@ -378,7 +375,7 @@ module Ci
context 'when feature is supported by runner' do
let(:params) do
- { info: { features: { runner_required_feature: true } } }
+ { info: { features: { upload_multiple_artifacts: true } } }
end
it 'does pick job' do
diff --git a/spec/services/ci/resource_groups/assign_resource_from_resource_group_service_spec.rb b/spec/services/ci/resource_groups/assign_resource_from_resource_group_service_spec.rb
index 50d312647ae..6c69a7f3b11 100644
--- a/spec/services/ci/resource_groups/assign_resource_from_resource_group_service_spec.rb
+++ b/spec/services/ci/resource_groups/assign_resource_from_resource_group_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Ci::ResourceGroups::AssignResourceFromResourceGroupService do
+RSpec.describe Ci::ResourceGroups::AssignResourceFromResourceGroupService do
let_it_be(:project) { create(:project) }
let_it_be(:user) { create(:user) }
let(:service) { described_class.new(project, user) }
diff --git a/spec/services/ci/retry_build_service_spec.rb b/spec/services/ci/retry_build_service_spec.rb
index 90c53d4a346..5a245415b32 100644
--- a/spec/services/ci/retry_build_service_spec.rb
+++ b/spec/services/ci/retry_build_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Ci::RetryBuildService do
+RSpec.describe Ci::RetryBuildService do
let_it_be(:user) { create(:user) }
let_it_be(:project) { create(:project, :repository) }
let_it_be(:pipeline) do
@@ -33,13 +33,13 @@ describe Ci::RetryBuildService do
job_artifacts_sast job_artifacts_secret_detection job_artifacts_dependency_scanning
job_artifacts_container_scanning job_artifacts_dast
job_artifacts_license_management job_artifacts_license_scanning
- job_artifacts_performance job_artifacts_lsif
- job_artifacts_terraform job_artifacts_cluster_applications
+ job_artifacts_performance job_artifacts_browser_performance job_artifacts_load_performance
+ job_artifacts_lsif job_artifacts_terraform job_artifacts_cluster_applications
job_artifacts_codequality job_artifacts_metrics scheduled_at
job_variables waiting_for_resource_at job_artifacts_metrics_referee
job_artifacts_network_referee job_artifacts_dotenv
job_artifacts_cobertura needs job_artifacts_accessibility
- job_artifacts_requirements].freeze
+ job_artifacts_requirements job_artifacts_coverage_fuzzing].freeze
ignore_accessors =
%i[type lock_version target_url base_tags trace_sections
@@ -279,25 +279,16 @@ describe Ci::RetryBuildService do
end
end
- context 'when scheduling_type of build is nil' do
+ context 'when build has needs' do
before do
- build.update_columns(scheduling_type: nil)
+ create(:ci_build_need, build: build, name: 'build1')
+ create(:ci_build_need, build: build, name: 'build2')
end
- context 'when build has not needs' do
- it 'sets scheduling_type as :stage' do
- expect(new_build.scheduling_type).to eq('stage')
- end
- end
+ it 'bulk inserts all needs' do
+ expect(Ci::BuildNeed).to receive(:bulk_insert!).and_call_original
- context 'when build has needs' do
- before do
- create(:ci_build_need, build: build)
- end
-
- it 'sets scheduling_type as :dag' do
- expect(new_build.scheduling_type).to eq('dag')
- end
+ new_build
end
end
end
diff --git a/spec/services/ci/retry_pipeline_service_spec.rb b/spec/services/ci/retry_pipeline_service_spec.rb
index 8e85e68d4fc..fa46d6c4d1d 100644
--- a/spec/services/ci/retry_pipeline_service_spec.rb
+++ b/spec/services/ci/retry_pipeline_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Ci::RetryPipelineService, '#execute' do
+RSpec.describe Ci::RetryPipelineService, '#execute' do
include ProjectForksHelper
let(:user) { create(:user) }
diff --git a/spec/services/ci/run_scheduled_build_service_spec.rb b/spec/services/ci/run_scheduled_build_service_spec.rb
index 43d110cbc8f..27d25e88944 100644
--- a/spec/services/ci/run_scheduled_build_service_spec.rb
+++ b/spec/services/ci/run_scheduled_build_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Ci::RunScheduledBuildService do
+RSpec.describe Ci::RunScheduledBuildService do
let(:user) { create(:user) }
let(:project) { create(:project) }
let(:pipeline) { create(:ci_pipeline, project: project) }
diff --git a/spec/services/ci/stop_environments_service_spec.rb b/spec/services/ci/stop_environments_service_spec.rb
index ebbe6c37b87..5a0b7f23556 100644
--- a/spec/services/ci/stop_environments_service_spec.rb
+++ b/spec/services/ci/stop_environments_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Ci::StopEnvironmentsService do
+RSpec.describe Ci::StopEnvironmentsService do
include CreateEnvironmentsHelpers
let(:project) { create(:project, :private, :repository) }
diff --git a/spec/services/ci/unlock_artifacts_service_spec.rb b/spec/services/ci/unlock_artifacts_service_spec.rb
new file mode 100644
index 00000000000..8d289a867ba
--- /dev/null
+++ b/spec/services/ci/unlock_artifacts_service_spec.rb
@@ -0,0 +1,97 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Ci::UnlockArtifactsService do
+ describe '#execute' do
+ subject(:execute) { described_class.new(pipeline.project, pipeline.user).execute(ci_ref, before_pipeline) }
+
+ before do
+ stub_const("#{described_class}::BATCH_SIZE", 1)
+ end
+
+ [true, false].each do |tag|
+ context "when tag is #{tag}" do
+ let(:ref) { 'master' }
+ let(:ref_path) { tag ? "#{::Gitlab::Git::TAG_REF_PREFIX}#{ref}" : "#{::Gitlab::Git::BRANCH_REF_PREFIX}#{ref}" }
+ let(:ci_ref) { create(:ci_ref, ref_path: ref_path) }
+
+ let!(:old_unlocked_pipeline) { create(:ci_pipeline, ref: ref, tag: tag, project: ci_ref.project, locked: :unlocked) }
+ let!(:older_pipeline) { create(:ci_pipeline, ref: ref, tag: tag, project: ci_ref.project, locked: :artifacts_locked) }
+ let!(:older_ambiguous_pipeline) { create(:ci_pipeline, ref: ref, tag: !tag, project: ci_ref.project, locked: :artifacts_locked) }
+ let!(:pipeline) { create(:ci_pipeline, ref: ref, tag: tag, project: ci_ref.project, locked: :artifacts_locked) }
+ let!(:child_pipeline) { create(:ci_pipeline, ref: ref, tag: tag, project: ci_ref.project, locked: :artifacts_locked) }
+ let!(:newer_pipeline) { create(:ci_pipeline, ref: ref, tag: tag, project: ci_ref.project, locked: :artifacts_locked) }
+ let!(:other_ref_pipeline) { create(:ci_pipeline, ref: 'other_ref', tag: tag, project: ci_ref.project, locked: :artifacts_locked) }
+
+ before do
+ create(:ci_sources_pipeline,
+ source_job: create(:ci_build, pipeline: pipeline),
+ source_project: ci_ref.project,
+ pipeline: child_pipeline,
+ project: ci_ref.project)
+ end
+
+ context 'when running on a ref before a pipeline' do
+ let(:before_pipeline) { pipeline }
+
+ it 'unlocks artifacts from older pipelines' do
+ expect { execute }.to change { older_pipeline.reload.locked }.from('artifacts_locked').to('unlocked')
+ end
+
+ it 'does not unlock artifacts for tag or branch with same name as ref' do
+ expect { execute }.not_to change { older_ambiguous_pipeline.reload.locked }.from('artifacts_locked')
+ end
+
+ it 'does not unlock artifacts from newer pipelines' do
+ expect { execute }.not_to change { newer_pipeline.reload.locked }.from('artifacts_locked')
+ end
+
+ it 'does not lock artifacts from old unlocked pipelines' do
+ expect { execute }.not_to change { old_unlocked_pipeline.reload.locked }.from('unlocked')
+ end
+
+ it 'does not unlock artifacts from the same pipeline' do
+ expect { execute }.not_to change { pipeline.reload.locked }.from('artifacts_locked')
+ end
+
+ it 'does not unlock artifacts for other refs' do
+ expect { execute }.not_to change { other_ref_pipeline.reload.locked }.from('artifacts_locked')
+ end
+
+ it 'does not unlock artifacts for child pipeline' do
+ expect { execute }.not_to change { child_pipeline.reload.locked }.from('artifacts_locked')
+ end
+ end
+
+ context 'when running on just the ref' do
+ let(:before_pipeline) { nil }
+
+ it 'unlocks artifacts from older pipelines' do
+ expect { execute }.to change { older_pipeline.reload.locked }.from('artifacts_locked').to('unlocked')
+ end
+
+ it 'unlocks artifacts from newer pipelines' do
+ expect { execute }.to change { newer_pipeline.reload.locked }.from('artifacts_locked').to('unlocked')
+ end
+
+ it 'unlocks artifacts from the same pipeline' do
+ expect { execute }.to change { pipeline.reload.locked }.from('artifacts_locked').to('unlocked')
+ end
+
+ it 'does not unlock artifacts for tag or branch with same name as ref' do
+ expect { execute }.not_to change { older_ambiguous_pipeline.reload.locked }.from('artifacts_locked')
+ end
+
+ it 'does not lock artifacts from old unlocked pipelines' do
+ expect { execute }.not_to change { old_unlocked_pipeline.reload.locked }.from('unlocked')
+ end
+
+ it 'does not unlock artifacts for other refs' do
+ expect { execute }.not_to change { other_ref_pipeline.reload.locked }.from('artifacts_locked')
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/spec/services/ci/update_build_queue_service_spec.rb b/spec/services/ci/update_build_queue_service_spec.rb
index 522dd1ba1c2..0f4c0fa5ecb 100644
--- a/spec/services/ci/update_build_queue_service_spec.rb
+++ b/spec/services/ci/update_build_queue_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Ci::UpdateBuildQueueService do
+RSpec.describe Ci::UpdateBuildQueueService do
let(:project) { create(:project, :repository) }
let(:build) { create(:ci_build, pipeline: pipeline) }
let(:pipeline) { create(:ci_pipeline, project: project) }
diff --git a/spec/services/ci/update_instance_variables_service_spec.rb b/spec/services/ci/update_instance_variables_service_spec.rb
index 93f6e5d3ea8..f235d006e34 100644
--- a/spec/services/ci/update_instance_variables_service_spec.rb
+++ b/spec/services/ci/update_instance_variables_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Ci::UpdateInstanceVariablesService do
+RSpec.describe Ci::UpdateInstanceVariablesService do
let(:params) { { variables_attributes: variables_attributes } }
subject { described_class.new(params) }
diff --git a/spec/services/ci/update_runner_service_spec.rb b/spec/services/ci/update_runner_service_spec.rb
index abe575eebc8..cad9e893335 100644
--- a/spec/services/ci/update_runner_service_spec.rb
+++ b/spec/services/ci/update_runner_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Ci::UpdateRunnerService do
+RSpec.describe Ci::UpdateRunnerService do
let(:runner) { create(:ci_runner) }
describe '#update' do
diff --git a/spec/services/ci/web_ide_config_service_spec.rb b/spec/services/ci/web_ide_config_service_spec.rb
index 7522103ccb7..437b468cec8 100644
--- a/spec/services/ci/web_ide_config_service_spec.rb
+++ b/spec/services/ci/web_ide_config_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Ci::WebIdeConfigService do
+RSpec.describe Ci::WebIdeConfigService do
let_it_be(:project) { create(:project, :repository) }
let_it_be(:user) { create(:user) }
let(:sha) { 'sha' }
diff --git a/spec/services/clusters/applications/check_ingress_ip_address_service_spec.rb b/spec/services/clusters/applications/check_ingress_ip_address_service_spec.rb
index 84bca76e69b..605d9e67ab6 100644
--- a/spec/services/clusters/applications/check_ingress_ip_address_service_spec.rb
+++ b/spec/services/clusters/applications/check_ingress_ip_address_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Clusters::Applications::CheckIngressIpAddressService do
+RSpec.describe Clusters::Applications::CheckIngressIpAddressService do
include ExclusiveLeaseHelpers
let(:application) { create(:clusters_applications_ingress, :installed) }
diff --git a/spec/services/clusters/applications/check_installation_progress_service_spec.rb b/spec/services/clusters/applications/check_installation_progress_service_spec.rb
index 4b8db405101..13f7cd62002 100644
--- a/spec/services/clusters/applications/check_installation_progress_service_spec.rb
+++ b/spec/services/clusters/applications/check_installation_progress_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Clusters::Applications::CheckInstallationProgressService, '#execute' do
+RSpec.describe Clusters::Applications::CheckInstallationProgressService, '#execute' do
RESCHEDULE_PHASES = Gitlab::Kubernetes::Pod::PHASES - [Gitlab::Kubernetes::Pod::SUCCEEDED, Gitlab::Kubernetes::Pod::FAILED].freeze
let(:application) { create(:clusters_applications_helm, :installing) }
diff --git a/spec/services/clusters/applications/check_uninstall_progress_service_spec.rb b/spec/services/clusters/applications/check_uninstall_progress_service_spec.rb
index 9dede1947f8..4b8893429cf 100644
--- a/spec/services/clusters/applications/check_uninstall_progress_service_spec.rb
+++ b/spec/services/clusters/applications/check_uninstall_progress_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Clusters::Applications::CheckUninstallProgressService do
+RSpec.describe Clusters::Applications::CheckUninstallProgressService do
reschedule_phases = Gitlab::Kubernetes::Pod::PHASES - [Gitlab::Kubernetes::Pod::SUCCEEDED, Gitlab::Kubernetes::Pod::FAILED].freeze
let(:application) { create(:clusters_applications_prometheus, :uninstalling) }
diff --git a/spec/services/clusters/applications/check_upgrade_progress_service_spec.rb b/spec/services/clusters/applications/check_upgrade_progress_service_spec.rb
index 29ee897454a..dbde8cec9b9 100644
--- a/spec/services/clusters/applications/check_upgrade_progress_service_spec.rb
+++ b/spec/services/clusters/applications/check_upgrade_progress_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Clusters::Applications::CheckUpgradeProgressService do
+RSpec.describe Clusters::Applications::CheckUpgradeProgressService do
reschedule_phashes = ::Gitlab::Kubernetes::Pod::PHASES -
[::Gitlab::Kubernetes::Pod::SUCCEEDED, ::Gitlab::Kubernetes::Pod::FAILED, ::Gitlab].freeze
diff --git a/spec/services/clusters/applications/create_service_spec.rb b/spec/services/clusters/applications/create_service_spec.rb
index 0b48af408e1..f93ae2c62f3 100644
--- a/spec/services/clusters/applications/create_service_spec.rb
+++ b/spec/services/clusters/applications/create_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Clusters::Applications::CreateService do
+RSpec.describe Clusters::Applications::CreateService do
include TestRequestHelpers
let(:cluster) { create(:cluster, :project, :provided_by_gcp) }
diff --git a/spec/services/clusters/applications/destroy_service_spec.rb b/spec/services/clusters/applications/destroy_service_spec.rb
index 8d9dc6a0f11..7306256e68e 100644
--- a/spec/services/clusters/applications/destroy_service_spec.rb
+++ b/spec/services/clusters/applications/destroy_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Clusters::Applications::DestroyService, '#execute' do
+RSpec.describe Clusters::Applications::DestroyService, '#execute' do
let(:cluster) { create(:cluster, :project, :provided_by_gcp) }
let(:user) { create(:user) }
let(:params) { { application: 'prometheus' } }
diff --git a/spec/services/clusters/applications/install_service_spec.rb b/spec/services/clusters/applications/install_service_spec.rb
index 2441cc595a3..d34b4dd943c 100644
--- a/spec/services/clusters/applications/install_service_spec.rb
+++ b/spec/services/clusters/applications/install_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Clusters::Applications::InstallService do
+RSpec.describe Clusters::Applications::InstallService do
describe '#execute' do
let(:application) { create(:clusters_applications_helm, :scheduled) }
let!(:install_command) { application.install_command }
diff --git a/spec/services/clusters/applications/patch_service_spec.rb b/spec/services/clusters/applications/patch_service_spec.rb
index dc9843a5116..281da62b80b 100644
--- a/spec/services/clusters/applications/patch_service_spec.rb
+++ b/spec/services/clusters/applications/patch_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Clusters::Applications::PatchService do
+RSpec.describe Clusters::Applications::PatchService do
describe '#execute' do
let(:application) { create(:clusters_applications_knative, :scheduled) }
let!(:update_command) { application.update_command }
diff --git a/spec/services/clusters/applications/prometheus_config_service_spec.rb b/spec/services/clusters/applications/prometheus_config_service_spec.rb
index b9032e665ec..7399f250248 100644
--- a/spec/services/clusters/applications/prometheus_config_service_spec.rb
+++ b/spec/services/clusters/applications/prometheus_config_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Clusters::Applications::PrometheusConfigService do
+RSpec.describe Clusters::Applications::PrometheusConfigService do
include Gitlab::Routing.url_helpers
let_it_be(:project) { create(:project) }
diff --git a/spec/services/clusters/applications/prometheus_health_check_service_spec.rb b/spec/services/clusters/applications/prometheus_health_check_service_spec.rb
index 5c4127e4938..fc5a80688e6 100644
--- a/spec/services/clusters/applications/prometheus_health_check_service_spec.rb
+++ b/spec/services/clusters/applications/prometheus_health_check_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Clusters::Applications::PrometheusHealthCheckService, '#execute' do
+RSpec.describe Clusters::Applications::PrometheusHealthCheckService, '#execute' do
let(:service) { described_class.new(cluster) }
subject { service.execute }
diff --git a/spec/services/clusters/applications/prometheus_update_service_spec.rb b/spec/services/clusters/applications/prometheus_update_service_spec.rb
index 078b01d2777..076ff0210c9 100644
--- a/spec/services/clusters/applications/prometheus_update_service_spec.rb
+++ b/spec/services/clusters/applications/prometheus_update_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Clusters::Applications::PrometheusUpdateService do
+RSpec.describe Clusters::Applications::PrometheusUpdateService do
describe '#execute' do
let(:project) { create(:project) }
let(:environment) { create(:environment, project: project) }
diff --git a/spec/services/clusters/applications/schedule_update_service_spec.rb b/spec/services/clusters/applications/schedule_update_service_spec.rb
index eb1006ce8e0..f559fb1b7aa 100644
--- a/spec/services/clusters/applications/schedule_update_service_spec.rb
+++ b/spec/services/clusters/applications/schedule_update_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Clusters::Applications::ScheduleUpdateService do
+RSpec.describe Clusters::Applications::ScheduleUpdateService do
describe '#execute' do
let(:project) { create(:project) }
diff --git a/spec/services/clusters/applications/uninstall_service_spec.rb b/spec/services/clusters/applications/uninstall_service_spec.rb
index 6d7f0478b20..50d7e82c47e 100644
--- a/spec/services/clusters/applications/uninstall_service_spec.rb
+++ b/spec/services/clusters/applications/uninstall_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Clusters::Applications::UninstallService, '#execute' do
+RSpec.describe Clusters::Applications::UninstallService, '#execute' do
let(:application) { create(:clusters_applications_prometheus, :scheduled) }
let(:service) { described_class.new(application) }
let(:helm_client) { instance_double(Gitlab::Kubernetes::Helm::API) }
diff --git a/spec/services/clusters/applications/update_service_spec.rb b/spec/services/clusters/applications/update_service_spec.rb
index 4676951faff..4c05a12a4a1 100644
--- a/spec/services/clusters/applications/update_service_spec.rb
+++ b/spec/services/clusters/applications/update_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Clusters::Applications::UpdateService do
+RSpec.describe Clusters::Applications::UpdateService do
include TestRequestHelpers
let(:cluster) { create(:cluster, :project, :provided_by_gcp) }
diff --git a/spec/services/clusters/applications/upgrade_service_spec.rb b/spec/services/clusters/applications/upgrade_service_spec.rb
index 86fb06375f1..22fbb7ca6e3 100644
--- a/spec/services/clusters/applications/upgrade_service_spec.rb
+++ b/spec/services/clusters/applications/upgrade_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Clusters::Applications::UpgradeService do
+RSpec.describe Clusters::Applications::UpgradeService do
describe '#execute' do
let(:application) { create(:clusters_applications_helm, :scheduled) }
let!(:install_command) { application.install_command }
diff --git a/spec/services/clusters/aws/authorize_role_service_spec.rb b/spec/services/clusters/aws/authorize_role_service_spec.rb
index 3ef332558a2..530268340b7 100644
--- a/spec/services/clusters/aws/authorize_role_service_spec.rb
+++ b/spec/services/clusters/aws/authorize_role_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Clusters::Aws::AuthorizeRoleService do
+RSpec.describe Clusters::Aws::AuthorizeRoleService do
let(:user) { create(:user) }
let(:credentials) { instance_double(Aws::Credentials) }
let(:credentials_service) { instance_double(Clusters::Aws::FetchCredentialsService, execute: credentials) }
diff --git a/spec/services/clusters/aws/fetch_credentials_service_spec.rb b/spec/services/clusters/aws/fetch_credentials_service_spec.rb
index 9194947c67f..a0e63d96a5c 100644
--- a/spec/services/clusters/aws/fetch_credentials_service_spec.rb
+++ b/spec/services/clusters/aws/fetch_credentials_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Clusters::Aws::FetchCredentialsService do
+RSpec.describe Clusters::Aws::FetchCredentialsService do
describe '#execute' do
let(:user) { create(:user) }
let(:provider) { create(:cluster_provider_aws, region: 'ap-southeast-2') }
diff --git a/spec/services/clusters/aws/finalize_creation_service_spec.rb b/spec/services/clusters/aws/finalize_creation_service_spec.rb
index 8d7341483e3..6b0cb86eff0 100644
--- a/spec/services/clusters/aws/finalize_creation_service_spec.rb
+++ b/spec/services/clusters/aws/finalize_creation_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Clusters::Aws::FinalizeCreationService do
+RSpec.describe Clusters::Aws::FinalizeCreationService do
describe '#execute' do
let(:provider) { create(:cluster_provider_aws, :creating) }
let(:platform) { provider.cluster.platform_kubernetes }
diff --git a/spec/services/clusters/aws/provision_service_spec.rb b/spec/services/clusters/aws/provision_service_spec.rb
index 15571c64e13..529e1d26575 100644
--- a/spec/services/clusters/aws/provision_service_spec.rb
+++ b/spec/services/clusters/aws/provision_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Clusters::Aws::ProvisionService do
+RSpec.describe Clusters::Aws::ProvisionService do
describe '#execute' do
let(:provider) { create(:cluster_provider_aws) }
diff --git a/spec/services/clusters/aws/verify_provision_status_service_spec.rb b/spec/services/clusters/aws/verify_provision_status_service_spec.rb
index b62b0875bf3..b9a58b97842 100644
--- a/spec/services/clusters/aws/verify_provision_status_service_spec.rb
+++ b/spec/services/clusters/aws/verify_provision_status_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Clusters::Aws::VerifyProvisionStatusService do
+RSpec.describe Clusters::Aws::VerifyProvisionStatusService do
describe '#execute' do
let(:provider) { create(:cluster_provider_aws) }
diff --git a/spec/services/clusters/build_kubernetes_namespace_service_spec.rb b/spec/services/clusters/build_kubernetes_namespace_service_spec.rb
index 36c05469542..4ee933374f6 100644
--- a/spec/services/clusters/build_kubernetes_namespace_service_spec.rb
+++ b/spec/services/clusters/build_kubernetes_namespace_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Clusters::BuildKubernetesNamespaceService do
+RSpec.describe Clusters::BuildKubernetesNamespaceService do
let(:cluster) { create(:cluster, :project, :provided_by_gcp) }
let(:environment) { create(:environment) }
let(:project) { environment.project }
diff --git a/spec/services/clusters/build_service_spec.rb b/spec/services/clusters/build_service_spec.rb
index f3e852726f4..c7a64435d3b 100644
--- a/spec/services/clusters/build_service_spec.rb
+++ b/spec/services/clusters/build_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Clusters::BuildService do
+RSpec.describe Clusters::BuildService do
describe '#execute' do
subject { described_class.new(cluster_subject).execute }
diff --git a/spec/services/clusters/cleanup/app_service_spec.rb b/spec/services/clusters/cleanup/app_service_spec.rb
index 14bfca02fee..ba1be7448a4 100644
--- a/spec/services/clusters/cleanup/app_service_spec.rb
+++ b/spec/services/clusters/cleanup/app_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Clusters::Cleanup::AppService do
+RSpec.describe Clusters::Cleanup::AppService do
describe '#execute' do
let!(:cluster) { create(:cluster, :project, :cleanup_uninstalling_applications, provider_type: :gcp) }
let(:service) { described_class.new(cluster) }
diff --git a/spec/services/clusters/cleanup/project_namespace_service_spec.rb b/spec/services/clusters/cleanup/project_namespace_service_spec.rb
index 22e29cc57d1..761ad8dd8c8 100644
--- a/spec/services/clusters/cleanup/project_namespace_service_spec.rb
+++ b/spec/services/clusters/cleanup/project_namespace_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Clusters::Cleanup::ProjectNamespaceService do
+RSpec.describe Clusters::Cleanup::ProjectNamespaceService do
describe '#execute' do
subject { service.execute }
diff --git a/spec/services/clusters/cleanup/service_account_service_spec.rb b/spec/services/clusters/cleanup/service_account_service_spec.rb
index ecaf0da9fa3..6fe3d0c286e 100644
--- a/spec/services/clusters/cleanup/service_account_service_spec.rb
+++ b/spec/services/clusters/cleanup/service_account_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Clusters::Cleanup::ServiceAccountService do
+RSpec.describe Clusters::Cleanup::ServiceAccountService do
describe '#execute' do
subject { service.execute }
diff --git a/spec/services/clusters/create_service_spec.rb b/spec/services/clusters/create_service_spec.rb
index 3dd25be2a3d..6e252bee7c0 100644
--- a/spec/services/clusters/create_service_spec.rb
+++ b/spec/services/clusters/create_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Clusters::CreateService do
+RSpec.describe Clusters::CreateService do
let(:access_token) { 'xxx' }
let(:project) { create(:project) }
let(:user) { create(:user) }
@@ -53,13 +53,54 @@ describe Clusters::CreateService do
include_context 'valid cluster create params'
let!(:cluster) { create(:cluster, :provided_by_gcp, :production_environment, projects: [project]) }
- it 'does not create a cluster' do
- expect(ClusterProvisionWorker).not_to receive(:perform_async)
- expect { subject }.to raise_error(ArgumentError).and change { Clusters::Cluster.count }.by(0)
+ it 'creates another cluster' do
+ expect(ClusterProvisionWorker).to receive(:perform_async)
+ expect { subject }.to change { Clusters::Cluster.count }.by(1)
end
end
end
+ context 'when another cluster exists' do
+ let!(:cluster) { create(:cluster, :provided_by_gcp, :production_environment, projects: [project]) }
+
+ context 'when correct params' do
+ let(:params) do
+ {
+ name: 'test-cluster',
+ provider_type: :gcp,
+ provider_gcp_attributes: {
+ gcp_project_id: 'gcp-project',
+ zone: 'us-central1-a',
+ num_nodes: 1,
+ machine_type: 'machine_type-a',
+ legacy_abac: 'true'
+ },
+ clusterable: project
+ }
+ end
+
+ include_examples 'create cluster service success'
+ end
+
+ context 'when invalid params' do
+ let(:params) do
+ {
+ name: 'test-cluster',
+ provider_type: :gcp,
+ provider_gcp_attributes: {
+ gcp_project_id: '!!!!!!!',
+ zone: 'us-central1-a',
+ num_nodes: 1,
+ machine_type: 'machine_type-a'
+ },
+ clusterable: project
+ }
+ end
+
+ include_examples 'create cluster service error'
+ end
+ end
+
context 'when params includes :management_project_id' do
subject(:cluster) { described_class.new(user, params).execute(access_token: access_token) }
diff --git a/spec/services/clusters/destroy_service_spec.rb b/spec/services/clusters/destroy_service_spec.rb
index 43ebf8f499e..76d9cc34b5d 100644
--- a/spec/services/clusters/destroy_service_spec.rb
+++ b/spec/services/clusters/destroy_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Clusters::DestroyService do
+RSpec.describe Clusters::DestroyService do
describe '#execute' do
subject { described_class.new(cluster.user, params).execute(cluster) }
diff --git a/spec/services/clusters/gcp/fetch_operation_service_spec.rb b/spec/services/clusters/gcp/fetch_operation_service_spec.rb
index 23da8004a7d..990cc745382 100644
--- a/spec/services/clusters/gcp/fetch_operation_service_spec.rb
+++ b/spec/services/clusters/gcp/fetch_operation_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Clusters::Gcp::FetchOperationService do
+RSpec.describe Clusters::Gcp::FetchOperationService do
include GoogleApi::CloudPlatformHelpers
describe '#execute' do
diff --git a/spec/services/clusters/gcp/finalize_creation_service_spec.rb b/spec/services/clusters/gcp/finalize_creation_service_spec.rb
index 4d1548c9786..be362dc6e23 100644
--- a/spec/services/clusters/gcp/finalize_creation_service_spec.rb
+++ b/spec/services/clusters/gcp/finalize_creation_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Clusters::Gcp::FinalizeCreationService, '#execute' do
+RSpec.describe Clusters::Gcp::FinalizeCreationService, '#execute' do
include GoogleApi::CloudPlatformHelpers
include KubernetesHelpers
diff --git a/spec/services/clusters/gcp/provision_service_spec.rb b/spec/services/clusters/gcp/provision_service_spec.rb
index dfd15690a1f..c5778db6001 100644
--- a/spec/services/clusters/gcp/provision_service_spec.rb
+++ b/spec/services/clusters/gcp/provision_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Clusters::Gcp::ProvisionService do
+RSpec.describe Clusters::Gcp::ProvisionService do
include GoogleApi::CloudPlatformHelpers
describe '#execute' do
diff --git a/spec/services/clusters/gcp/verify_provision_status_service_spec.rb b/spec/services/clusters/gcp/verify_provision_status_service_spec.rb
index 584f9b8367f..ccb4b3b6c15 100644
--- a/spec/services/clusters/gcp/verify_provision_status_service_spec.rb
+++ b/spec/services/clusters/gcp/verify_provision_status_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Clusters::Gcp::VerifyProvisionStatusService do
+RSpec.describe Clusters::Gcp::VerifyProvisionStatusService do
include GoogleApi::CloudPlatformHelpers
describe '#execute' do
diff --git a/spec/services/clusters/kubernetes/configure_istio_ingress_service_spec.rb b/spec/services/clusters/kubernetes/configure_istio_ingress_service_spec.rb
index e9f7f015293..b4402aadc88 100644
--- a/spec/services/clusters/kubernetes/configure_istio_ingress_service_spec.rb
+++ b/spec/services/clusters/kubernetes/configure_istio_ingress_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Clusters::Kubernetes::ConfigureIstioIngressService, '#execute' do
+RSpec.describe Clusters::Kubernetes::ConfigureIstioIngressService, '#execute' do
include KubernetesHelpers
let(:cluster) { create(:cluster, :project, :provided_by_gcp) }
diff --git a/spec/services/clusters/kubernetes/create_or_update_namespace_service_spec.rb b/spec/services/clusters/kubernetes/create_or_update_namespace_service_spec.rb
index 6d8b1617c17..ee10c59390e 100644
--- a/spec/services/clusters/kubernetes/create_or_update_namespace_service_spec.rb
+++ b/spec/services/clusters/kubernetes/create_or_update_namespace_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Clusters::Kubernetes::CreateOrUpdateNamespaceService, '#execute' do
+RSpec.describe Clusters::Kubernetes::CreateOrUpdateNamespaceService, '#execute' do
include KubernetesHelpers
let(:cluster) { create(:cluster, :project, :provided_by_gcp) }
diff --git a/spec/services/clusters/kubernetes/create_or_update_service_account_service_spec.rb b/spec/services/clusters/kubernetes/create_or_update_service_account_service_spec.rb
index 4bcd5c6933e..f3fa6c2c0bb 100644
--- a/spec/services/clusters/kubernetes/create_or_update_service_account_service_spec.rb
+++ b/spec/services/clusters/kubernetes/create_or_update_service_account_service_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
require 'spec_helper'
-describe Clusters::Kubernetes::CreateOrUpdateServiceAccountService do
+RSpec.describe Clusters::Kubernetes::CreateOrUpdateServiceAccountService do
include KubernetesHelpers
let(:api_url) { 'http://111.111.111.111' }
diff --git a/spec/services/clusters/kubernetes/fetch_kubernetes_token_service_spec.rb b/spec/services/clusters/kubernetes/fetch_kubernetes_token_service_spec.rb
index fa4b6e497e5..c4daae9dbf0 100644
--- a/spec/services/clusters/kubernetes/fetch_kubernetes_token_service_spec.rb
+++ b/spec/services/clusters/kubernetes/fetch_kubernetes_token_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Clusters::Kubernetes::FetchKubernetesTokenService do
+RSpec.describe Clusters::Kubernetes::FetchKubernetesTokenService do
include KubernetesHelpers
describe '#execute' do
diff --git a/spec/services/clusters/kubernetes_spec.rb b/spec/services/clusters/kubernetes_spec.rb
index 09cc304debe..12af63890fc 100644
--- a/spec/services/clusters/kubernetes_spec.rb
+++ b/spec/services/clusters/kubernetes_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Clusters::Kubernetes do
+RSpec.describe Clusters::Kubernetes do
it { is_expected.to be_const_defined(:GITLAB_SERVICE_ACCOUNT_NAME) }
it { is_expected.to be_const_defined(:GITLAB_SERVICE_ACCOUNT_NAMESPACE) }
it { is_expected.to be_const_defined(:GITLAB_ADMIN_TOKEN_NAME) }
diff --git a/spec/services/clusters/management/create_project_service_spec.rb b/spec/services/clusters/management/create_project_service_spec.rb
index b7764b7840c..5d8cc71faa4 100644
--- a/spec/services/clusters/management/create_project_service_spec.rb
+++ b/spec/services/clusters/management/create_project_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Clusters::Management::CreateProjectService do
+RSpec.describe Clusters::Management::CreateProjectService do
let(:cluster) { create(:cluster, :project) }
let(:current_user) { create(:user) }
diff --git a/spec/services/clusters/management/validate_management_project_permissions_service_spec.rb b/spec/services/clusters/management/validate_management_project_permissions_service_spec.rb
index 1bcebe2e2ac..a21c378d3d1 100644
--- a/spec/services/clusters/management/validate_management_project_permissions_service_spec.rb
+++ b/spec/services/clusters/management/validate_management_project_permissions_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Clusters::Management::ValidateManagementProjectPermissionsService do
+RSpec.describe Clusters::Management::ValidateManagementProjectPermissionsService do
describe '#execute' do
subject { described_class.new(user).execute(cluster, management_project_id) }
diff --git a/spec/services/clusters/parse_cluster_applications_artifact_service_spec.rb b/spec/services/clusters/parse_cluster_applications_artifact_service_spec.rb
index bb0b107eba6..3b155d95345 100644
--- a/spec/services/clusters/parse_cluster_applications_artifact_service_spec.rb
+++ b/spec/services/clusters/parse_cluster_applications_artifact_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Clusters::ParseClusterApplicationsArtifactService do
+RSpec.describe Clusters::ParseClusterApplicationsArtifactService do
let_it_be(:project) { create(:project) }
let_it_be(:user) { create(:user) }
@@ -120,90 +120,9 @@ describe Clusters::ParseClusterApplicationsArtifactService do
end
end
- context 'release is missing' do
- let(:fixture) { 'spec/fixtures/helm/helm_list_v2_prometheus_missing.json.gz' }
- let(:file) { fixture_file_upload(Rails.root.join(fixture)) }
- let(:artifact) { create(:ci_job_artifact, :cluster_applications, job: job, file: file) }
-
- context 'application does not exist' do
- it 'does not create or destroy an application' do
- expect do
- described_class.new(job, user).execute(artifact)
- end.not_to change(Clusters::Applications::Prometheus, :count)
- end
- end
-
- context 'application exists' do
- before do
- create(:clusters_applications_prometheus, :installed, cluster: cluster)
- end
-
- it 'marks the application as uninstalled' do
- described_class.new(job, user).execute(artifact)
-
- cluster.application_prometheus.reload
- expect(cluster.application_prometheus).to be_uninstalled
- end
- end
- end
-
- context 'release is deployed' do
- let(:fixture) { 'spec/fixtures/helm/helm_list_v2_prometheus_deployed.json.gz' }
- let(:file) { fixture_file_upload(Rails.root.join(fixture)) }
- let(:artifact) { create(:ci_job_artifact, :cluster_applications, job: job, file: file) }
-
- context 'application does not exist' do
- it 'creates an application and marks it as installed' do
- expect do
- described_class.new(job, user).execute(artifact)
- end.to change(Clusters::Applications::Prometheus, :count)
-
- expect(cluster.application_prometheus).to be_persisted
- expect(cluster.application_prometheus).to be_installed
- end
- end
-
- context 'application exists' do
- before do
- create(:clusters_applications_prometheus, :errored, cluster: cluster)
- end
-
- it 'marks the application as installed' do
- described_class.new(job, user).execute(artifact)
-
- expect(cluster.application_prometheus).to be_installed
- end
- end
- end
-
- context 'release is failed' do
- let(:fixture) { 'spec/fixtures/helm/helm_list_v2_prometheus_failed.json.gz' }
- let(:file) { fixture_file_upload(Rails.root.join(fixture)) }
- let(:artifact) { create(:ci_job_artifact, :cluster_applications, job: job, file: file) }
-
- context 'application does not exist' do
- it 'creates an application and marks it as errored' do
- expect do
- described_class.new(job, user).execute(artifact)
- end.to change(Clusters::Applications::Prometheus, :count)
-
- expect(cluster.application_prometheus).to be_persisted
- expect(cluster.application_prometheus).to be_errored
- expect(cluster.application_prometheus.status_reason).to eq('Helm release failed to install')
- end
- end
-
- context 'application exists' do
- before do
- create(:clusters_applications_prometheus, :installed, cluster: cluster)
- end
-
- it 'marks the application as errored' do
- described_class.new(job, user).execute(artifact)
-
- expect(cluster.application_prometheus).to be_errored
- expect(cluster.application_prometheus.status_reason).to eq('Helm release failed to install')
- end
+ Clusters::ParseClusterApplicationsArtifactService::RELEASE_NAMES.each do |release_name|
+ context release_name do
+ include_examples 'parse cluster applications artifact', release_name
end
end
end
diff --git a/spec/services/clusters/update_service_spec.rb b/spec/services/clusters/update_service_spec.rb
index 5a7726eded8..e496ccd5c23 100644
--- a/spec/services/clusters/update_service_spec.rb
+++ b/spec/services/clusters/update_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Clusters::UpdateService do
+RSpec.describe Clusters::UpdateService do
include KubernetesHelpers
describe '#execute' do
diff --git a/spec/services/cohorts_service_spec.rb b/spec/services/cohorts_service_spec.rb
index b2f82a1153c..dce8d4f80f2 100644
--- a/spec/services/cohorts_service_spec.rb
+++ b/spec/services/cohorts_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe CohortsService do
+RSpec.describe CohortsService do
describe '#execute' do
def month_start(months_ago)
months_ago.months.ago.beginning_of_month.to_date
diff --git a/spec/services/commits/cherry_pick_service_spec.rb b/spec/services/commits/cherry_pick_service_spec.rb
index 3b797b8ac02..8fad5164b77 100644
--- a/spec/services/commits/cherry_pick_service_spec.rb
+++ b/spec/services/commits/cherry_pick_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Commits::CherryPickService do
+RSpec.describe Commits::CherryPickService do
let(:project) { create(:project, :repository) }
# * ddd0f15ae83993f5cb66a927a28673882e99100b (HEAD -> master, origin/master, origin/HEAD) Merge branch 'po-fix-test-en
# |\
diff --git a/spec/services/commits/commit_patch_service_spec.rb b/spec/services/commits/commit_patch_service_spec.rb
index f4fcec2fbc2..c8c0cbe23b2 100644
--- a/spec/services/commits/commit_patch_service_spec.rb
+++ b/spec/services/commits/commit_patch_service_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
require 'spec_helper'
-describe Commits::CommitPatchService do
+RSpec.describe Commits::CommitPatchService do
describe '#execute' do
let(:patches) do
patches_folder = Rails.root.join('spec/fixtures/patchfiles')
diff --git a/spec/services/commits/tag_service_spec.rb b/spec/services/commits/tag_service_spec.rb
index 82377a8dace..dd742ebe469 100644
--- a/spec/services/commits/tag_service_spec.rb
+++ b/spec/services/commits/tag_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Commits::TagService do
+RSpec.describe Commits::TagService do
let(:project) { create(:project, :repository) }
let(:user) { create(:user) }
diff --git a/spec/services/compare_service_spec.rb b/spec/services/compare_service_spec.rb
index f6d8eb348d0..e96a7f2f4f4 100644
--- a/spec/services/compare_service_spec.rb
+++ b/spec/services/compare_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe CompareService do
+RSpec.describe CompareService do
let(:project) { create(:project, :repository) }
let(:user) { create(:user) }
let(:service) { described_class.new(project, 'feature') }
diff --git a/spec/services/concerns/exclusive_lease_guard_spec.rb b/spec/services/concerns/exclusive_lease_guard_spec.rb
index a38facc7520..d54ba6abadd 100644
--- a/spec/services/concerns/exclusive_lease_guard_spec.rb
+++ b/spec/services/concerns/exclusive_lease_guard_spec.rb
@@ -51,7 +51,7 @@ RSpec.describe ExclusiveLeaseGuard, :clean_gitlab_redis_shared_state do
it 'does not call internal_method but logs error', :aggregate_failures do
expect(subject).not_to receive(:internal_method)
- expect(Gitlab::AppLogger).to receive(:error).with('Cannot obtain an exclusive lease. There must be another instance already in execution.')
+ expect(Gitlab::AppLogger).to receive(:error).with("Cannot obtain an exclusive lease for #{subject.class.name}. There must be another instance already in execution.")
subject.call
end
diff --git a/spec/services/concerns/merge_requests/assigns_merge_params_spec.rb b/spec/services/concerns/merge_requests/assigns_merge_params_spec.rb
index 9cf7f354191..5b1e8fca31b 100644
--- a/spec/services/concerns/merge_requests/assigns_merge_params_spec.rb
+++ b/spec/services/concerns/merge_requests/assigns_merge_params_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe MergeRequests::AssignsMergeParams do
+RSpec.describe MergeRequests::AssignsMergeParams do
it 'raises an error when used from an instance that does not respond to #current_user' do
define_class = -> { Class.new { include MergeRequests::AssignsMergeParams }.new }
diff --git a/spec/services/container_expiration_policies/update_service_spec.rb b/spec/services/container_expiration_policies/update_service_spec.rb
index ec178f3830f..d4b6715ae86 100644
--- a/spec/services/container_expiration_policies/update_service_spec.rb
+++ b/spec/services/container_expiration_policies/update_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe ContainerExpirationPolicies::UpdateService do
+RSpec.describe ContainerExpirationPolicies::UpdateService do
using RSpec::Parameterized::TableSyntax
let_it_be(:project, reload: true) { create(:project) }
diff --git a/spec/services/container_expiration_policy_service_spec.rb b/spec/services/container_expiration_policy_service_spec.rb
index 97715b990ef..dfce51d73ad 100644
--- a/spec/services/container_expiration_policy_service_spec.rb
+++ b/spec/services/container_expiration_policy_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe ContainerExpirationPolicyService do
+RSpec.describe ContainerExpirationPolicyService do
let_it_be(:user) { create(:user) }
let_it_be(:container_expiration_policy) { create(:container_expiration_policy, :runnable) }
let(:project) { container_expiration_policy.project }
diff --git a/spec/services/deploy_keys/collect_keys_service_spec.rb b/spec/services/deploy_keys/collect_keys_service_spec.rb
new file mode 100644
index 00000000000..3442e5e456a
--- /dev/null
+++ b/spec/services/deploy_keys/collect_keys_service_spec.rb
@@ -0,0 +1,58 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe DeployKeys::CollectKeysService do
+ let_it_be(:user) { create(:user) }
+ let_it_be(:project) { create(:project, :private) }
+
+ subject { DeployKeys::CollectKeysService.new(project, user) }
+
+ before do
+ project&.add_developer(user)
+ end
+
+ context 'when no project is passed in' do
+ let(:project) { nil }
+
+ it 'returns an empty Array' do
+ expect(subject.execute).to be_empty
+ end
+ end
+
+ context 'when no user is passed in' do
+ let(:user) { nil }
+
+ it 'returns an empty Array' do
+ expect(subject.execute).to be_empty
+ end
+ end
+
+ context 'when a project is passed in' do
+ let_it_be(:deploy_keys_project) { create(:deploy_keys_project, :write_access, project: project) }
+ let_it_be(:deploy_key) { deploy_keys_project.deploy_key }
+
+ it 'only returns deploy keys with write access' do
+ create(:deploy_keys_project, project: project)
+
+ expect(subject.execute).to contain_exactly(deploy_key)
+ end
+
+ it 'returns deploy keys only for this project' do
+ other_project = create(:project)
+ create(:deploy_keys_project, :write_access, project: other_project)
+
+ expect(subject.execute).to contain_exactly(deploy_key)
+ end
+ end
+
+ context 'when the user cannot read the project' do
+ before do
+ project.members.delete_all
+ end
+
+ it 'returns an empty Array' do
+ expect(subject.execute).to be_empty
+ end
+ end
+end
diff --git a/spec/services/deploy_keys/create_service_spec.rb b/spec/services/deploy_keys/create_service_spec.rb
index a55f1561194..2e3318236f5 100644
--- a/spec/services/deploy_keys/create_service_spec.rb
+++ b/spec/services/deploy_keys/create_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe DeployKeys::CreateService do
+RSpec.describe DeployKeys::CreateService do
let(:user) { create(:user) }
let(:params) { attributes_for(:deploy_key) }
diff --git a/spec/services/deployments/after_create_service_spec.rb b/spec/services/deployments/after_create_service_spec.rb
index 5a69ffd8b9c..3287eed03b7 100644
--- a/spec/services/deployments/after_create_service_spec.rb
+++ b/spec/services/deployments/after_create_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Deployments::AfterCreateService do
+RSpec.describe Deployments::AfterCreateService do
let(:user) { create(:user) }
let(:project) { create(:project, :repository) }
let(:options) { { name: 'production' } }
diff --git a/spec/services/deployments/create_service_spec.rb b/spec/services/deployments/create_service_spec.rb
index 6ab1f8635f7..d1f977c28d3 100644
--- a/spec/services/deployments/create_service_spec.rb
+++ b/spec/services/deployments/create_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Deployments::CreateService do
+RSpec.describe Deployments::CreateService do
let(:user) { create(:user) }
describe '#execute' do
diff --git a/spec/services/deployments/link_merge_requests_service_spec.rb b/spec/services/deployments/link_merge_requests_service_spec.rb
index aa2cecbf897..e2ac2273b8c 100644
--- a/spec/services/deployments/link_merge_requests_service_spec.rb
+++ b/spec/services/deployments/link_merge_requests_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Deployments::LinkMergeRequestsService do
+RSpec.describe Deployments::LinkMergeRequestsService do
let(:project) { create(:project, :repository) }
# * ddd0f15 Merge branch 'po-fix-test-env-path' into 'master'
diff --git a/spec/services/deployments/older_deployments_drop_service_spec.rb b/spec/services/deployments/older_deployments_drop_service_spec.rb
index 4c9bcf90533..6152a95cc3c 100644
--- a/spec/services/deployments/older_deployments_drop_service_spec.rb
+++ b/spec/services/deployments/older_deployments_drop_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Deployments::OlderDeploymentsDropService do
+RSpec.describe Deployments::OlderDeploymentsDropService do
let(:environment) { create(:environment) }
let(:deployment) { create(:deployment, environment: environment) }
let(:service) { described_class.new(deployment) }
diff --git a/spec/services/deployments/update_service_spec.rb b/spec/services/deployments/update_service_spec.rb
index 471e90de467..16b24d0dee8 100644
--- a/spec/services/deployments/update_service_spec.rb
+++ b/spec/services/deployments/update_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Deployments::UpdateService do
+RSpec.describe Deployments::UpdateService do
let(:deploy) { create(:deployment) }
describe '#execute' do
diff --git a/spec/services/design_management/delete_designs_service_spec.rb b/spec/services/design_management/delete_designs_service_spec.rb
index bf5d6b443e6..ace63b6e59c 100644
--- a/spec/services/design_management/delete_designs_service_spec.rb
+++ b/spec/services/design_management/delete_designs_service_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
require 'spec_helper'
-describe DesignManagement::DeleteDesignsService do
+RSpec.describe DesignManagement::DeleteDesignsService do
include DesignManagementTestHelpers
let_it_be(:project) { create(:project) }
diff --git a/spec/services/design_management/design_user_notes_count_service_spec.rb b/spec/services/design_management/design_user_notes_count_service_spec.rb
index 62211a4dd0f..37806d3461c 100644
--- a/spec/services/design_management/design_user_notes_count_service_spec.rb
+++ b/spec/services/design_management/design_user_notes_count_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe DesignManagement::DesignUserNotesCountService, :use_clean_rails_memory_store_caching do
+RSpec.describe DesignManagement::DesignUserNotesCountService, :use_clean_rails_memory_store_caching do
let_it_be(:design) { create(:design, :with_file) }
subject { described_class.new(design) }
diff --git a/spec/services/design_management/generate_image_versions_service_spec.rb b/spec/services/design_management/generate_image_versions_service_spec.rb
index cd021c8d7d3..631eec97e5a 100644
--- a/spec/services/design_management/generate_image_versions_service_spec.rb
+++ b/spec/services/design_management/generate_image_versions_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe DesignManagement::GenerateImageVersionsService do
+RSpec.describe DesignManagement::GenerateImageVersionsService do
let_it_be(:project) { create(:project) }
let_it_be(:issue) { create(:issue, project: project) }
let_it_be(:version) { create(:design, :with_lfs_file, issue: issue).versions.first }
diff --git a/spec/services/design_management/save_designs_service_spec.rb b/spec/services/design_management/save_designs_service_spec.rb
index 3be3ac9daca..24639632566 100644
--- a/spec/services/design_management/save_designs_service_spec.rb
+++ b/spec/services/design_management/save_designs_service_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
require 'spec_helper'
-describe DesignManagement::SaveDesignsService do
+RSpec.describe DesignManagement::SaveDesignsService do
include DesignManagementTestHelpers
include ConcurrentHelpers
diff --git a/spec/services/discussions/capture_diff_note_position_service_spec.rb b/spec/services/discussions/capture_diff_note_position_service_spec.rb
index bc71e170e92..0913ddd8ef2 100644
--- a/spec/services/discussions/capture_diff_note_position_service_spec.rb
+++ b/spec/services/discussions/capture_diff_note_position_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Discussions::CaptureDiffNotePositionService do
+RSpec.describe Discussions::CaptureDiffNotePositionService do
subject { described_class.new(note.noteable, paths) }
context 'image note on diff' do
diff --git a/spec/services/discussions/capture_diff_note_positions_service_spec.rb b/spec/services/discussions/capture_diff_note_positions_service_spec.rb
index 7b1e207f3eb..dede5a4c354 100644
--- a/spec/services/discussions/capture_diff_note_positions_service_spec.rb
+++ b/spec/services/discussions/capture_diff_note_positions_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Discussions::CaptureDiffNotePositionsService do
+RSpec.describe Discussions::CaptureDiffNotePositionsService do
context 'when merge request has a discussion' do
let(:source_branch) { 'compare-with-merge-head-source' }
let(:target_branch) { 'compare-with-merge-head-target' }
diff --git a/spec/services/discussions/resolve_service_spec.rb b/spec/services/discussions/resolve_service_spec.rb
index 7461934b455..5ff0d535b46 100644
--- a/spec/services/discussions/resolve_service_spec.rb
+++ b/spec/services/discussions/resolve_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Discussions::ResolveService do
+RSpec.describe Discussions::ResolveService do
describe '#execute' do
let_it_be(:project) { create(:project, :repository) }
let_it_be(:user) { create(:user, developer_projects: [project]) }
diff --git a/spec/services/discussions/update_diff_position_service_spec.rb b/spec/services/discussions/update_diff_position_service_spec.rb
index 60ec83e9062..85020e95c83 100644
--- a/spec/services/discussions/update_diff_position_service_spec.rb
+++ b/spec/services/discussions/update_diff_position_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Discussions::UpdateDiffPositionService do
+RSpec.describe Discussions::UpdateDiffPositionService do
let(:project) { create(:project, :repository) }
let(:current_user) { project.owner }
let(:create_commit) { project.commit("913c66a37b4a45b9769037c55c2d238bd0942d2e") }
diff --git a/spec/services/draft_notes/create_service_spec.rb b/spec/services/draft_notes/create_service_spec.rb
index 8f244ed386b..f0291067777 100644
--- a/spec/services/draft_notes/create_service_spec.rb
+++ b/spec/services/draft_notes/create_service_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
require 'spec_helper'
-describe DraftNotes::CreateService do
+RSpec.describe DraftNotes::CreateService do
let(:merge_request) { create(:merge_request) }
let(:project) { merge_request.target_project }
let(:user) { merge_request.author }
diff --git a/spec/services/draft_notes/destroy_service_spec.rb b/spec/services/draft_notes/destroy_service_spec.rb
index d0bf88dcdbe..f725f08f3c7 100644
--- a/spec/services/draft_notes/destroy_service_spec.rb
+++ b/spec/services/draft_notes/destroy_service_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
require 'spec_helper'
-describe DraftNotes::DestroyService do
+RSpec.describe DraftNotes::DestroyService do
let(:merge_request) { create(:merge_request) }
let(:project) { merge_request.target_project }
let(:user) { merge_request.author }
diff --git a/spec/services/draft_notes/publish_service_spec.rb b/spec/services/draft_notes/publish_service_spec.rb
index 4ebae2f9aa2..ae0c8113904 100644
--- a/spec/services/draft_notes/publish_service_spec.rb
+++ b/spec/services/draft_notes/publish_service_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
require 'spec_helper'
-describe DraftNotes::PublishService do
+RSpec.describe DraftNotes::PublishService do
include RepoHelpers
let(:merge_request) { create(:merge_request) }
@@ -237,7 +237,8 @@ describe DraftNotes::PublishService do
it 'resolves the thread' do
publish(draft: draft_note)
- expect(note.discussion.resolved?).to be true
+ # discussion is memoized and reload doesn't clear the memoization
+ expect(Note.find(note.id).discussion.resolved?).to be true
end
it 'sends notifications if all threads are resolved' do
diff --git a/spec/services/emails/confirm_service_spec.rb b/spec/services/emails/confirm_service_spec.rb
index 973d2731b2f..935a673f548 100644
--- a/spec/services/emails/confirm_service_spec.rb
+++ b/spec/services/emails/confirm_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Emails::ConfirmService do
+RSpec.describe Emails::ConfirmService do
let(:user) { create(:user) }
subject(:service) { described_class.new(user) }
diff --git a/spec/services/emails/create_service_spec.rb b/spec/services/emails/create_service_spec.rb
index 23c2f53dca0..1396a1fce30 100644
--- a/spec/services/emails/create_service_spec.rb
+++ b/spec/services/emails/create_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Emails::CreateService do
+RSpec.describe Emails::CreateService do
let(:user) { create(:user) }
let(:opts) { { email: 'new@email.com', user: user } }
diff --git a/spec/services/emails/destroy_service_spec.rb b/spec/services/emails/destroy_service_spec.rb
index 9e14a13aa4f..f8407be41e7 100644
--- a/spec/services/emails/destroy_service_spec.rb
+++ b/spec/services/emails/destroy_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Emails::DestroyService do
+RSpec.describe Emails::DestroyService do
let!(:user) { create(:user) }
let!(:email) { create(:email, user: user) }
diff --git a/spec/services/environments/auto_stop_service_spec.rb b/spec/services/environments/auto_stop_service_spec.rb
index b34d15889d3..8e56c7e642c 100644
--- a/spec/services/environments/auto_stop_service_spec.rb
+++ b/spec/services/environments/auto_stop_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Environments::AutoStopService, :clean_gitlab_redis_shared_state do
+RSpec.describe Environments::AutoStopService, :clean_gitlab_redis_shared_state do
include CreateEnvironmentsHelpers
include ExclusiveLeaseHelpers
diff --git a/spec/services/environments/reset_auto_stop_service_spec.rb b/spec/services/environments/reset_auto_stop_service_spec.rb
index 53a20dd906e..cab1bf2cc26 100644
--- a/spec/services/environments/reset_auto_stop_service_spec.rb
+++ b/spec/services/environments/reset_auto_stop_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Environments::ResetAutoStopService do
+RSpec.describe Environments::ResetAutoStopService do
let_it_be(:project) { create(:project) }
let_it_be(:developer) { create(:user).tap { |user| project.add_developer(user) } }
let_it_be(:reporter) { create(:user).tap { |user| project.add_reporter(user) } }
diff --git a/spec/services/error_tracking/base_service_spec.rb b/spec/services/error_tracking/base_service_spec.rb
index 68deb2e2a73..ffbda37d417 100644
--- a/spec/services/error_tracking/base_service_spec.rb
+++ b/spec/services/error_tracking/base_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe ErrorTracking::BaseService do
+RSpec.describe ErrorTracking::BaseService do
describe '#compose_response' do
let(:project) { double('project') }
let(:user) { double('user') }
diff --git a/spec/services/error_tracking/issue_details_service_spec.rb b/spec/services/error_tracking/issue_details_service_spec.rb
index 66b8988f8e3..1954640a512 100644
--- a/spec/services/error_tracking/issue_details_service_spec.rb
+++ b/spec/services/error_tracking/issue_details_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe ErrorTracking::IssueDetailsService do
+RSpec.describe ErrorTracking::IssueDetailsService do
include_context 'sentry error tracking context'
subject { described_class.new(project, user, params) }
diff --git a/spec/services/error_tracking/issue_latest_event_service_spec.rb b/spec/services/error_tracking/issue_latest_event_service_spec.rb
index 078d7511850..b7560762ae4 100644
--- a/spec/services/error_tracking/issue_latest_event_service_spec.rb
+++ b/spec/services/error_tracking/issue_latest_event_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe ErrorTracking::IssueLatestEventService do
+RSpec.describe ErrorTracking::IssueLatestEventService do
include_context 'sentry error tracking context'
subject { described_class.new(project, user) }
diff --git a/spec/services/error_tracking/issue_update_service_spec.rb b/spec/services/error_tracking/issue_update_service_spec.rb
index a13d42ec141..9ed24038ed8 100644
--- a/spec/services/error_tracking/issue_update_service_spec.rb
+++ b/spec/services/error_tracking/issue_update_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe ErrorTracking::IssueUpdateService do
+RSpec.describe ErrorTracking::IssueUpdateService do
include_context 'sentry error tracking context'
let(:arguments) { { issue_id: non_existing_record_id, status: 'resolved' } }
diff --git a/spec/services/error_tracking/list_issues_service_spec.rb b/spec/services/error_tracking/list_issues_service_spec.rb
index 5f6e071e10d..518f2a80826 100644
--- a/spec/services/error_tracking/list_issues_service_spec.rb
+++ b/spec/services/error_tracking/list_issues_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe ErrorTracking::ListIssuesService do
+RSpec.describe ErrorTracking::ListIssuesService do
include_context 'sentry error tracking context'
let(:params) { { search_term: 'something', sort: 'last_seen', cursor: 'some-cursor' } }
diff --git a/spec/services/error_tracking/list_projects_service_spec.rb b/spec/services/error_tracking/list_projects_service_spec.rb
index 565610c64ac..8bc632349fa 100644
--- a/spec/services/error_tracking/list_projects_service_spec.rb
+++ b/spec/services/error_tracking/list_projects_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe ErrorTracking::ListProjectsService do
+RSpec.describe ErrorTracking::ListProjectsService do
let_it_be(:user) { create(:user) }
let_it_be(:project, reload: true) { create(:project) }
diff --git a/spec/services/event_create_service_spec.rb b/spec/services/event_create_service_spec.rb
index 73c089334ed..d10ed7d6640 100644
--- a/spec/services/event_create_service_spec.rb
+++ b/spec/services/event_create_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe EventCreateService do
+RSpec.describe EventCreateService do
let(:service) { described_class.new }
let_it_be(:user, reload: true) { create :user }
@@ -16,7 +16,6 @@ describe EventCreateService do
it "creates new event" do
expect { service.open_issue(issue, issue.author) }.to change { Event.count }
- expect { service.open_issue(issue, issue.author) }.to change { ResourceStateEvent.count }
end
end
@@ -27,7 +26,6 @@ describe EventCreateService do
it "creates new event" do
expect { service.close_issue(issue, issue.author) }.to change { Event.count }
- expect { service.close_issue(issue, issue.author) }.to change { ResourceStateEvent.count }
end
end
@@ -38,7 +36,6 @@ describe EventCreateService do
it "creates new event" do
expect { service.reopen_issue(issue, issue.author) }.to change { Event.count }
- expect { service.reopen_issue(issue, issue.author) }.to change { ResourceStateEvent.count }
end
end
end
@@ -51,7 +48,6 @@ describe EventCreateService do
it "creates new event" do
expect { service.open_mr(merge_request, merge_request.author) }.to change { Event.count }
- expect { service.open_mr(merge_request, merge_request.author) }.to change { ResourceStateEvent.count }
end
end
@@ -62,7 +58,6 @@ describe EventCreateService do
it "creates new event" do
expect { service.close_mr(merge_request, merge_request.author) }.to change { Event.count }
- expect { service.close_mr(merge_request, merge_request.author) }.to change { ResourceStateEvent.count }
end
end
@@ -73,7 +68,6 @@ describe EventCreateService do
it "creates new event" do
expect { service.merge_mr(merge_request, merge_request.author) }.to change { Event.count }
- expect { service.merge_mr(merge_request, merge_request.author) }.to change { ResourceStateEvent.count }
end
end
@@ -84,7 +78,18 @@ describe EventCreateService do
it "creates new event" do
expect { service.reopen_mr(merge_request, merge_request.author) }.to change { Event.count }
- expect { service.reopen_mr(merge_request, merge_request.author) }.to change { ResourceStateEvent.count }
+ end
+ end
+
+ describe '#approve_mr' do
+ let(:merge_request) { create(:merge_request) }
+
+ it { expect(service.approve_mr(merge_request, user)).to be_truthy }
+
+ it 'creates new event' do
+ service.approve_mr(merge_request, user)
+
+ change { Event.approved_action.where(target: merge_request).count }.by(1)
end
end
end
@@ -161,7 +166,7 @@ describe EventCreateService do
end
end
- describe '#wiki_event' do
+ describe '#wiki_event', :clean_gitlab_redis_shared_state do
let_it_be(:user) { create(:user) }
let_it_be(:wiki_page) { create(:wiki_page) }
let_it_be(:meta) { create(:wiki_page_meta, :for_wiki_page, wiki_page: wiki_page) }
@@ -181,6 +186,16 @@ describe EventCreateService do
)
end
+ it 'records the event in the event counter' do
+ stub_feature_flags(Gitlab::UsageDataCounters::TrackUniqueActions::FEATURE_FLAG => true)
+ counter_class = Gitlab::UsageDataCounters::TrackUniqueActions
+ tracking_params = { event_action: counter_class::WIKI_ACTION, date_from: Date.yesterday, date_to: Date.today }
+
+ expect { event }
+ .to change { counter_class.count_unique_events(tracking_params) }
+ .from(0).to(1)
+ end
+
it 'is idempotent', :aggregate_failures do
expect { event }.to change(Event, :count).by(1)
duplicate = nil
@@ -188,16 +203,6 @@ describe EventCreateService do
expect(duplicate).to eq(event)
end
-
- context 'the feature is disabled' do
- before do
- stub_feature_flags(wiki_events: false)
- end
-
- it 'does not create the event' do
- expect { event }.not_to change(Event, :count)
- end
- end
end
end
@@ -229,6 +234,16 @@ describe EventCreateService do
subject { service.push(project, user, push_data) }
it_behaves_like 'service for creating a push event', PushEventPayloadService
+
+ it 'records the event in the event counter' do
+ stub_feature_flags(Gitlab::UsageDataCounters::TrackUniqueActions::FEATURE_FLAG => true)
+ counter_class = Gitlab::UsageDataCounters::TrackUniqueActions
+ tracking_params = { event_action: counter_class::PUSH_ACTION, date_from: Date.yesterday, date_to: Date.today }
+
+ expect { subject }
+ .to change { counter_class.count_unique_events(tracking_params) }
+ .from(0).to(1)
+ end
end
describe '#bulk_push', :clean_gitlab_redis_shared_state do
@@ -243,6 +258,16 @@ describe EventCreateService do
subject { service.bulk_push(project, user, push_data) }
it_behaves_like 'service for creating a push event', BulkPushEventPayloadService
+
+ it 'records the event in the event counter' do
+ stub_feature_flags(Gitlab::UsageDataCounters::TrackUniqueActions::FEATURE_FLAG => true)
+ counter_class = Gitlab::UsageDataCounters::TrackUniqueActions
+ tracking_params = { event_action: counter_class::PUSH_ACTION, date_from: Date.yesterday, date_to: Date.today }
+
+ expect { subject }
+ .to change { counter_class.count_unique_events(tracking_params) }
+ .from(0).to(1)
+ end
end
describe 'Project' do
@@ -261,31 +286,10 @@ describe EventCreateService do
end
end
- describe 'design events' do
+ describe 'design events', :clean_gitlab_redis_shared_state do
let_it_be(:design) { create(:design, project: project) }
let_it_be(:author) { user }
- shared_examples 'feature flag gated multiple event creation' do
- context 'the feature flag is off' do
- before do
- stub_feature_flags(design_activity_events: false)
- end
-
- specify { expect(result).to be_empty }
- specify { expect { result }.not_to change { Event.count } }
- specify { expect { result }.not_to exceed_query_limit(0) }
- end
-
- context 'the feature flag is enabled for a single project' do
- before do
- stub_feature_flags(design_activity_events: project)
- end
-
- specify { expect(result).not_to be_empty }
- specify { expect { result }.to change { Event.count }.by(1) }
- end
- end
-
describe '#save_designs' do
let_it_be(:updated) { create_list(:design, 5) }
let_it_be(:created) { create_list(:design, 3) }
@@ -310,8 +314,14 @@ describe EventCreateService do
expect(events.map(&:design)).to match_array(updated)
end
- it_behaves_like 'feature flag gated multiple event creation' do
- let(:project) { created.first.project }
+ it 'records the event in the event counter' do
+ stub_feature_flags(Gitlab::UsageDataCounters::TrackUniqueActions::FEATURE_FLAG => true)
+ counter_class = Gitlab::UsageDataCounters::TrackUniqueActions
+ tracking_params = { event_action: counter_class::DESIGN_ACTION, date_from: Date.yesterday, date_to: Date.today }
+
+ expect { result }
+ .to change { counter_class.count_unique_events(tracking_params) }
+ .from(0).to(1)
end
end
@@ -332,8 +342,14 @@ describe EventCreateService do
expect(events.map(&:design)).to match_array(designs)
end
- it_behaves_like 'feature flag gated multiple event creation' do
- let(:project) { designs.first.project }
+ it 'records the event in the event counter' do
+ stub_feature_flags(Gitlab::UsageDataCounters::TrackUniqueActions::FEATURE_FLAG => true)
+ counter_class = Gitlab::UsageDataCounters::TrackUniqueActions
+ tracking_params = { event_action: counter_class::DESIGN_ACTION, date_from: Date.yesterday, date_to: Date.today }
+
+ expect { result }
+ .to change { counter_class.count_unique_events(tracking_params) }
+ .from(0).to(1)
end
end
end
diff --git a/spec/services/events/render_service_spec.rb b/spec/services/events/render_service_spec.rb
index a623a05a56d..24a3b9abe14 100644
--- a/spec/services/events/render_service_spec.rb
+++ b/spec/services/events/render_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Events::RenderService do
+RSpec.describe Events::RenderService do
describe '#execute' do
let!(:note) { build(:note) }
let!(:event) { build(:event, target: note, project: note.project) }
diff --git a/spec/services/files/create_service_spec.rb b/spec/services/files/create_service_spec.rb
index 195f56a2909..3b3dbd1fcfe 100644
--- a/spec/services/files/create_service_spec.rb
+++ b/spec/services/files/create_service_spec.rb
@@ -2,7 +2,7 @@
require "spec_helper"
-describe Files::CreateService do
+RSpec.describe Files::CreateService do
let(:project) { create(:project, :repository) }
let(:repository) { project.repository }
let(:user) { create(:user, :commit_email) }
diff --git a/spec/services/files/delete_service_spec.rb b/spec/services/files/delete_service_spec.rb
index b849def06fc..17e4645fde6 100644
--- a/spec/services/files/delete_service_spec.rb
+++ b/spec/services/files/delete_service_spec.rb
@@ -2,7 +2,7 @@
require "spec_helper"
-describe Files::DeleteService do
+RSpec.describe Files::DeleteService do
subject { described_class.new(project, user, commit_params) }
let(:project) { create(:project, :repository) }
diff --git a/spec/services/files/multi_service_spec.rb b/spec/services/files/multi_service_spec.rb
index 0f51c72019e..6a5c7d2749d 100644
--- a/spec/services/files/multi_service_spec.rb
+++ b/spec/services/files/multi_service_spec.rb
@@ -2,7 +2,7 @@
require "spec_helper"
-describe Files::MultiService do
+RSpec.describe Files::MultiService do
subject { described_class.new(project, user, commit_params) }
let(:project) { create(:project, :repository) }
diff --git a/spec/services/files/update_service_spec.rb b/spec/services/files/update_service_spec.rb
index 37869b176ef..84d78b4c2bc 100644
--- a/spec/services/files/update_service_spec.rb
+++ b/spec/services/files/update_service_spec.rb
@@ -2,7 +2,7 @@
require "spec_helper"
-describe Files::UpdateService do
+RSpec.describe Files::UpdateService do
subject { described_class.new(project, user, commit_params) }
let(:project) { create(:project, :repository) }
diff --git a/spec/services/git/base_hooks_service_spec.rb b/spec/services/git/base_hooks_service_spec.rb
index 07ce560bd88..661c77b56bb 100644
--- a/spec/services/git/base_hooks_service_spec.rb
+++ b/spec/services/git/base_hooks_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Git::BaseHooksService do
+RSpec.describe Git::BaseHooksService do
include RepoHelpers
include GitHelpers
diff --git a/spec/services/git/branch_hooks_service_spec.rb b/spec/services/git/branch_hooks_service_spec.rb
index 908b9772c40..7f22af8bfc6 100644
--- a/spec/services/git/branch_hooks_service_spec.rb
+++ b/spec/services/git/branch_hooks_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Git::BranchHooksService do
+RSpec.describe Git::BranchHooksService do
include RepoHelpers
include ProjectForksHelper
diff --git a/spec/services/git/branch_push_service_spec.rb b/spec/services/git/branch_push_service_spec.rb
index 6ecc1a62ff3..6ccf2d03e4a 100644
--- a/spec/services/git/branch_push_service_spec.rb
+++ b/spec/services/git/branch_push_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Git::BranchPushService, services: true do
+RSpec.describe Git::BranchPushService, services: true do
include RepoHelpers
let_it_be(:user) { create(:user) }
@@ -635,6 +635,37 @@ describe Git::BranchPushService, services: true do
end
end
+ describe 'artifacts' do
+ context 'create branch' do
+ let(:oldrev) { blankrev }
+
+ it 'does nothing' do
+ expect(::Ci::RefDeleteUnlockArtifactsWorker).not_to receive(:perform_async)
+
+ execute_service(project, user, oldrev: oldrev, newrev: newrev, ref: ref)
+ end
+ end
+
+ context 'update branch' do
+ it 'does nothing' do
+ expect(::Ci::RefDeleteUnlockArtifactsWorker).not_to receive(:perform_async)
+
+ execute_service(project, user, oldrev: oldrev, newrev: newrev, ref: ref)
+ end
+ end
+
+ context 'delete branch' do
+ let(:newrev) { blankrev }
+
+ it 'unlocks artifacts' do
+ expect(::Ci::RefDeleteUnlockArtifactsWorker)
+ .to receive(:perform_async).with(project.id, user.id, "refs/heads/#{branch}")
+
+ execute_service(project, user, oldrev: oldrev, newrev: newrev, ref: ref)
+ end
+ end
+ end
+
describe 'Hooks' do
context 'run on a branch' do
it 'delegates to Git::BranchHooksService' do
diff --git a/spec/services/git/process_ref_changes_service_spec.rb b/spec/services/git/process_ref_changes_service_spec.rb
index 924e913a9ec..c2fb40a0ed0 100644
--- a/spec/services/git/process_ref_changes_service_spec.rb
+++ b/spec/services/git/process_ref_changes_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Git::ProcessRefChangesService do
+RSpec.describe Git::ProcessRefChangesService do
let(:project) { create(:project, :repository) }
let(:user) { project.owner }
let(:params) { { changes: git_changes } }
diff --git a/spec/services/git/tag_hooks_service_spec.rb b/spec/services/git/tag_hooks_service_spec.rb
index 094ccd8c9f0..4443c46a414 100644
--- a/spec/services/git/tag_hooks_service_spec.rb
+++ b/spec/services/git/tag_hooks_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Git::TagHooksService, :service do
+RSpec.describe Git::TagHooksService, :service do
let(:user) { create(:user) }
let(:project) { create(:project, :repository) }
diff --git a/spec/services/git/tag_push_service_spec.rb b/spec/services/git/tag_push_service_spec.rb
index 9688041c08c..87dbf79a245 100644
--- a/spec/services/git/tag_push_service_spec.rb
+++ b/spec/services/git/tag_push_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Git::TagPushService do
+RSpec.describe Git::TagPushService do
include RepoHelpers
include GitHelpers
@@ -10,9 +10,11 @@ describe Git::TagPushService do
let(:project) { create(:project, :repository) }
let(:service) { described_class.new(project, user, change: { oldrev: oldrev, newrev: newrev, ref: ref }) }
- let(:oldrev) { Gitlab::Git::BLANK_SHA }
+ let(:blankrev) { Gitlab::Git::BLANK_SHA }
+ let(:oldrev) { blankrev }
let(:newrev) { "8a2a6eb295bb170b34c24c76c49ed0e9b2eaf34b" } # gitlab-test: git rev-parse refs/tags/v1.1.0
- let(:ref) { 'refs/tags/v1.1.0' }
+ let(:tag) { 'v1.1.0' }
+ let(:ref) { "refs/tags/#{tag}" }
describe "Push tags" do
subject do
@@ -58,4 +60,35 @@ describe Git::TagPushService do
end
end
end
+
+ describe 'artifacts' do
+ context 'create tag' do
+ let(:oldrev) { blankrev }
+
+ it 'does nothing' do
+ expect(::Ci::RefDeleteUnlockArtifactsWorker).not_to receive(:perform_async)
+
+ service.execute
+ end
+ end
+
+ context 'update tag' do
+ it 'does nothing' do
+ expect(::Ci::RefDeleteUnlockArtifactsWorker).not_to receive(:perform_async)
+
+ service.execute
+ end
+ end
+
+ context 'delete tag' do
+ let(:newrev) { blankrev }
+
+ it 'unlocks artifacts' do
+ expect(::Ci::RefDeleteUnlockArtifactsWorker)
+ .to receive(:perform_async).with(project.id, user.id, "refs/tags/#{tag}")
+
+ service.execute
+ end
+ end
+ end
end
diff --git a/spec/services/git/wiki_push_service/change_spec.rb b/spec/services/git/wiki_push_service/change_spec.rb
index 4da3f0fc738..3616bf62b20 100644
--- a/spec/services/git/wiki_push_service/change_spec.rb
+++ b/spec/services/git/wiki_push_service/change_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Git::WikiPushService::Change do
+RSpec.describe Git::WikiPushService::Change do
subject { described_class.new(project_wiki, change, raw_change) }
let(:project_wiki) { double('ProjectWiki') }
diff --git a/spec/services/git/wiki_push_service_spec.rb b/spec/services/git/wiki_push_service_spec.rb
index b2234c81c24..f338b7a5709 100644
--- a/spec/services/git/wiki_push_service_spec.rb
+++ b/spec/services/git/wiki_push_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Git::WikiPushService, services: true do
+RSpec.describe Git::WikiPushService, services: true do
include RepoHelpers
let_it_be(:key_id) { create(:key, user: current_user).shell_id }
@@ -247,14 +247,6 @@ describe Git::WikiPushService, services: true do
end
end
- context 'the wiki_events feature is disabled' do
- before do
- stub_feature_flags(wiki_events: false)
- end
-
- it_behaves_like 'a no-op push'
- end
-
context 'the wiki_events_on_git_push feature is disabled' do
before do
stub_feature_flags(wiki_events_on_git_push: false)
diff --git a/spec/services/gpg_keys/create_service_spec.rb b/spec/services/gpg_keys/create_service_spec.rb
index 8dfc9f19439..9ac56355b4b 100644
--- a/spec/services/gpg_keys/create_service_spec.rb
+++ b/spec/services/gpg_keys/create_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe GpgKeys::CreateService do
+RSpec.describe GpgKeys::CreateService do
let(:user) { create(:user) }
let(:params) { attributes_for(:gpg_key) }
diff --git a/spec/services/gpg_keys/destroy_service_spec.rb b/spec/services/gpg_keys/destroy_service_spec.rb
new file mode 100644
index 00000000000..b9aa3e351c9
--- /dev/null
+++ b/spec/services/gpg_keys/destroy_service_spec.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe GpgKeys::DestroyService do
+ let(:user) { create(:user) }
+
+ subject { described_class.new(user) }
+
+ it 'destroys the GPG key' do
+ gpg_key = create(:gpg_key)
+
+ expect { subject.execute(gpg_key) }.to change(GpgKey, :count).by(-1)
+ end
+end
diff --git a/spec/services/grafana/proxy_service_spec.rb b/spec/services/grafana/proxy_service_spec.rb
index 8cb7210524a..7ddc31d45d9 100644
--- a/spec/services/grafana/proxy_service_spec.rb
+++ b/spec/services/grafana/proxy_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Grafana::ProxyService do
+RSpec.describe Grafana::ProxyService do
include ReactiveCachingHelpers
let_it_be(:project) { create(:project) }
diff --git a/spec/services/gravatar_service_spec.rb b/spec/services/gravatar_service_spec.rb
index 9ce1df0f76f..a6418b02f78 100644
--- a/spec/services/gravatar_service_spec.rb
+++ b/spec/services/gravatar_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe GravatarService do
+RSpec.describe GravatarService do
describe '#execute' do
let(:url) { 'http://example.com/avatar?hash=%{hash}&size=%{size}&email=%{email}&username=%{username}' }
diff --git a/spec/services/groups/auto_devops_service_spec.rb b/spec/services/groups/auto_devops_service_spec.rb
index 63fbdc70c1b..3d89ee96823 100644
--- a/spec/services/groups/auto_devops_service_spec.rb
+++ b/spec/services/groups/auto_devops_service_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
require 'spec_helper'
-describe Groups::AutoDevopsService, '#execute' do
+RSpec.describe Groups::AutoDevopsService, '#execute' do
let_it_be(:group) { create(:group) }
let_it_be(:user) { create(:user) }
let(:group_params) { { auto_devops_enabled: '0' } }
diff --git a/spec/services/groups/create_service_spec.rb b/spec/services/groups/create_service_spec.rb
index c0e876cce33..fc877f45a39 100644
--- a/spec/services/groups/create_service_spec.rb
+++ b/spec/services/groups/create_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Groups::CreateService, '#execute' do
+RSpec.describe Groups::CreateService, '#execute' do
let!(:user) { create(:user) }
let!(:group_params) { { path: "group_path", visibility_level: Gitlab::VisibilityLevel::PUBLIC } }
@@ -129,4 +129,13 @@ describe Groups::CreateService, '#execute' do
expect { subject }.to change { ChatTeam.count }.from(0).to(1)
end
end
+
+ describe 'creating a setting record' do
+ let(:service) { described_class.new(user, group_params) }
+
+ it 'create the settings record connected to the group' do
+ group = subject
+ expect(group.namespace_settings).to be_persisted
+ end
+ end
end
diff --git a/spec/services/groups/deploy_tokens/create_service_spec.rb b/spec/services/groups/deploy_tokens/create_service_spec.rb
index 20c609bc828..0c28075f998 100644
--- a/spec/services/groups/deploy_tokens/create_service_spec.rb
+++ b/spec/services/groups/deploy_tokens/create_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Groups::DeployTokens::CreateService do
+RSpec.describe Groups::DeployTokens::CreateService do
it_behaves_like 'a deploy token creation service' do
let(:entity) { create(:group) }
let(:deploy_token_class) { GroupDeployToken }
diff --git a/spec/services/groups/deploy_tokens/destroy_service_spec.rb b/spec/services/groups/deploy_tokens/destroy_service_spec.rb
index d4ef5963558..28e60b12993 100644
--- a/spec/services/groups/deploy_tokens/destroy_service_spec.rb
+++ b/spec/services/groups/deploy_tokens/destroy_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Groups::DeployTokens::DestroyService do
+RSpec.describe Groups::DeployTokens::DestroyService do
it_behaves_like 'a deploy token deletion service' do
let_it_be(:entity) { create(:group) }
let_it_be(:deploy_token_class) { GroupDeployToken }
diff --git a/spec/services/groups/destroy_service_spec.rb b/spec/services/groups/destroy_service_spec.rb
index bf639153b99..31afdba8192 100644
--- a/spec/services/groups/destroy_service_spec.rb
+++ b/spec/services/groups/destroy_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Groups::DestroyService do
+RSpec.describe Groups::DestroyService do
include DatabaseConnectionHelpers
let!(:user) { create(:user) }
diff --git a/spec/services/groups/group_links/create_service_spec.rb b/spec/services/groups/group_links/create_service_spec.rb
index 36faa69577e..bca03863d1e 100644
--- a/spec/services/groups/group_links/create_service_spec.rb
+++ b/spec/services/groups/group_links/create_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Groups::GroupLinks::CreateService, '#execute' do
+RSpec.describe Groups::GroupLinks::CreateService, '#execute' do
let(:parent_group_user) { create(:user) }
let(:group_user) { create(:user) }
let(:child_group_user) { create(:user) }
diff --git a/spec/services/groups/group_links/destroy_service_spec.rb b/spec/services/groups/group_links/destroy_service_spec.rb
index 8989f024262..22fe8a1d58b 100644
--- a/spec/services/groups/group_links/destroy_service_spec.rb
+++ b/spec/services/groups/group_links/destroy_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Groups::GroupLinks::DestroyService, '#execute' do
+RSpec.describe Groups::GroupLinks::DestroyService, '#execute' do
let(:user) { create(:user) }
let_it_be(:group) { create(:group, :private) }
diff --git a/spec/services/groups/group_links/update_service_spec.rb b/spec/services/groups/group_links/update_service_spec.rb
index 446364c9799..e4ff83d7926 100644
--- a/spec/services/groups/group_links/update_service_spec.rb
+++ b/spec/services/groups/group_links/update_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Groups::GroupLinks::UpdateService, '#execute' do
+RSpec.describe Groups::GroupLinks::UpdateService, '#execute' do
let(:user) { create(:user) }
let_it_be(:group) { create(:group, :private) }
diff --git a/spec/services/groups/import_export/export_service_spec.rb b/spec/services/groups/import_export/export_service_spec.rb
index ea49b26cc7c..690bcb94556 100644
--- a/spec/services/groups/import_export/export_service_spec.rb
+++ b/spec/services/groups/import_export/export_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Groups::ImportExport::ExportService do
+RSpec.describe Groups::ImportExport::ExportService do
describe '#async_execute' do
let(:user) { create(:user) }
let(:group) { create(:group) }
diff --git a/spec/services/groups/import_export/import_service_spec.rb b/spec/services/groups/import_export/import_service_spec.rb
index 1f7eaccbdbd..4aac602a6da 100644
--- a/spec/services/groups/import_export/import_service_spec.rb
+++ b/spec/services/groups/import_export/import_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Groups::ImportExport::ImportService do
+RSpec.describe Groups::ImportExport::ImportService do
describe '#async_execute' do
let_it_be(:user) { create(:user) }
let_it_be(:group) { create(:group) }
diff --git a/spec/services/groups/nested_create_service_spec.rb b/spec/services/groups/nested_create_service_spec.rb
index b30392c1b12..a43c1d8d9c3 100644
--- a/spec/services/groups/nested_create_service_spec.rb
+++ b/spec/services/groups/nested_create_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Groups::NestedCreateService do
+RSpec.describe Groups::NestedCreateService do
let(:user) { create(:user) }
subject(:service) { described_class.new(user, params) }
diff --git a/spec/services/groups/transfer_service_spec.rb b/spec/services/groups/transfer_service_spec.rb
index d7f6bececfe..fa254bba6a9 100644
--- a/spec/services/groups/transfer_service_spec.rb
+++ b/spec/services/groups/transfer_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Groups::TransferService do
+RSpec.describe Groups::TransferService do
let(:user) { create(:user) }
let(:new_parent_group) { create(:group, :public) }
let!(:group_member) { create(:group_member, :owner, group: group, user: user) }
diff --git a/spec/services/groups/update_service_spec.rb b/spec/services/groups/update_service_spec.rb
index b17d78505d1..25c79d9e600 100644
--- a/spec/services/groups/update_service_spec.rb
+++ b/spec/services/groups/update_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Groups::UpdateService do
+RSpec.describe Groups::UpdateService do
let!(:user) { create(:user) }
let!(:private_group) { create(:group, :private) }
let!(:internal_group) { create(:group, :internal) }
diff --git a/spec/services/groups/update_shared_runners_service_spec.rb b/spec/services/groups/update_shared_runners_service_spec.rb
new file mode 100644
index 00000000000..9fd8477a455
--- /dev/null
+++ b/spec/services/groups/update_shared_runners_service_spec.rb
@@ -0,0 +1,230 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Groups::UpdateSharedRunnersService do
+ let(:user) { create(:user) }
+ let(:group) { create(:group) }
+ let(:params) { {} }
+
+ describe '#execute' do
+ subject { described_class.new(group, user, params).execute }
+
+ context 'when current_user is not the group owner' do
+ let_it_be(:group) { create(:group) }
+
+ let(:params) { { shared_runners_enabled: '0' } }
+
+ before do
+ group.add_maintainer(user)
+ end
+
+ it 'results error and does not call any method' do
+ expect(group).not_to receive(:enable_shared_runners!)
+ expect(group).not_to receive(:disable_shared_runners!)
+ expect(group).not_to receive(:allow_descendants_override_disabled_shared_runners!)
+ expect(group).not_to receive(:disallow_descendants_override_disabled_shared_runners!)
+
+ expect(subject[:status]).to eq(:error)
+ expect(subject[:message]).to eq('Operation not allowed')
+ expect(subject[:http_status]).to eq(403)
+ end
+ end
+
+ context 'when current_user is the group owner' do
+ before do
+ group.add_owner(user)
+ end
+
+ context 'enable shared Runners' do
+ where(:desired_params) do
+ ['1', true]
+ end
+
+ with_them do
+ let(:params) { { shared_runners_enabled: desired_params } }
+
+ context 'group that its ancestors have shared runners disabled' do
+ let_it_be(:parent) { create(:group, :shared_runners_disabled) }
+ let_it_be(:group) { create(:group, :shared_runners_disabled, parent: parent) }
+
+ it 'results error' do
+ expect(subject[:status]).to eq(:error)
+ expect(subject[:message]).to eq('Shared Runners disabled for the parent group')
+ end
+ end
+
+ context 'root group with shared runners disabled' do
+ let_it_be(:group) { create(:group, :shared_runners_disabled) }
+
+ it 'receives correct method and succeeds' do
+ expect(group).to receive(:enable_shared_runners!)
+ expect(group).not_to receive(:disable_shared_runners!)
+ expect(group).not_to receive(:allow_descendants_override_disabled_shared_runners!)
+ expect(group).not_to receive(:disallow_descendants_override_disabled_shared_runners!)
+
+ expect(subject[:status]).to eq(:success)
+ end
+ end
+ end
+ end
+
+ context 'disable shared Runners' do
+ let_it_be(:group) { create(:group) }
+
+ where(:desired_params) do
+ ['0', false]
+ end
+
+ with_them do
+ let(:params) { { shared_runners_enabled: desired_params } }
+
+ it 'receives correct method and succeeds' do
+ expect(group).to receive(:disable_shared_runners!)
+ expect(group).not_to receive(:enable_shared_runners!)
+ expect(group).not_to receive(:allow_descendants_override_disabled_shared_runners!)
+ expect(group).not_to receive(:disallow_descendants_override_disabled_shared_runners!)
+
+ expect(subject[:status]).to eq(:success)
+ end
+ end
+ end
+
+ context 'allow descendants to override' do
+ where(:desired_params) do
+ ['1', true]
+ end
+
+ with_them do
+ let(:params) { { allow_descendants_override_disabled_shared_runners: desired_params } }
+
+ context 'top level group' do
+ let_it_be(:group) { create(:group, :shared_runners_disabled) }
+
+ it 'receives correct method and succeeds' do
+ expect(group).to receive(:allow_descendants_override_disabled_shared_runners!)
+ expect(group).not_to receive(:disallow_descendants_override_disabled_shared_runners!)
+ expect(group).not_to receive(:enable_shared_runners!)
+ expect(group).not_to receive(:disable_shared_runners!)
+
+ expect(subject[:status]).to eq(:success)
+ end
+ end
+
+ context 'when parent does not allow' do
+ let_it_be(:parent) { create(:group, :shared_runners_disabled, allow_descendants_override_disabled_shared_runners: false ) }
+ let_it_be(:group) { create(:group, :shared_runners_disabled, allow_descendants_override_disabled_shared_runners: false, parent: parent) }
+
+ it 'results error' do
+ expect(subject[:status]).to eq(:error)
+ expect(subject[:message]).to eq('Group level shared Runners not allowed')
+ end
+ end
+ end
+ end
+
+ context 'disallow descendants to override' do
+ where(:desired_params) do
+ ['0', false]
+ end
+
+ with_them do
+ let(:params) { { allow_descendants_override_disabled_shared_runners: desired_params } }
+
+ context 'top level group' do
+ let_it_be(:group) { create(:group, :shared_runners_disabled, :allow_descendants_override_disabled_shared_runners ) }
+
+ it 'receives correct method and succeeds' do
+ expect(group).to receive(:disallow_descendants_override_disabled_shared_runners!)
+ expect(group).not_to receive(:allow_descendants_override_disabled_shared_runners!)
+ expect(group).not_to receive(:enable_shared_runners!)
+ expect(group).not_to receive(:disable_shared_runners!)
+
+ expect(subject[:status]).to eq(:success)
+ end
+ end
+
+ context 'top level group that has shared Runners enabled' do
+ let_it_be(:group) { create(:group, shared_runners_enabled: true) }
+
+ it 'results error' do
+ expect(subject[:status]).to eq(:error)
+ expect(subject[:message]).to eq('Shared Runners enabled')
+ end
+ end
+ end
+ end
+
+ context 'both params are present' do
+ context 'shared_runners_enabled: 1 and allow_descendants_override_disabled_shared_runners' do
+ let_it_be(:group) { create(:group, :shared_runners_disabled) }
+ let_it_be(:sub_group) { create(:group, :shared_runners_disabled, parent: group) }
+ let_it_be(:project) { create(:project, shared_runners_enabled: false, group: sub_group) }
+
+ where(:allow_descendants_override) do
+ ['1', true, '0', false]
+ end
+
+ with_them do
+ let(:params) { { shared_runners_enabled: '1', allow_descendants_override_disabled_shared_runners: allow_descendants_override } }
+
+ it 'results in an error because shared Runners are enabled' do
+ expect { subject }
+ .to not_change { group.reload.shared_runners_enabled }
+ .and not_change { sub_group.reload.shared_runners_enabled }
+ .and not_change { project.reload.shared_runners_enabled }
+ .and not_change { group.reload.allow_descendants_override_disabled_shared_runners }
+ .and not_change { sub_group.reload.allow_descendants_override_disabled_shared_runners }
+ expect(subject[:status]).to eq(:error)
+ expect(subject[:message]).to eq('Cannot set shared_runners_enabled to true and allow_descendants_override_disabled_shared_runners')
+ end
+ end
+ end
+
+ context 'shared_runners_enabled: 0 and allow_descendants_override_disabled_shared_runners: 0' do
+ let_it_be(:group) { create(:group, :allow_descendants_override_disabled_shared_runners) }
+ let_it_be(:sub_group) { create(:group, :shared_runners_disabled, :allow_descendants_override_disabled_shared_runners, parent: group) }
+ let_it_be(:sub_group_2) { create(:group, parent: group) }
+ let_it_be(:project) { create(:project, group: group, shared_runners_enabled: true) }
+ let_it_be(:project_2) { create(:project, group: sub_group_2, shared_runners_enabled: true) }
+
+ let(:params) { { shared_runners_enabled: '0', allow_descendants_override_disabled_shared_runners: '0' } }
+
+ it 'disables shared Runners and disable allow_descendants_override_disabled_shared_runners' do
+ expect { subject }
+ .to change { group.reload.shared_runners_enabled }.from(true).to(false)
+ .and change { group.reload.allow_descendants_override_disabled_shared_runners }.from(true).to(false)
+ .and not_change { sub_group.reload.shared_runners_enabled }
+ .and change { sub_group.reload.allow_descendants_override_disabled_shared_runners }.from(true).to(false)
+ .and change { sub_group_2.reload.shared_runners_enabled }.from(true).to(false)
+ .and not_change { sub_group_2.reload.allow_descendants_override_disabled_shared_runners }
+ .and change { project.reload.shared_runners_enabled }.from(true).to(false)
+ .and change { project_2.reload.shared_runners_enabled }.from(true).to(false)
+ end
+ end
+
+ context 'shared_runners_enabled: 0 and allow_descendants_override_disabled_shared_runners: 1' do
+ let_it_be(:group) { create(:group) }
+ let_it_be(:sub_group) { create(:group, :shared_runners_disabled, parent: group) }
+ let_it_be(:sub_group_2) { create(:group, parent: group) }
+ let_it_be(:project) { create(:project, group: group, shared_runners_enabled: true) }
+ let_it_be(:project_2) { create(:project, group: sub_group_2, shared_runners_enabled: true) }
+
+ let(:params) { { shared_runners_enabled: '0', allow_descendants_override_disabled_shared_runners: '1' } }
+
+ it 'disables shared Runners and enable allow_descendants_override_disabled_shared_runners only for itself' do
+ expect { subject }
+ .to change { group.reload.shared_runners_enabled }.from(true).to(false)
+ .and change { group.reload.allow_descendants_override_disabled_shared_runners }.from(false).to(true)
+ .and not_change { sub_group.reload.shared_runners_enabled }
+ .and not_change { sub_group.reload.allow_descendants_override_disabled_shared_runners }
+ .and change { sub_group_2.reload.shared_runners_enabled }.from(true).to(false)
+ .and not_change { sub_group_2.reload.allow_descendants_override_disabled_shared_runners }
+ .and change { project.reload.shared_runners_enabled }.from(true).to(false)
+ .and change { project_2.reload.shared_runners_enabled }.from(true).to(false)
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/spec/services/import/bitbucket_server_service_spec.rb b/spec/services/import/bitbucket_server_service_spec.rb
new file mode 100644
index 00000000000..c548e87b040
--- /dev/null
+++ b/spec/services/import/bitbucket_server_service_spec.rb
@@ -0,0 +1,113 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Import::BitbucketServerService do
+ let_it_be(:user) { create(:user) }
+ let(:base_uri) { "https://test:7990" }
+ let(:token) { "asdasd12345" }
+ let(:secret) { "sekrettt" }
+ let(:project_key) { 'TES' }
+ let(:repo_slug) { 'vim' }
+ let(:repo) do
+ {
+ name: 'vim',
+ description: 'test',
+ visibility_level: Gitlab::VisibilityLevel::PUBLIC,
+ browse_url: 'http://repo.com/repo/repo',
+ clone_url: 'http://repo.com/repo/repo.git'
+ }
+ end
+
+ let(:client) { double(BitbucketServer::Client) }
+
+ let(:credentials) { { base_uri: base_uri, user: user, password: token } }
+ let(:params) { { bitbucket_server_url: base_uri, bitbucket_server_username: user, personal_access_token: token, bitbucket_server_project: project_key, bitbucket_server_repo: repo_slug } }
+
+ subject { described_class.new(client, user, params) }
+
+ before do
+ allow(subject).to receive(:authorized?).and_return(true)
+ end
+
+ context 'when no repo is found' do
+ before do
+ allow(subject).to receive(:authorized?).and_return(true)
+ allow(client).to receive(:repo).and_return(nil)
+ end
+
+ it 'returns an error' do
+ result = subject.execute(credentials)
+
+ expect(result).to include(
+ message: "Project #{project_key}/#{repo_slug} could not be found",
+ status: :error,
+ http_status: :unprocessable_entity
+ )
+ end
+ end
+
+ context 'when user is unauthorized' do
+ before do
+ allow(subject).to receive(:authorized?).and_return(false)
+ end
+
+ it 'returns an error' do
+ result = subject.execute(credentials)
+
+ expect(result).to include(
+ message: "You don't have permissions to create this project",
+ status: :error,
+ http_status: :unauthorized
+ )
+ end
+ end
+
+ context 'verify url' do
+ shared_examples 'denies local request' do
+ before do
+ allow(client).to receive(:repo).with(project_key, repo_slug).and_return(double(repo))
+ end
+
+ it 'does not allow requests' do
+ result = subject.execute(credentials)
+ expect(result[:status]).to eq(:error)
+ expect(result[:message]).to include("Invalid URL:")
+ end
+ end
+
+ context 'when host is localhost' do
+ before do
+ allow(subject).to receive(:url).and_return('https://localhost:3000')
+ end
+
+ include_examples 'denies local request'
+ end
+
+ context 'when host is on local network' do
+ before do
+ allow(subject).to receive(:url).and_return('https://192.168.0.191')
+ end
+
+ include_examples 'denies local request'
+ end
+
+ context 'when host is ftp protocol' do
+ before do
+ allow(subject).to receive(:url).and_return('ftp://testing')
+ end
+
+ include_examples 'denies local request'
+ end
+ end
+
+ it 'raises an exception for unknown error causes' do
+ exception = StandardError.new('Not Implemented')
+
+ allow(client).to receive(:repo).and_raise(exception)
+
+ expect(Gitlab::Import::Logger).not_to receive(:error)
+
+ expect { subject.execute(credentials) }.to raise_error(exception)
+ end
+end
diff --git a/spec/services/import/github_service_spec.rb b/spec/services/import/github_service_spec.rb
index 461b17e0e33..266ff309662 100644
--- a/spec/services/import/github_service_spec.rb
+++ b/spec/services/import/github_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Import::GithubService do
+RSpec.describe Import::GithubService do
let_it_be(:user) { create(:user) }
let_it_be(:token) { 'complex-token' }
let_it_be(:access_params) { { github_access_token: 'github-complex-token' } }
diff --git a/spec/services/import_export_clean_up_service_spec.rb b/spec/services/import_export_clean_up_service_spec.rb
index 9f811f56f50..4101b13adf9 100644
--- a/spec/services/import_export_clean_up_service_spec.rb
+++ b/spec/services/import_export_clean_up_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe ImportExportCleanUpService do
+RSpec.describe ImportExportCleanUpService do
describe '#execute' do
let(:service) { described_class.new }
diff --git a/spec/services/incident_management/create_incident_label_service_spec.rb b/spec/services/incident_management/create_incident_label_service_spec.rb
new file mode 100644
index 00000000000..2f11bcf397e
--- /dev/null
+++ b/spec/services/incident_management/create_incident_label_service_spec.rb
@@ -0,0 +1,58 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe IncidentManagement::CreateIncidentLabelService do
+ let_it_be(:project) { create(:project, :private) }
+ let_it_be(:user) { User.alert_bot }
+ let(:service) { described_class.new(project, user) }
+
+ subject(:execute) { service.execute }
+
+ describe 'execute' do
+ let(:title) { described_class::LABEL_PROPERTIES[:title] }
+ let(:color) { described_class::LABEL_PROPERTIES[:color] }
+ let(:description) { described_class::LABEL_PROPERTIES[:description] }
+
+ shared_examples 'existing label' do
+ it 'returns the existing label' do
+ expect { execute }.not_to change(Label, :count)
+
+ expect(execute).to be_success
+ expect(execute.payload).to eq(label: label)
+ end
+ end
+
+ shared_examples 'new label' do
+ it 'creates a new label' do
+ expect { execute }.to change(Label, :count).by(1)
+
+ label = project.reload.labels.last
+ expect(execute).to be_success
+ expect(execute.payload).to eq(label: label)
+ expect(label.title).to eq(title)
+ expect(label.color).to eq(color)
+ expect(label.description).to eq(description)
+ end
+ end
+
+ context 'with predefined project label' do
+ it_behaves_like 'existing label' do
+ let!(:label) { create(:label, project: project, title: title) }
+ end
+ end
+
+ context 'with predefined group label' do
+ let(:project) { create(:project, group: group) }
+ let(:group) { create(:group) }
+
+ it_behaves_like 'existing label' do
+ let!(:label) { create(:group_label, group: group, title: title) }
+ end
+ end
+
+ context 'without label' do
+ it_behaves_like 'new label'
+ end
+ end
+end
diff --git a/spec/services/incident_management/create_issue_service_spec.rb b/spec/services/incident_management/create_issue_service_spec.rb
index 5a3721f00b8..dab9a149458 100644
--- a/spec/services/incident_management/create_issue_service_spec.rb
+++ b/spec/services/incident_management/create_issue_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe IncidentManagement::CreateIssueService do
+RSpec.describe IncidentManagement::CreateIssueService do
let(:project) { create(:project, :repository, :private) }
let_it_be(:user) { User.alert_bot }
let(:service) { described_class.new(project, alert_payload) }
@@ -199,80 +199,7 @@ describe IncidentManagement::CreateIssueService do
end
describe "label `incident`" do
- let(:title) { 'incident' }
- let(:color) { '#CC0033' }
- let(:description) do
- <<~DESCRIPTION.chomp
- Denotes a disruption to IT services and \
- the associated issues require immediate attention
- DESCRIPTION
- end
-
- shared_examples 'existing label' do
- it 'adds the existing label' do
- expect { subject }.not_to change(Label, :count)
-
- expect(issue.labels).to eq([label])
- end
- end
-
- shared_examples 'new label' do
- it 'adds newly created label' do
- expect { subject }.to change(Label, :count).by(1)
-
- label = project.reload.labels.last
- expect(issue.labels).to eq([label])
- expect(label.title).to eq(title)
- expect(label.color).to eq(color)
- expect(label.description).to eq(description)
- end
- end
-
- context 'with predefined project label' do
- it_behaves_like 'existing label' do
- let!(:label) { create(:label, project: project, title: title) }
- end
- end
-
- context 'with predefined group label' do
- let(:project) { create(:project, group: group) }
- let(:group) { create(:group) }
-
- it_behaves_like 'existing label' do
- let!(:label) { create(:group_label, group: group, title: title) }
- end
- end
-
- context 'without label' do
- it_behaves_like 'new label'
- end
-
- context 'with duplicate labels', issue: 'https://gitlab.com/gitlab-org/gitlab-foss/issues/65042' do
- before do
- # Replicate race condition to create duplicates
- build(:label, project: project, title: title).save!(validate: false)
- build(:label, project: project, title: title).save!(validate: false)
- end
-
- it 'create an issue without labels' do
- # Verify we have duplicates
- expect(project.labels.size).to eq(2)
- expect(project.labels.map(&:title)).to all(eq(title))
-
- message = <<~MESSAGE.chomp
- Cannot create incident issue with labels ["#{title}"] for \
- "#{project.full_name}": Labels is invalid.
- Retrying without labels.
- MESSAGE
-
- expect(service)
- .to receive(:log_info)
- .with(message)
-
- expect(subject).to include(status: :success)
- expect(issue.labels).to be_empty
- end
- end
+ it_behaves_like 'create alert issue sets issue labels'
end
end
@@ -281,22 +208,12 @@ describe IncidentManagement::CreateIssueService do
setting.update!(create_issue: false)
end
- context 'when skip_settings_check is false (default)' do
- it 'returns an error' do
- expect(service)
- .to receive(:log_error)
- .with(error_message('setting disabled'))
+ it 'returns an error' do
+ expect(service)
+ .to receive(:log_error)
+ .with(error_message('setting disabled'))
- expect(subject).to eq(status: :error, message: 'setting disabled')
- end
- end
-
- context 'when skip_settings_check is true' do
- subject { service.execute(skip_settings_check: true) }
-
- it 'creates an issue' do
- expect { subject }.to change(Issue, :count).by(1)
- end
+ expect(subject).to eq(status: :error, message: 'setting disabled')
end
end
diff --git a/spec/services/incident_management/pager_duty/create_incident_issue_service_spec.rb b/spec/services/incident_management/pager_duty/create_incident_issue_service_spec.rb
new file mode 100644
index 00000000000..cf43ed2411d
--- /dev/null
+++ b/spec/services/incident_management/pager_duty/create_incident_issue_service_spec.rb
@@ -0,0 +1,104 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe IncidentManagement::PagerDuty::CreateIncidentIssueService do
+ let_it_be(:project, reload: true) { create(:project) }
+ let_it_be(:user) { User.alert_bot }
+ let(:webhook_payload) { Gitlab::Json.parse(fixture_file('pager_duty/webhook_incident_trigger.json')) }
+ let(:parsed_payload) { ::PagerDuty::WebhookPayloadParser.call(webhook_payload) }
+ let(:incident_payload) { parsed_payload.first['incident'] }
+
+ subject(:execute) { described_class.new(project, incident_payload).execute }
+
+ describe '#execute' do
+ context 'when pagerduty_webhook feature enabled' do
+ before do
+ stub_feature_flags(pagerduty_webhook: project)
+ end
+
+ context 'when PagerDuty webhook setting is active' do
+ let_it_be(:incident_management_setting) { create(:project_incident_management_setting, project: project, pagerduty_active: true) }
+
+ context 'when issue can be created' do
+ it 'creates a new issue' do
+ expect { execute }.to change(Issue, :count).by(1)
+ end
+
+ it 'responds with success' do
+ response = execute
+
+ expect(response).to be_success
+ expect(response.payload[:issue]).to be_kind_of(Issue)
+ end
+
+ it 'the issue author is Alert bot' do
+ expect(execute.payload[:issue].author).to eq(User.alert_bot)
+ end
+
+ it 'issue has a correct title' do
+ expect(execute.payload[:issue].title).to eq(incident_payload['title'])
+ end
+
+ it 'issue has a correct description' do
+ markdown_line_break = ' '
+
+ expect(execute.payload[:issue].description).to eq(
+ <<~MARKDOWN.chomp
+ **Incident:** [My new incident](https://webdemo.pagerduty.com/incidents/PRORDTY)#{markdown_line_break}
+ **Incident number:** 33#{markdown_line_break}
+ **Urgency:** high#{markdown_line_break}
+ **Status:** triggered#{markdown_line_break}
+ **Incident key:** #{markdown_line_break}
+ **Created at:** 26 September 2017, 3:14PM (UTC)#{markdown_line_break}
+ **Assignees:** [Laura Haley](https://webdemo.pagerduty.com/users/P553OPV)#{markdown_line_break}
+ **Impacted services:** [Production XDB Cluster](https://webdemo.pagerduty.com/services/PN49J75)
+ MARKDOWN
+ )
+ end
+ end
+
+ context 'when the payload does not contain a title' do
+ let(:incident_payload) { {} }
+
+ it 'does not create a GitLab issue' do
+ expect { execute }.not_to change(Issue, :count)
+ end
+
+ it 'responds with error' do
+ expect(execute).to be_error
+ expect(execute.message).to eq("Title can't be blank")
+ end
+ end
+ end
+
+ context 'when PagerDuty webhook setting is not active' do
+ let_it_be(:incident_management_setting) { create(:project_incident_management_setting, project: project, pagerduty_active: false) }
+
+ it 'does not create a GitLab issue' do
+ expect { execute }.not_to change(Issue, :count)
+ end
+
+ it 'responds with forbidden' do
+ expect(execute).to be_error
+ expect(execute.http_status).to eq(:forbidden)
+ end
+ end
+ end
+
+ context 'when pagerduty_webhook feature disabled' do
+ before do
+ stub_feature_flags(pagerduty_webhook: false)
+ end
+
+ it 'does not create a GitLab issue' do
+ expect { execute }.not_to change(Issue, :count)
+ end
+
+ it 'responds with forbidden' do
+ expect(execute).to be_error
+ expect(execute.http_status).to eq(:forbidden)
+ end
+ end
+ end
+end
diff --git a/spec/services/incident_management/pager_duty/process_webhook_service_spec.rb b/spec/services/incident_management/pager_duty/process_webhook_service_spec.rb
new file mode 100644
index 00000000000..11ce8388427
--- /dev/null
+++ b/spec/services/incident_management/pager_duty/process_webhook_service_spec.rb
@@ -0,0 +1,148 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe IncidentManagement::PagerDuty::ProcessWebhookService do
+ let_it_be(:project, reload: true) { create(:project) }
+
+ describe '#execute' do
+ shared_examples 'does not process incidents' do
+ it 'does not process incidents' do
+ expect(::IncidentManagement::PagerDuty::ProcessIncidentWorker).not_to receive(:perform_async)
+
+ execute
+ end
+ end
+
+ let(:webhook_payload) { Gitlab::Json.parse(fixture_file('pager_duty/webhook_incident_trigger.json')) }
+ let(:token) { nil }
+
+ subject(:execute) { described_class.new(project, nil, webhook_payload).execute(token) }
+
+ context 'when pagerduty_webhook feature is enabled' do
+ before do
+ stub_feature_flags(pagerduty_webhook: project)
+ end
+
+ context 'when PagerDuty webhook setting is active' do
+ let_it_be(:incident_management_setting) { create(:project_incident_management_setting, project: project, pagerduty_active: true) }
+
+ context 'when token is valid' do
+ let(:token) { incident_management_setting.pagerduty_token }
+
+ context 'when webhook payload has acceptable size' do
+ it 'responds with Accepted' do
+ result = execute
+
+ expect(result).to be_success
+ expect(result.http_status).to eq(:accepted)
+ end
+
+ it 'processes issues' do
+ incident_payload = ::PagerDuty::WebhookPayloadParser.call(webhook_payload).first['incident']
+
+ expect(::IncidentManagement::PagerDuty::ProcessIncidentWorker)
+ .to receive(:perform_async)
+ .with(project.id, incident_payload)
+ .once
+
+ execute
+ end
+ end
+
+ context 'when webhook payload is too big' do
+ let(:deep_size) { instance_double(Gitlab::Utils::DeepSize, valid?: false) }
+
+ before do
+ allow(Gitlab::Utils::DeepSize)
+ .to receive(:new)
+ .with(webhook_payload, max_size: described_class::PAGER_DUTY_PAYLOAD_SIZE_LIMIT)
+ .and_return(deep_size)
+ end
+
+ it 'responds with Bad Request' do
+ result = execute
+
+ expect(result).to be_error
+ expect(result.http_status).to eq(:bad_request)
+ end
+
+ it_behaves_like 'does not process incidents'
+ end
+
+ context 'when webhook payload is blank' do
+ let(:webhook_payload) { nil }
+
+ it 'responds with Accepted' do
+ result = execute
+
+ expect(result).to be_success
+ expect(result.http_status).to eq(:accepted)
+ end
+
+ it_behaves_like 'does not process incidents'
+ end
+ end
+
+ context 'when token is invalid' do
+ let(:token) { 'invalid-token' }
+
+ it 'responds with Unauthorized' do
+ result = execute
+
+ expect(result).to be_error
+ expect(result.http_status).to eq(:unauthorized)
+ end
+
+ it_behaves_like 'does not process incidents'
+ end
+ end
+
+ context 'when both tokens are nil' do
+ let_it_be(:incident_management_setting) { create(:project_incident_management_setting, project: project, pagerduty_active: false) }
+ let(:token) { nil }
+
+ before do
+ incident_management_setting.update_column(:pagerduty_active, true)
+ end
+
+ it 'responds with Unauthorized' do
+ result = execute
+
+ expect(result).to be_error
+ expect(result.http_status).to eq(:unauthorized)
+ end
+
+ it_behaves_like 'does not process incidents'
+ end
+
+ context 'when PagerDuty webhook setting is not active' do
+ let_it_be(:incident_management_setting) { create(:project_incident_management_setting, project: project, pagerduty_active: false) }
+
+ it 'responds with Forbidden' do
+ result = execute
+
+ expect(result).to be_error
+ expect(result.http_status).to eq(:forbidden)
+ end
+
+ it_behaves_like 'does not process incidents'
+ end
+ end
+
+ context 'when pagerduty_webhook feature is disabled' do
+ before do
+ stub_feature_flags(pagerduty_webhook: false)
+ end
+
+ it 'responds with Forbidden' do
+ result = execute
+
+ expect(result).to be_error
+ expect(result.http_status).to eq(:forbidden)
+ end
+
+ it_behaves_like 'does not process incidents'
+ end
+ end
+end
diff --git a/spec/services/integrations/test/project_service_spec.rb b/spec/services/integrations/test/project_service_spec.rb
index fdb43ca345a..dd603765d59 100644
--- a/spec/services/integrations/test/project_service_spec.rb
+++ b/spec/services/integrations/test/project_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Integrations::Test::ProjectService do
+RSpec.describe Integrations::Test::ProjectService do
let(:user) { double('user') }
describe '#execute' do
diff --git a/spec/services/issuable/bulk_update_service_spec.rb b/spec/services/issuable/bulk_update_service_spec.rb
index c791c454d70..168a80a97c0 100644
--- a/spec/services/issuable/bulk_update_service_spec.rb
+++ b/spec/services/issuable/bulk_update_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Issuable::BulkUpdateService do
+RSpec.describe Issuable::BulkUpdateService do
let(:user) { create(:user) }
let(:project) { create(:project, :repository, namespace: user.namespace) }
@@ -18,8 +18,8 @@ describe Issuable::BulkUpdateService do
it 'succeeds' do
result = bulk_update(issuables, milestone_id: milestone.id)
- expect(result[:success]).to be_truthy
- expect(result[:count]).to eq(issuables.count)
+ expect(result.success?).to be_truthy
+ expect(result.payload[:count]).to eq(issuables.count)
end
it 'updates the issuables milestone' do
@@ -121,8 +121,8 @@ describe Issuable::BulkUpdateService do
it 'succeeds and returns the correct number of issues updated' do
result = bulk_update(issues, state_event: 'close')
- expect(result[:success]).to be_truthy
- expect(result[:count]).to eq(issues.count)
+ expect(result.success?).to be_truthy
+ expect(result.payload[:count]).to eq(issues.count)
end
it 'closes all the issues passed' do
@@ -139,8 +139,8 @@ describe Issuable::BulkUpdateService do
it 'succeeds and returns the correct number of issues updated' do
result = bulk_update(issues, state_event: 'reopen')
- expect(result[:success]).to be_truthy
- expect(result[:count]).to eq(issues.count)
+ expect(result.success?).to be_truthy
+ expect(result.payload[:count]).to eq(issues.count)
end
it 'reopens all the issues passed' do
@@ -161,8 +161,8 @@ describe Issuable::BulkUpdateService do
result = bulk_update(merge_request, assignee_ids: [user.id, new_assignee.id])
- expect(result[:success]).to be_truthy
- expect(result[:count]).to eq(1)
+ expect(result.success?).to be_truthy
+ expect(result.payload[:count]).to eq(1)
end
it 'updates the assignee to the user ID passed' do
@@ -199,8 +199,8 @@ describe Issuable::BulkUpdateService do
result = bulk_update(issue, assignee_ids: [new_assignee.id])
- expect(result[:success]).to be_truthy
- expect(result[:count]).to eq(1)
+ expect(result.success?).to be_truthy
+ expect(result.payload[:count]).to eq(1)
end
it 'updates the assignee to the user ID passed' do
@@ -273,8 +273,8 @@ describe Issuable::BulkUpdateService do
issue2 = create(:issue, project: create(:project))
result = bulk_update([issue1, issue2], assignee_ids: [user.id])
- expect(result[:success]).to be_truthy
- expect(result[:count]).to eq(1)
+ expect(result.success?).to be_truthy
+ expect(result.payload[:count]).to eq(1)
expect(issue1.reload.assignees).to eq([user])
expect(issue2.reload.assignees).to be_empty
@@ -332,8 +332,8 @@ describe Issuable::BulkUpdateService do
milestone = create(:milestone, group: group)
result = bulk_update([issue1, issue2, issue3], milestone_id: milestone.id)
- expect(result[:success]).to be_truthy
- expect(result[:count]).to eq(2)
+ expect(result.success?).to be_truthy
+ expect(result.payload[:count]).to eq(2)
expect(issue1.reload.milestone).to eq(milestone)
expect(issue2.reload.milestone).to be_nil
diff --git a/spec/services/issuable/clone/attributes_rewriter_spec.rb b/spec/services/issuable/clone/attributes_rewriter_spec.rb
index fb520f828fa..372e6d480e3 100644
--- a/spec/services/issuable/clone/attributes_rewriter_spec.rb
+++ b/spec/services/issuable/clone/attributes_rewriter_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Issuable::Clone::AttributesRewriter do
+RSpec.describe Issuable::Clone::AttributesRewriter do
let(:user) { create(:user) }
let(:group) { create(:group) }
let(:project1) { create(:project, :public, group: group) }
diff --git a/spec/services/issuable/clone/content_rewriter_spec.rb b/spec/services/issuable/clone/content_rewriter_spec.rb
index 3479c20862a..f39439b7c2f 100644
--- a/spec/services/issuable/clone/content_rewriter_spec.rb
+++ b/spec/services/issuable/clone/content_rewriter_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Issuable::Clone::ContentRewriter do
+RSpec.describe Issuable::Clone::ContentRewriter do
let(:user) { create(:user) }
let(:group) { create(:group) }
let(:project1) { create(:project, :public, group: group) }
diff --git a/spec/services/issuable/common_system_notes_service_spec.rb b/spec/services/issuable/common_system_notes_service_spec.rb
index 771e7ca42c9..daf4f68208e 100644
--- a/spec/services/issuable/common_system_notes_service_spec.rb
+++ b/spec/services/issuable/common_system_notes_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Issuable::CommonSystemNotesService do
+RSpec.describe Issuable::CommonSystemNotesService do
let_it_be(:project) { create(:project) }
let_it_be(:user) { create(:user) }
@@ -43,23 +43,23 @@ describe Issuable::CommonSystemNotesService do
it_behaves_like 'system note creation', {}, 'changed milestone'
end
- context 'with merge requests WIP note' do
- context 'adding WIP note' do
+ context 'with merge requests Draft note' do
+ context 'adding Draft note' do
let(:issuable) { create(:merge_request, title: "merge request") }
- it_behaves_like 'system note creation', { title: "WIP merge request" }, 'marked as a **Work In Progress**'
+ it_behaves_like 'system note creation', { title: "Draft: merge request" }, 'marked as a **Work In Progress**'
context 'and changing title' do
before do
- issuable.update_attribute(:title, "WIP changed title")
+ issuable.update_attribute(:title, "Draft: changed title")
end
- it_behaves_like 'WIP notes creation', 'marked'
+ it_behaves_like 'draft notes creation', 'marked'
end
end
- context 'removing WIP note' do
- let(:issuable) { create(:merge_request, title: "WIP merge request") }
+ context 'removing Draft note' do
+ let(:issuable) { create(:merge_request, title: "Draft: merge request") }
it_behaves_like 'system note creation', { title: "merge request" }, 'unmarked as a **Work In Progress**'
@@ -68,7 +68,7 @@ describe Issuable::CommonSystemNotesService do
issuable.update_attribute(:title, "changed title")
end
- it_behaves_like 'WIP notes creation', 'unmarked'
+ it_behaves_like 'draft notes creation', 'unmarked'
end
end
end
diff --git a/spec/services/issuable/destroy_service_spec.rb b/spec/services/issuable/destroy_service_spec.rb
index dd6a966c145..8d62932f986 100644
--- a/spec/services/issuable/destroy_service_spec.rb
+++ b/spec/services/issuable/destroy_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Issuable::DestroyService do
+RSpec.describe Issuable::DestroyService do
let(:user) { create(:user) }
let(:project) { create(:project, :public) }
diff --git a/spec/services/issues/build_service_spec.rb b/spec/services/issues/build_service_spec.rb
index 140b78f9b7a..68b226b02da 100644
--- a/spec/services/issues/build_service_spec.rb
+++ b/spec/services/issues/build_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper.rb'
-describe Issues::BuildService do
+RSpec.describe Issues::BuildService do
let(:project) { create(:project, :repository) }
let(:user) { create(:user) }
diff --git a/spec/services/issues/close_service_spec.rb b/spec/services/issues/close_service_spec.rb
index 78eba565de4..6678d831775 100644
--- a/spec/services/issues/close_service_spec.rb
+++ b/spec/services/issues/close_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Issues::CloseService do
+RSpec.describe Issues::CloseService do
let(:project) { create(:project, :repository) }
let(:user) { create(:user, email: "user@example.com") }
let(:user2) { create(:user, email: "user2@example.com") }
diff --git a/spec/services/issues/create_service_spec.rb b/spec/services/issues/create_service_spec.rb
index bb02941576a..fdf2326b75e 100644
--- a/spec/services/issues/create_service_spec.rb
+++ b/spec/services/issues/create_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Issues::CreateService do
+RSpec.describe Issues::CreateService do
let(:project) { create(:project) }
let(:user) { create(:user) }
@@ -284,7 +284,9 @@ describe Issues::CreateService do
end
end
- it_behaves_like 'new issuable record that supports quick actions'
+ it_behaves_like 'issuable record that supports quick actions' do
+ let(:issuable) { described_class.new(project, user, params).execute }
+ end
context 'Quick actions' do
context 'with assignee and milestone in params and command' do
diff --git a/spec/services/issues/duplicate_service_spec.rb b/spec/services/issues/duplicate_service_spec.rb
index 41a151b0ca1..78e030e6ac7 100644
--- a/spec/services/issues/duplicate_service_spec.rb
+++ b/spec/services/issues/duplicate_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Issues::DuplicateService do
+RSpec.describe Issues::DuplicateService do
let(:user) { create(:user) }
let(:canonical_project) { create(:project) }
let(:duplicate_project) { create(:project) }
diff --git a/spec/services/issues/export_csv_service_spec.rb b/spec/services/issues/export_csv_service_spec.rb
index 419e29d92a8..76381fe525b 100644
--- a/spec/services/issues/export_csv_service_spec.rb
+++ b/spec/services/issues/export_csv_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Issues::ExportCsvService do
+RSpec.describe Issues::ExportCsvService do
let_it_be(:user) { create(:user) }
let(:group) { create(:group) }
let(:project) { create(:project, :public, group: group) }
diff --git a/spec/services/issues/import_csv_service_spec.rb b/spec/services/issues/import_csv_service_spec.rb
index 92b88489af9..cc3e1d23a74 100644
--- a/spec/services/issues/import_csv_service_spec.rb
+++ b/spec/services/issues/import_csv_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Issues::ImportCsvService do
+RSpec.describe Issues::ImportCsvService do
let(:project) { create(:project) }
let(:user) { create(:user) }
diff --git a/spec/services/issues/move_service_spec.rb b/spec/services/issues/move_service_spec.rb
index a449541f459..8929907a179 100644
--- a/spec/services/issues/move_service_spec.rb
+++ b/spec/services/issues/move_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Issues::MoveService do
+RSpec.describe Issues::MoveService do
let(:user) { create(:user) }
let(:author) { create(:user) }
let(:title) { 'Some issue' }
@@ -210,4 +210,49 @@ describe Issues::MoveService do
end
end
end
+
+ context 'updating sent notifications' do
+ let!(:old_issue_notification_1) { create(:sent_notification, project: old_issue.project, noteable: old_issue) }
+ let!(:old_issue_notification_2) { create(:sent_notification, project: old_issue.project, noteable: old_issue) }
+ let!(:other_issue_notification) { create(:sent_notification, project: old_issue.project) }
+
+ include_context 'user can move issue'
+
+ context 'when issue is from service desk' do
+ before do
+ allow(old_issue).to receive(:from_service_desk?).and_return(true)
+ end
+
+ it 'updates moved issue sent notifications' do
+ new_issue = move_service.execute(old_issue, new_project)
+
+ old_issue_notification_1.reload
+ old_issue_notification_2.reload
+ expect(old_issue_notification_1.project_id).to eq(new_issue.project_id)
+ expect(old_issue_notification_1.noteable_id).to eq(new_issue.id)
+ expect(old_issue_notification_2.project_id).to eq(new_issue.project_id)
+ expect(old_issue_notification_2.noteable_id).to eq(new_issue.id)
+ end
+
+ it 'does not update other issues sent notifications' do
+ expect do
+ move_service.execute(old_issue, new_project)
+ other_issue_notification.reload
+ end.not_to change { other_issue_notification.noteable_id }
+ end
+ end
+
+ context 'when issue is not from service desk' do
+ it 'does not update sent notifications' do
+ move_service.execute(old_issue, new_project)
+
+ old_issue_notification_1.reload
+ old_issue_notification_2.reload
+ expect(old_issue_notification_1.project_id).to eq(old_issue.project_id)
+ expect(old_issue_notification_1.noteable_id).to eq(old_issue.id)
+ expect(old_issue_notification_2.project_id).to eq(old_issue.project_id)
+ expect(old_issue_notification_2.noteable_id).to eq(old_issue.id)
+ end
+ end
+ end
end
diff --git a/spec/services/issues/referenced_merge_requests_service_spec.rb b/spec/services/issues/referenced_merge_requests_service_spec.rb
index 2c5af11d2e6..bf7a4c97e48 100644
--- a/spec/services/issues/referenced_merge_requests_service_spec.rb
+++ b/spec/services/issues/referenced_merge_requests_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper.rb'
-describe Issues::ReferencedMergeRequestsService do
+RSpec.describe Issues::ReferencedMergeRequestsService do
def create_referencing_mr(attributes = {})
create(:merge_request, attributes).tap do |merge_request|
create(:note, :system, project: project, noteable: issue, author: user, note: merge_request.to_reference(full: true))
diff --git a/spec/services/issues/related_branches_service_spec.rb b/spec/services/issues/related_branches_service_spec.rb
index 9f72e499414..d79132d98db 100644
--- a/spec/services/issues/related_branches_service_spec.rb
+++ b/spec/services/issues/related_branches_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Issues::RelatedBranchesService do
+RSpec.describe Issues::RelatedBranchesService do
let_it_be(:developer) { create(:user) }
let_it_be(:issue) { create(:issue) }
let(:user) { developer }
diff --git a/spec/services/issues/reopen_service_spec.rb b/spec/services/issues/reopen_service_spec.rb
index ca878ee947a..f7416203259 100644
--- a/spec/services/issues/reopen_service_spec.rb
+++ b/spec/services/issues/reopen_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Issues::ReopenService do
+RSpec.describe Issues::ReopenService do
let(:project) { create(:project) }
let(:issue) { create(:issue, :closed, project: project) }
diff --git a/spec/services/issues/reorder_service_spec.rb b/spec/services/issues/reorder_service_spec.rb
index 6d72d698b1d..b6ad488a48c 100644
--- a/spec/services/issues/reorder_service_spec.rb
+++ b/spec/services/issues/reorder_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Issues::ReorderService do
+RSpec.describe Issues::ReorderService do
let_it_be(:user) { create(:user) }
let_it_be(:project) { create(:project) }
let_it_be(:group) { create(:group) }
diff --git a/spec/services/issues/resolve_discussions_spec.rb b/spec/services/issues/resolve_discussions_spec.rb
index ec6624db6fc..a541d92feb2 100644
--- a/spec/services/issues/resolve_discussions_spec.rb
+++ b/spec/services/issues/resolve_discussions_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper.rb'
-describe Issues::ResolveDiscussions do
+RSpec.describe Issues::ResolveDiscussions do
let(:project) { create(:project, :repository) }
let(:user) { create(:user) }
diff --git a/spec/services/issues/update_service_spec.rb b/spec/services/issues/update_service_spec.rb
index 33ae2682d01..77bd540e22f 100644
--- a/spec/services/issues/update_service_spec.rb
+++ b/spec/services/issues/update_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Issues::UpdateService, :mailer do
+RSpec.describe Issues::UpdateService, :mailer do
let_it_be(:user) { create(:user) }
let_it_be(:user2) { create(:user) }
let_it_be(:user3) { create(:user) }
@@ -866,5 +866,10 @@ describe Issues::UpdateService, :mailer do
end
end
end
+
+ it_behaves_like 'issuable record that supports quick actions' do
+ let(:existing_issue) { create(:issue, project: project) }
+ let(:issuable) { described_class.new(project, user, params).execute(existing_issue) }
+ end
end
end
diff --git a/spec/services/issues/zoom_link_service_spec.rb b/spec/services/issues/zoom_link_service_spec.rb
index 3fb1eae361a..56aec4fe564 100644
--- a/spec/services/issues/zoom_link_service_spec.rb
+++ b/spec/services/issues/zoom_link_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Issues::ZoomLinkService do
+RSpec.describe Issues::ZoomLinkService do
let_it_be(:user) { create(:user) }
let_it_be(:issue) { create(:issue) }
diff --git a/spec/services/jira/requests/projects_spec.rb b/spec/services/jira/requests/projects/list_service_spec.rb
index f7b9aa7c00c..51e67dd821d 100644
--- a/spec/services/jira/requests/projects_spec.rb
+++ b/spec/services/jira/requests/projects/list_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Jira::Requests::Projects do
+RSpec.describe Jira::Requests::Projects::ListService do
let(:jira_service) { create(:jira_service) }
let(:params) { {} }
@@ -32,14 +32,6 @@ describe Jira::Requests::Projects do
end
context 'with jira_service' do
- context 'when limit is invalid' do
- let(:params) { { limit: 0 } }
-
- it 'returns a paylod with no projects returned' do
- expect(subject.payload[:projects]).to be_empty
- end
- end
-
context 'when validations and params are ok' do
let(:client) { double(options: { site: 'https://jira.example.com' }) }
@@ -60,7 +52,7 @@ describe Jira::Requests::Projects do
context 'when the request does not return any values' do
before do
- expect(client).to receive(:get).and_return({ 'someKey' => 'value' })
+ expect(client).to receive(:get).and_return([])
end
it 'returns a paylod with no projects returned' do
@@ -74,19 +66,15 @@ describe Jira::Requests::Projects do
context 'when the request returns values' do
before do
- expect(client).to receive(:get).and_return(
- { 'values' => %w(project1 project2), 'isLast' => false }
- )
- expect(JIRA::Resource::Project).to receive(:build).with(client, 'project1').and_return('jira_project1')
- expect(JIRA::Resource::Project).to receive(:build).with(client, 'project2').and_return('jira_project2')
+ expect(client).to receive(:get).and_return([{ "key" => 'project1' }, { "key" => 'project2' }])
end
it 'returns a paylod with jira projets' do
payload = subject.payload
expect(subject.success?).to be_truthy
- expect(payload[:projects]).to eq(%w(jira_project1 jira_project2))
- expect(payload[:is_last]).to be_falsey
+ expect(payload[:projects].map(&:key)).to eq(%w(project1 project2))
+ expect(payload[:is_last]).to be_truthy
end
end
end
diff --git a/spec/services/jira_import/start_import_service_spec.rb b/spec/services/jira_import/start_import_service_spec.rb
index 9dc8cdb1475..a10928355ef 100644
--- a/spec/services/jira_import/start_import_service_spec.rb
+++ b/spec/services/jira_import/start_import_service_spec.rb
@@ -2,14 +2,21 @@
require 'spec_helper'
-describe JiraImport::StartImportService do
+RSpec.describe JiraImport::StartImportService do
include JiraServiceHelper
let_it_be(:user) { create(:user) }
let_it_be(:project, reload: true) { create(:project) }
let(:key) { 'KEY' }
+ let(:mapping) do
+ [
+ { jira_account_id: 'abc', gitlab_id: 12 },
+ { jira_account_id: 'def', gitlab_id: nil },
+ { jira_account_id: nil, gitlab_id: 1 }
+ ]
+ end
- subject { described_class.new(user, project, key).execute }
+ subject { described_class.new(user, project, key, mapping).execute }
context 'when an error is returned from the project validation' do
before do
@@ -37,7 +44,7 @@ describe JiraImport::StartImportService do
context 'when correct data provided' do
let(:fake_key) { 'some-key' }
- subject { described_class.new(user, project, fake_key).execute }
+ subject { described_class.new(user, project, fake_key, mapping).execute }
context 'when import is already running' do
let_it_be(:jira_import_state) { create(:jira_import_state, :started, project: project) }
@@ -62,35 +69,68 @@ describe JiraImport::StartImportService do
end
context 'when everything is ok' do
- it 'returns success response' do
- expect(subject).to be_a(ServiceResponse)
- expect(subject).to be_success
- end
+ context 'with complete mapping' do
+ before do
+ expect(Gitlab::JiraImport).to receive(:cache_users_mapping).with(project.id, { 'abc' => 12 })
+ end
- it 'schedules Jira import' do
- subject
+ it 'returns success response' do
+ expect(subject).to be_a(ServiceResponse)
+ expect(subject).to be_success
+ end
- expect(project.latest_jira_import).to be_scheduled
- end
+ it 'schedules Jira import' do
+ subject
- it 'creates Jira import data', :aggregate_failures do
- jira_import = subject.payload[:import_data]
+ expect(project.latest_jira_import).to be_scheduled
+ end
+
+ it 'creates Jira import data', :aggregate_failures do
+ jira_import = subject.payload[:import_data]
+
+ expect(jira_import.jira_project_xid).to eq(0)
+ expect(jira_import.jira_project_name).to eq(fake_key)
+ expect(jira_import.jira_project_key).to eq(fake_key)
+ expect(jira_import.user).to eq(user)
+ end
+
+ it 'creates Jira import label' do
+ expect { subject }.to change { Label.count }.by(1)
+ end
+
+ it 'creates Jira label title with correct number' do
+ jira_import = subject.payload[:import_data]
+ label_title = "jira-import::#{jira_import.jira_project_key}-1"
- expect(jira_import.jira_project_xid).to eq(0)
- expect(jira_import.jira_project_name).to eq(fake_key)
- expect(jira_import.jira_project_key).to eq(fake_key)
- expect(jira_import.user).to eq(user)
+ expect(jira_import.label.title).to eq(label_title)
+ end
end
- it 'creates Jira import label' do
- expect { subject }.to change { Label.count }.by(1)
+ context 'when mapping is nil' do
+ let(:mapping) { nil }
+
+ it 'returns success response' do
+ expect(Gitlab::JiraImport).not_to receive(:cache_users_mapping)
+
+ expect(subject).to be_a(ServiceResponse)
+ expect(subject).to be_success
+ end
end
- it 'creates Jira label title with correct number' do
- jira_import = subject.payload[:import_data]
- label_title = "jira-import::#{jira_import.jira_project_key}-1"
+ context 'when no mapping value is complete' do
+ let(:mapping) do
+ [
+ { jira_account_id: 'def', gitlab_id: nil },
+ { jira_account_id: nil, gitlab_id: 1 }
+ ]
+ end
- expect(jira_import.label.title).to eq(label_title)
+ it 'returns success response' do
+ expect(Gitlab::JiraImport).not_to receive(:cache_users_mapping)
+
+ expect(subject).to be_a(ServiceResponse)
+ expect(subject).to be_success
+ end
end
end
diff --git a/spec/services/jira_import/users_importer_spec.rb b/spec/services/jira_import/users_importer_spec.rb
index 28ce5f1b44b..64cdc70f612 100644
--- a/spec/services/jira_import/users_importer_spec.rb
+++ b/spec/services/jira_import/users_importer_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe JiraImport::UsersImporter do
+RSpec.describe JiraImport::UsersImporter do
include JiraServiceHelper
let_it_be(:user) { create(:user) }
diff --git a/spec/services/jira_import/users_mapper_spec.rb b/spec/services/jira_import/users_mapper_spec.rb
index 75dbc41aa2e..e5e8279a6fb 100644
--- a/spec/services/jira_import/users_mapper_spec.rb
+++ b/spec/services/jira_import/users_mapper_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe JiraImport::UsersMapper do
+RSpec.describe JiraImport::UsersMapper do
let_it_be(:project) { create(:project) }
subject { described_class.new(project, jira_users).execute }
@@ -29,9 +29,9 @@ describe JiraImport::UsersMapper do
# mapping is tracked in https://gitlab.com/gitlab-org/gitlab/-/issues/219023
let(:mapped_users) do
[
- { jira_account_id: 'abcd', jira_display_name: 'user1', jira_email: nil, gitlab_id: nil },
- { jira_account_id: 'efg', jira_display_name: nil, jira_email: nil, gitlab_id: nil },
- { jira_account_id: 'hij', jira_display_name: 'user3', jira_email: 'user3@example.com', gitlab_id: nil }
+ { jira_account_id: 'abcd', jira_display_name: 'user1', jira_email: nil, gitlab_id: nil, gitlab_username: nil, gitlab_name: nil },
+ { jira_account_id: 'efg', jira_display_name: nil, jira_email: nil, gitlab_id: nil, gitlab_username: nil, gitlab_name: nil },
+ { jira_account_id: 'hij', jira_display_name: 'user3', jira_email: 'user3@example.com', gitlab_id: nil, gitlab_username: nil, gitlab_name: nil }
]
end
diff --git a/spec/services/keys/create_service_spec.rb b/spec/services/keys/create_service_spec.rb
index 1f8b402cf08..1dbe383ad8e 100644
--- a/spec/services/keys/create_service_spec.rb
+++ b/spec/services/keys/create_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Keys::CreateService do
+RSpec.describe Keys::CreateService do
let(:user) { create(:user) }
let(:params) { attributes_for(:key) }
diff --git a/spec/services/keys/destroy_service_spec.rb b/spec/services/keys/destroy_service_spec.rb
index ca4bbd50c03..59ce4a941c7 100644
--- a/spec/services/keys/destroy_service_spec.rb
+++ b/spec/services/keys/destroy_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Keys::DestroyService do
+RSpec.describe Keys::DestroyService do
let(:user) { create(:user) }
subject { described_class.new(user) }
diff --git a/spec/services/keys/last_used_service_spec.rb b/spec/services/keys/last_used_service_spec.rb
index c675df39f4d..82b6b05975b 100644
--- a/spec/services/keys/last_used_service_spec.rb
+++ b/spec/services/keys/last_used_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Keys::LastUsedService do
+RSpec.describe Keys::LastUsedService do
describe '#execute', :clean_gitlab_redis_shared_state do
it 'updates the key when it has not been used recently' do
key = create(:key, last_used_at: 1.year.ago)
diff --git a/spec/services/labels/available_labels_service_spec.rb b/spec/services/labels/available_labels_service_spec.rb
index 56826257d6f..9912f2cf469 100644
--- a/spec/services/labels/available_labels_service_spec.rb
+++ b/spec/services/labels/available_labels_service_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
require 'spec_helper'
-describe Labels::AvailableLabelsService do
+RSpec.describe Labels::AvailableLabelsService do
let(:user) { create(:user) }
let(:project) { create(:project, :public, group: group) }
let(:group) { create(:group) }
diff --git a/spec/services/labels/create_service_spec.rb b/spec/services/labels/create_service_spec.rb
index f057c4401e7..7a31a5a7cae 100644
--- a/spec/services/labels/create_service_spec.rb
+++ b/spec/services/labels/create_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Labels::CreateService do
+RSpec.describe Labels::CreateService do
describe '#execute' do
let(:project) { create(:project) }
let(:group) { create(:group) }
diff --git a/spec/services/labels/find_or_create_service_spec.rb b/spec/services/labels/find_or_create_service_spec.rb
index 438d895392b..aa9eb0e6a0d 100644
--- a/spec/services/labels/find_or_create_service_spec.rb
+++ b/spec/services/labels/find_or_create_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Labels::FindOrCreateService do
+RSpec.describe Labels::FindOrCreateService do
describe '#execute' do
let(:group) { create(:group) }
let(:project) { create(:project, namespace: group) }
diff --git a/spec/services/labels/promote_service_spec.rb b/spec/services/labels/promote_service_spec.rb
index d86281b751c..7674ec36331 100644
--- a/spec/services/labels/promote_service_spec.rb
+++ b/spec/services/labels/promote_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Labels::PromoteService do
+RSpec.describe Labels::PromoteService do
describe '#execute' do
let!(:user) { create(:user) }
diff --git a/spec/services/labels/transfer_service_spec.rb b/spec/services/labels/transfer_service_spec.rb
index a2a9c8dddf2..2c0c82ed976 100644
--- a/spec/services/labels/transfer_service_spec.rb
+++ b/spec/services/labels/transfer_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Labels::TransferService do
+RSpec.describe Labels::TransferService do
describe '#execute' do
let_it_be(:user) { create(:admin) }
diff --git a/spec/services/labels/update_service_spec.rb b/spec/services/labels/update_service_spec.rb
index 045e8af1135..af2403656af 100644
--- a/spec/services/labels/update_service_spec.rb
+++ b/spec/services/labels/update_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Labels::UpdateService do
+RSpec.describe Labels::UpdateService do
describe '#execute' do
let(:project) { create(:project) }
diff --git a/spec/services/lfs/file_transformer_spec.rb b/spec/services/lfs/file_transformer_spec.rb
index 13d9c369c42..e87c80b4c6c 100644
--- a/spec/services/lfs/file_transformer_spec.rb
+++ b/spec/services/lfs/file_transformer_spec.rb
@@ -2,7 +2,7 @@
require "spec_helper"
-describe Lfs::FileTransformer do
+RSpec.describe Lfs::FileTransformer do
let(:project) { create(:project, :repository, :wiki_repo) }
let(:repository) { project.repository }
let(:file_content) { 'Test file content' }
diff --git a/spec/services/lfs/lock_file_service_spec.rb b/spec/services/lfs/lock_file_service_spec.rb
index 2bd62b96083..b3a121866c8 100644
--- a/spec/services/lfs/lock_file_service_spec.rb
+++ b/spec/services/lfs/lock_file_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Lfs::LockFileService do
+RSpec.describe Lfs::LockFileService do
let(:project) { create(:project) }
let(:current_user) { create(:user) }
diff --git a/spec/services/lfs/locks_finder_service_spec.rb b/spec/services/lfs/locks_finder_service_spec.rb
index fdc60e2c03f..1167212eb69 100644
--- a/spec/services/lfs/locks_finder_service_spec.rb
+++ b/spec/services/lfs/locks_finder_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Lfs::LocksFinderService do
+RSpec.describe Lfs::LocksFinderService do
let(:project) { create(:project) }
let(:user) { create(:user) }
let(:params) { {} }
diff --git a/spec/services/lfs/unlock_file_service_spec.rb b/spec/services/lfs/unlock_file_service_spec.rb
index 1334b074e84..7ab269f897a 100644
--- a/spec/services/lfs/unlock_file_service_spec.rb
+++ b/spec/services/lfs/unlock_file_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Lfs::UnlockFileService do
+RSpec.describe Lfs::UnlockFileService do
let(:project) { create(:project) }
let(:current_user) { create(:user) }
let(:lock_author) { create(:user) }
diff --git a/spec/services/members/approve_access_request_service_spec.rb b/spec/services/members/approve_access_request_service_spec.rb
index 5bbceac3dd0..e6a94fdaf84 100644
--- a/spec/services/members/approve_access_request_service_spec.rb
+++ b/spec/services/members/approve_access_request_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Members::ApproveAccessRequestService do
+RSpec.describe Members::ApproveAccessRequestService do
let(:project) { create(:project, :public) }
let(:group) { create(:group, :public) }
let(:current_user) { create(:user) }
diff --git a/spec/services/members/create_service_spec.rb b/spec/services/members/create_service_spec.rb
index 674fe0f666e..00b5ff59e48 100644
--- a/spec/services/members/create_service_spec.rb
+++ b/spec/services/members/create_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Members::CreateService do
+RSpec.describe Members::CreateService do
let(:project) { create(:project) }
let(:user) { create(:user) }
let(:project_user) { create(:user) }
diff --git a/spec/services/members/destroy_service_spec.rb b/spec/services/members/destroy_service_spec.rb
index 73ac0bd7716..13e7b4c1006 100644
--- a/spec/services/members/destroy_service_spec.rb
+++ b/spec/services/members/destroy_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Members::DestroyService do
+RSpec.describe Members::DestroyService do
let(:current_user) { create(:user) }
let(:member_user) { create(:user) }
let(:group) { create(:group, :public) }
@@ -25,6 +25,7 @@ describe Members::DestroyService do
before do
type = member.is_a?(GroupMember) ? 'Group' : 'Project'
expect(TodosDestroyer::EntityLeaveWorker).to receive(:perform_in).with(Todo::WAIT_FOR_DELETE, member.user_id, member.source_id, type)
+ expect(MembersDestroyer::UnassignIssuablesWorker).to receive(:perform_async).with(member.user_id, member.source_id, type) if opts[:unassign_issuables]
end
it 'destroys the member' do
@@ -56,12 +57,23 @@ describe Members::DestroyService do
expect(member_user.todos_pending_count).to be(1)
expect(member_user.todos_done_count).to be(1)
- described_class.new(current_user).execute(member, opts)
+ service = described_class.new(current_user)
+
+ if opts[:unassign_issuables]
+ expect(service).to receive(:enqueue_unassign_issuables).with(member)
+ end
+
+ service.execute(member, opts)
expect(member_user.assigned_open_merge_requests_count).to be(0)
expect(member_user.assigned_open_issues_count).to be(0)
expect(member_user.todos_pending_count).to be(0)
expect(member_user.todos_done_count).to be(0)
+
+ unless opts[:unassign_issuables]
+ expect(member_user.assigned_merge_requests.opened.count).to be(1)
+ expect(member_user.assigned_issues.opened.count).to be(1)
+ end
end
end
@@ -100,7 +112,7 @@ describe Members::DestroyService do
it_behaves_like 'a service raising Gitlab::Access::AccessDeniedError'
it_behaves_like 'a service destroying a member with access' do
- let(:opts) { { skip_authorization: true } }
+ let(:opts) { { skip_authorization: true, unassign_issuables: true } }
end
end
@@ -114,7 +126,7 @@ describe Members::DestroyService do
it_behaves_like 'a service raising Gitlab::Access::AccessDeniedError'
it_behaves_like 'a service destroying a member with access' do
- let(:opts) { { skip_authorization: true } }
+ let(:opts) { { skip_authorization: true, unassign_issuables: true } }
end
end
end
@@ -133,6 +145,31 @@ describe Members::DestroyService do
end
it_behaves_like 'a service destroying a member with access'
+
+ context 'unassign issuables' do
+ it_behaves_like 'a service destroying a member with access' do
+ let(:opts) { { unassign_issuables: true } }
+ end
+ end
+ end
+
+ context 'with a project bot member' do
+ let(:member) { group_project.members.find_by(user_id: member_user.id) }
+ let(:member_user) { create(:user, :project_bot) }
+
+ before do
+ group_project.add_maintainer(member_user)
+ end
+
+ context 'when the destroy_bot flag is true' do
+ it_behaves_like 'a service destroying a member with access' do
+ let(:opts) { { destroy_bot: true } }
+ end
+ end
+
+ context 'when the destroy_bot flag is not specified' do
+ it_behaves_like 'a service raising Gitlab::Access::AccessDeniedError'
+ end
end
context 'with a group member' do
@@ -143,6 +180,12 @@ describe Members::DestroyService do
end
it_behaves_like 'a service destroying a member with access'
+
+ context 'unassign issuables' do
+ it_behaves_like 'a service destroying a member with access' do
+ let(:opts) { { unassign_issuables: true } }
+ end
+ end
end
end
end
diff --git a/spec/services/members/request_access_service_spec.rb b/spec/services/members/request_access_service_spec.rb
index a0f7ae91bdb..69eea2aea4b 100644
--- a/spec/services/members/request_access_service_spec.rb
+++ b/spec/services/members/request_access_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Members::RequestAccessService do
+RSpec.describe Members::RequestAccessService do
let(:user) { create(:user) }
shared_examples 'a service raising Gitlab::Access::AccessDeniedError' do
diff --git a/spec/services/members/unassign_issuables_service_spec.rb b/spec/services/members/unassign_issuables_service_spec.rb
new file mode 100644
index 00000000000..3f7ccb7bab3
--- /dev/null
+++ b/spec/services/members/unassign_issuables_service_spec.rb
@@ -0,0 +1,66 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Members::UnassignIssuablesService do
+ let_it_be(:group) { create(:group, :private) }
+ let_it_be(:project) { create(:project, group: group) }
+ let_it_be(:user, reload: true) { create(:user) }
+ let_it_be(:assigned_issue1, reload: true) { create(:issue, project: project, assignees: [user]) }
+ let_it_be(:assigned_issue2, reload: true) { create(:issue, project: project, assignees: [user]) }
+
+ let!(:assigned_merge_request1) { create(:merge_request, :simple, :closed, target_project: project, source_project: project, assignees: [user], title: 'Test1') }
+ let!(:assigned_merge_request2) { create(:merge_request, :simple, :opened, target_project: project, source_project: project, assignees: [user], title: 'Test2') }
+
+ describe '#execute' do
+ RSpec.shared_examples 'un-assigning issuables' do |issue_count, mr_count, open_issue_count, open_mr_count|
+ it 'removes issuable assignments', :aggregate_failures do
+ expect(user.assigned_issues.count).to eq(issue_count)
+ expect(user.assigned_merge_requests.count).to eq(mr_count)
+
+ subject
+
+ expect(user.assigned_issues.count).to eq(0)
+ expect(user.assigned_merge_requests.count).to eq(0)
+ end
+
+ it 'invalidates user cache', :aggregate_failures, :clean_gitlab_redis_cache do
+ expect(user.assigned_open_merge_requests_count).to eq(open_mr_count)
+ expect(user.assigned_open_issues_count).to eq(open_issue_count)
+
+ subject
+
+ expect(user.assigned_open_merge_requests_count).to eq(0)
+ expect(user.assigned_open_issues_count).to eq(0)
+ end
+ end
+
+ context 'when a user leaves a project' do
+ before do
+ project.add_maintainer(user)
+ end
+
+ subject { described_class.new(user, project).execute }
+
+ it_behaves_like 'un-assigning issuables', 2, 2, 2, 1
+ end
+
+ context 'when a user leaves a group' do
+ let_it_be(:project2) { create(:project, group: group) }
+
+ let_it_be(:assigned_issue3, reload: true) { create(:issue, project: project2, assignees: [user]) }
+ let_it_be(:assigned_issue4, reload: true) { create(:issue, project: project2, assignees: [user]) }
+
+ let!(:assigned_merge_request3) { create(:merge_request, :simple, :closed, target_project: project2, source_project: project2, assignees: [user], title: 'Test1') }
+ let!(:assigned_merge_request4) { create(:merge_request, :simple, :opened, target_project: project2, source_project: project2, assignees: [user], title: 'Test2') }
+
+ before do
+ group.add_maintainer(user)
+ end
+
+ subject { described_class.new(user, group).execute }
+
+ it_behaves_like 'un-assigning issuables', 4, 4, 4, 2
+ end
+ end
+end
diff --git a/spec/services/members/update_service_spec.rb b/spec/services/members/update_service_spec.rb
index a8b28127df2..f510916558b 100644
--- a/spec/services/members/update_service_spec.rb
+++ b/spec/services/members/update_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Members::UpdateService do
+RSpec.describe Members::UpdateService do
let(:project) { create(:project, :public) }
let(:group) { create(:group, :public) }
let(:current_user) { create(:user) }
diff --git a/spec/services/merge_requests/add_context_service_spec.rb b/spec/services/merge_requests/add_context_service_spec.rb
index d4e95c2f1ea..58ed91218d1 100644
--- a/spec/services/merge_requests/add_context_service_spec.rb
+++ b/spec/services/merge_requests/add_context_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe MergeRequests::AddContextService do
+RSpec.describe MergeRequests::AddContextService do
let(:project) { create(:project, :repository) }
let(:admin) { create(:admin) }
let(:merge_request) { create(:merge_request, source_project: project, target_project: project, author: admin) }
diff --git a/spec/services/merge_requests/add_todo_when_build_fails_service_spec.rb b/spec/services/merge_requests/add_todo_when_build_fails_service_spec.rb
index 0cec1e7be22..3c81ad6722d 100644
--- a/spec/services/merge_requests/add_todo_when_build_fails_service_spec.rb
+++ b/spec/services/merge_requests/add_todo_when_build_fails_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe MergeRequests::AddTodoWhenBuildFailsService do
+RSpec.describe MergeRequests::AddTodoWhenBuildFailsService do
let(:user) { create(:user) }
let(:project) { create(:project, :repository) }
let(:sha) { '1234567890abcdef1234567890abcdef12345678' }
diff --git a/spec/services/merge_requests/after_create_service_spec.rb b/spec/services/merge_requests/after_create_service_spec.rb
index 4aefe5f7dae..840b7bc0a1c 100644
--- a/spec/services/merge_requests/after_create_service_spec.rb
+++ b/spec/services/merge_requests/after_create_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe MergeRequests::AfterCreateService do
+RSpec.describe MergeRequests::AfterCreateService do
let_it_be(:merge_request) { create(:merge_request) }
subject(:after_create_service) do
diff --git a/spec/services/merge_requests/approval_service_spec.rb b/spec/services/merge_requests/approval_service_spec.rb
new file mode 100644
index 00000000000..124501f17d5
--- /dev/null
+++ b/spec/services/merge_requests/approval_service_spec.rb
@@ -0,0 +1,74 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe MergeRequests::ApprovalService do
+ describe '#execute' do
+ let(:user) { create(:user) }
+ let(:merge_request) { create(:merge_request) }
+ let(:project) { merge_request.project }
+ let!(:todo) { create(:todo, user: user, project: project, target: merge_request) }
+
+ subject(:service) { described_class.new(project, user) }
+
+ before do
+ project.add_developer(user)
+ end
+
+ context 'with invalid approval' do
+ before do
+ allow(merge_request.approvals).to receive(:new).and_return(double(save: false))
+ end
+
+ it 'does not create an approval note' do
+ expect(SystemNoteService).not_to receive(:approve_mr)
+
+ service.execute(merge_request)
+ end
+
+ it 'does not mark pending todos as done' do
+ service.execute(merge_request)
+
+ expect(todo.reload).to be_pending
+ end
+ end
+
+ context 'with valid approval' do
+ it 'creates an approval note and marks pending todos as done' do
+ expect(SystemNoteService).to receive(:approve_mr).with(merge_request, user)
+ expect(merge_request.approvals).to receive(:reset)
+
+ service.execute(merge_request)
+
+ expect(todo.reload).to be_done
+ end
+
+ it 'creates approve MR event' do
+ expect_next_instance_of(EventCreateService) do |instance|
+ expect(instance).to receive(:approve_mr)
+ .with(merge_request, user)
+ end
+
+ service.execute(merge_request)
+ end
+
+ context 'with remaining approvals' do
+ it 'fires an approval webhook' do
+ expect(service).to receive(:execute_hooks).with(merge_request, 'approved')
+
+ service.execute(merge_request)
+ end
+ end
+ end
+
+ context 'user cannot update the merge request' do
+ before do
+ project.add_guest(user)
+ end
+
+ it 'does not update approvals' do
+ expect { service.execute(merge_request) }.not_to change { merge_request.approvals.size }
+ end
+ end
+ end
+end
diff --git a/spec/services/merge_requests/assign_issues_service_spec.rb b/spec/services/merge_requests/assign_issues_service_spec.rb
index c0b57b9092d..6398e8c533e 100644
--- a/spec/services/merge_requests/assign_issues_service_spec.rb
+++ b/spec/services/merge_requests/assign_issues_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe MergeRequests::AssignIssuesService do
+RSpec.describe MergeRequests::AssignIssuesService do
let(:user) { create(:user) }
let(:project) { create(:project, :public, :repository) }
let(:issue) { create(:issue, project: project) }
diff --git a/spec/services/merge_requests/build_service_spec.rb b/spec/services/merge_requests/build_service_spec.rb
index 9b358839c06..f99be26927d 100644
--- a/spec/services/merge_requests/build_service_spec.rb
+++ b/spec/services/merge_requests/build_service_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
require 'spec_helper'
-describe MergeRequests::BuildService do
+RSpec.describe MergeRequests::BuildService do
using RSpec::Parameterized::TableSyntax
include RepoHelpers
include ProjectForksHelper
@@ -189,8 +189,8 @@ describe MergeRequests::BuildService do
it_behaves_like 'allows the merge request to be created'
- it 'adds a WIP prefix to the merge request title' do
- expect(merge_request.title).to eq('WIP: Feature branch')
+ it 'adds a Draft prefix to the merge request title' do
+ expect(merge_request.title).to eq('Draft: Feature branch')
end
end
diff --git a/spec/services/merge_requests/close_service_spec.rb b/spec/services/merge_requests/close_service_spec.rb
index 0e51de48fb1..e518e439a84 100644
--- a/spec/services/merge_requests/close_service_spec.rb
+++ b/spec/services/merge_requests/close_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe MergeRequests::CloseService do
+RSpec.describe MergeRequests::CloseService do
let(:user) { create(:user) }
let(:user2) { create(:user) }
let(:guest) { create(:user) }
diff --git a/spec/services/merge_requests/conflicts/list_service_spec.rb b/spec/services/merge_requests/conflicts/list_service_spec.rb
index 13d69307084..14133731e37 100644
--- a/spec/services/merge_requests/conflicts/list_service_spec.rb
+++ b/spec/services/merge_requests/conflicts/list_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe MergeRequests::Conflicts::ListService do
+RSpec.describe MergeRequests::Conflicts::ListService do
describe '#can_be_resolved_in_ui?' do
def create_merge_request(source_branch, target_branch = 'conflict-start')
create(:merge_request, source_branch: source_branch, target_branch: target_branch, merge_status: :unchecked) do |mr|
@@ -30,6 +30,7 @@ describe MergeRequests::Conflicts::ListService do
it 'returns a falsey value when one of the MR branches is missing' do
merge_request = create_merge_request('conflict-resolvable')
merge_request.project.repository.rm_branch(merge_request.author, 'conflict-resolvable')
+ merge_request.clear_memoized_source_branch_exists
expect(conflicts_service(merge_request).can_be_resolved_in_ui?).to be_falsey
end
diff --git a/spec/services/merge_requests/conflicts/resolve_service_spec.rb b/spec/services/merge_requests/conflicts/resolve_service_spec.rb
index 74f20094081..c4d50124ca9 100644
--- a/spec/services/merge_requests/conflicts/resolve_service_spec.rb
+++ b/spec/services/merge_requests/conflicts/resolve_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe MergeRequests::Conflicts::ResolveService do
+RSpec.describe MergeRequests::Conflicts::ResolveService do
include ProjectForksHelper
let(:user) { create(:user) }
let(:project) { create(:project, :public, :repository) }
diff --git a/spec/services/merge_requests/create_from_issue_service_spec.rb b/spec/services/merge_requests/create_from_issue_service_spec.rb
index fb1bb308170..fa70ad8c559 100644
--- a/spec/services/merge_requests/create_from_issue_service_spec.rb
+++ b/spec/services/merge_requests/create_from_issue_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe MergeRequests::CreateFromIssueService do
+RSpec.describe MergeRequests::CreateFromIssueService do
include ProjectForksHelper
let(:project) { create(:project, :repository) }
@@ -163,10 +163,10 @@ describe MergeRequests::CreateFromIssueService do
expect(result[:merge_request].milestone_id).to eq(milestone_id)
end
- it 'sets the merge request title to: "WIP: Resolves "$issue-title"' do
+ it 'sets the merge request title to: "Draft: Resolves "$issue-title"' do
result = service.execute
- expect(result[:merge_request].title).to eq("WIP: Resolve \"#{issue.title}\"")
+ expect(result[:merge_request].title).to eq("Draft: Resolve \"#{issue.title}\"")
end
end
@@ -193,10 +193,10 @@ describe MergeRequests::CreateFromIssueService do
it_behaves_like 'a service that creates a merge request from an issue'
- it 'sets the merge request title to: "WIP: $issue-branch-name', :sidekiq_might_not_need_inline do
+ it 'sets the merge request title to: "Draft: $issue-branch-name', :sidekiq_might_not_need_inline do
result = service.execute
- expect(result[:merge_request].title).to eq("WIP: #{issue.to_branch_name.titleize.humanize}")
+ expect(result[:merge_request].title).to eq("Draft: #{issue.to_branch_name.titleize.humanize}")
end
end
end
diff --git a/spec/services/merge_requests/create_pipeline_service_spec.rb b/spec/services/merge_requests/create_pipeline_service_spec.rb
index 9eb28759061..db46bd37eea 100644
--- a/spec/services/merge_requests/create_pipeline_service_spec.rb
+++ b/spec/services/merge_requests/create_pipeline_service_spec.rb
@@ -2,10 +2,13 @@
require 'spec_helper'
-describe MergeRequests::CreatePipelineService do
+RSpec.describe MergeRequests::CreatePipelineService do
+ include ProjectForksHelper
+
let_it_be(:project) { create(:project, :repository) }
let_it_be(:user) { create(:user) }
- let(:service) { described_class.new(project, user, params) }
+ let(:service) { described_class.new(project, actor, params) }
+ let(:actor) { user }
let(:params) { {} }
before do
@@ -26,11 +29,13 @@ describe MergeRequests::CreatePipelineService do
let(:merge_request) do
create(:merge_request,
source_branch: 'feature',
- source_project: project,
+ source_project: source_project,
target_branch: 'master',
target_project: project)
end
+ let(:source_project) { project }
+
it 'creates a detached merge request pipeline' do
expect { subject }.to change { Ci::Pipeline.count }.by(1)
@@ -42,6 +47,50 @@ describe MergeRequests::CreatePipelineService do
expect(subject.source).to eq('merge_request_event')
end
+ context 'with fork merge request' do
+ let_it_be(:forked_project) { fork_project(project, nil, repository: true, target_project: create(:project, :private, :repository)) }
+ let(:source_project) { forked_project }
+
+ context 'when actor has permission to create pipelines in target project' do
+ let(:actor) { user }
+
+ it 'creates a pipeline in the target project' do
+ expect(subject.project).to eq(project)
+ end
+
+ context 'when ci_allow_to_create_merge_request_pipelines_in_target_project feature flag is disabled' do
+ before do
+ stub_feature_flags(ci_allow_to_create_merge_request_pipelines_in_target_project: false)
+ end
+
+ it 'creates a pipeline in the source project' do
+ expect(subject.project).to eq(source_project)
+ end
+ end
+ end
+
+ context 'when actor has permission to create pipelines in forked project' do
+ let(:actor) { fork_user }
+ let(:fork_user) { create(:user) }
+
+ before do
+ source_project.add_developer(fork_user)
+ end
+
+ it 'creates a pipeline in the source project' do
+ expect(subject.project).to eq(source_project)
+ end
+ end
+
+ context 'when actor does not have permission to create pipelines' do
+ let(:actor) { create(:user) }
+
+ it 'returns nothing' do
+ expect(subject.full_error_messages).to include('Insufficient permissions to create a new pipeline')
+ end
+ end
+ end
+
context 'when service is called multiple times' do
it 'creates a pipeline once' do
expect do
diff --git a/spec/services/merge_requests/create_service_spec.rb b/spec/services/merge_requests/create_service_spec.rb
index bb40c399b6e..a8661f027e8 100644
--- a/spec/services/merge_requests/create_service_spec.rb
+++ b/spec/services/merge_requests/create_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe MergeRequests::CreateService, :clean_gitlab_redis_shared_state do
+RSpec.describe MergeRequests::CreateService, :clean_gitlab_redis_shared_state do
include ProjectForksHelper
let(:project) { create(:project, :repository) }
@@ -216,11 +216,12 @@ describe MergeRequests::CreateService, :clean_gitlab_redis_shared_state do
target_project.add_maintainer(user)
end
- it 'create legacy detached merge request pipeline for fork merge request' do
+ it 'create detached merge request pipeline for fork merge request' do
merge_request.reload
- expect(merge_request.actual_head_pipeline)
- .to be_legacy_detached_merge_request_pipeline
+ head_pipeline = merge_request.actual_head_pipeline
+ expect(head_pipeline).to be_detached_merge_request_pipeline
+ expect(head_pipeline.project).to eq(target_project)
end
end
@@ -339,13 +340,14 @@ describe MergeRequests::CreateService, :clean_gitlab_redis_shared_state do
end
end
- it_behaves_like 'new issuable record that supports quick actions' do
+ it_behaves_like 'issuable record that supports quick actions' do
let(:default_params) do
{
source_branch: 'feature',
target_branch: 'master'
}
end
+ let(:issuable) { described_class.new(project, user, params).execute }
end
context 'Quick actions' do
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 2adf808619d..377615bbc6f 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
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe MergeRequests::DeleteNonLatestDiffsService, :clean_gitlab_redis_shared_state do
+RSpec.describe MergeRequests::DeleteNonLatestDiffsService, :clean_gitlab_redis_shared_state do
let(:merge_request) { create(:merge_request) }
let!(:subject) { described_class.new(merge_request) }
diff --git a/spec/services/merge_requests/ff_merge_service_spec.rb b/spec/services/merge_requests/ff_merge_service_spec.rb
index 415b351e13a..c3da02273a4 100644
--- a/spec/services/merge_requests/ff_merge_service_spec.rb
+++ b/spec/services/merge_requests/ff_merge_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe MergeRequests::FfMergeService do
+RSpec.describe MergeRequests::FfMergeService do
let(:user) { create(:user) }
let(:user2) { create(:user) }
let(:merge_request) do
diff --git a/spec/services/merge_requests/get_urls_service_spec.rb b/spec/services/merge_requests/get_urls_service_spec.rb
index 8cc627b64d9..053752626dc 100644
--- a/spec/services/merge_requests/get_urls_service_spec.rb
+++ b/spec/services/merge_requests/get_urls_service_spec.rb
@@ -2,7 +2,7 @@
require "spec_helper"
-describe MergeRequests::GetUrlsService do
+RSpec.describe MergeRequests::GetUrlsService do
include ProjectForksHelper
let(:project) { create(:project, :public, :repository) }
diff --git a/spec/services/merge_requests/link_lfs_objects_service_spec.rb b/spec/services/merge_requests/link_lfs_objects_service_spec.rb
index f07cf13e4f2..c1765e3a2ab 100644
--- a/spec/services/merge_requests/link_lfs_objects_service_spec.rb
+++ b/spec/services/merge_requests/link_lfs_objects_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe MergeRequests::LinkLfsObjectsService, :sidekiq_inline do
+RSpec.describe MergeRequests::LinkLfsObjectsService, :sidekiq_inline do
include ProjectForksHelper
include RepoHelpers
diff --git a/spec/services/merge_requests/merge_orchestration_service_spec.rb b/spec/services/merge_requests/merge_orchestration_service_spec.rb
index c50f20d7703..67dbb5a1a01 100644
--- a/spec/services/merge_requests/merge_orchestration_service_spec.rb
+++ b/spec/services/merge_requests/merge_orchestration_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe MergeRequests::MergeOrchestrationService do
+RSpec.describe MergeRequests::MergeOrchestrationService do
let_it_be(:maintainer) { create(:user) }
let(:merge_params) { { sha: merge_request.diff_head_sha } }
let(:user) { maintainer }
diff --git a/spec/services/merge_requests/merge_service_spec.rb b/spec/services/merge_requests/merge_service_spec.rb
index 2274d917527..11e341994f7 100644
--- a/spec/services/merge_requests/merge_service_spec.rb
+++ b/spec/services/merge_requests/merge_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe MergeRequests::MergeService do
+RSpec.describe MergeRequests::MergeService do
let_it_be(:user) { create(:user) }
let_it_be(:user2) { create(:user) }
let(:merge_request) { create(:merge_request, :simple, author: user2, assignees: [user2]) }
@@ -360,6 +360,25 @@ describe MergeRequests::MergeService do
expect(Gitlab::AppLogger).to have_received(:error).with(a_string_matching(error_message))
end
+ context 'when squashing is required' do
+ before do
+ merge_request.update!(source_branch: 'master', target_branch: 'feature')
+ merge_request.target_project.project_setting.squash_always!
+ end
+
+ it 'raises an error if squashing is not done' do
+ error_message = 'requires squashing commits'
+
+ service.execute(merge_request)
+
+ expect(merge_request).to be_open
+
+ expect(merge_request.merge_commit_sha).to be_nil
+ expect(merge_request.merge_error).to include(error_message)
+ expect(Gitlab::AppLogger).to have_received(:error).with(a_string_matching(error_message))
+ end
+ end
+
context 'when squashing' do
before do
merge_request.update!(source_branch: 'master', target_branch: 'feature')
diff --git a/spec/services/merge_requests/merge_to_ref_service_spec.rb b/spec/services/merge_requests/merge_to_ref_service_spec.rb
index 596d46f3c43..b482e8d6724 100644
--- a/spec/services/merge_requests/merge_to_ref_service_spec.rb
+++ b/spec/services/merge_requests/merge_to_ref_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe MergeRequests::MergeToRefService do
+RSpec.describe MergeRequests::MergeToRefService do
shared_examples_for 'MergeService for target ref' do
it 'target_ref has the same state of target branch' do
repo = merge_request.target_project.repository
diff --git a/spec/services/merge_requests/mergeability_check_service_spec.rb b/spec/services/merge_requests/mergeability_check_service_spec.rb
index 45519ddf3d3..543da46f883 100644
--- a/spec/services/merge_requests/mergeability_check_service_spec.rb
+++ b/spec/services/merge_requests/mergeability_check_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe MergeRequests::MergeabilityCheckService, :clean_gitlab_redis_shared_state do
+RSpec.describe MergeRequests::MergeabilityCheckService, :clean_gitlab_redis_shared_state do
shared_examples_for 'unmergeable merge request' do
it 'updates or keeps merge status as cannot_be_merged' do
subject
diff --git a/spec/services/merge_requests/migrate_external_diffs_service_spec.rb b/spec/services/merge_requests/migrate_external_diffs_service_spec.rb
index 233b944624f..6ea8626ba73 100644
--- a/spec/services/merge_requests/migrate_external_diffs_service_spec.rb
+++ b/spec/services/merge_requests/migrate_external_diffs_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe MergeRequests::MigrateExternalDiffsService do
+RSpec.describe MergeRequests::MigrateExternalDiffsService do
let(:merge_request) { create(:merge_request) }
let(:diff) { merge_request.merge_request_diff }
diff --git a/spec/services/merge_requests/post_merge_service_spec.rb b/spec/services/merge_requests/post_merge_service_spec.rb
index fff6ddf3928..a51a896ca96 100644
--- a/spec/services/merge_requests/post_merge_service_spec.rb
+++ b/spec/services/merge_requests/post_merge_service_spec.rb
@@ -2,11 +2,13 @@
require 'spec_helper'
-describe MergeRequests::PostMergeService do
+RSpec.describe MergeRequests::PostMergeService do
let(:user) { create(:user) }
let(:merge_request) { create(:merge_request, assignees: [user]) }
let(:project) { merge_request.project }
+ subject { described_class.new(project, user).execute(merge_request) }
+
before do
project.add_maintainer(user)
end
@@ -19,10 +21,7 @@ describe MergeRequests::PostMergeService do
project.open_merge_requests_count
merge_request.update!(state: 'merged')
- service = described_class.new(project, user, {})
-
- expect { service.execute(merge_request) }
- .to change { project.open_merge_requests_count }.from(1).to(0)
+ expect { subject }.to change { project.open_merge_requests_count }.from(1).to(0)
end
it 'updates metrics' do
@@ -35,7 +34,7 @@ describe MergeRequests::PostMergeService do
expect(metrics_service).to receive(:merge)
- described_class.new(project, user, {}).execute(merge_request)
+ subject
end
it 'deletes non-latest diffs' do
@@ -45,7 +44,7 @@ describe MergeRequests::PostMergeService do
.to receive(:new).with(merge_request)
.and_return(diff_removal_service)
- described_class.new(project, user, {}).execute(merge_request)
+ subject
expect(diff_removal_service).to have_received(:execute)
end
@@ -56,21 +55,63 @@ describe MergeRequests::PostMergeService do
issue = create(:issue, project: project)
allow(merge_request).to receive(:visible_closing_issues_for).and_return([issue])
- expect_next_instance_of(Issues::CloseService) do |service|
- allow(service).to receive(:execute).with(issue, commit: merge_request).and_raise(RuntimeError)
+ expect_next_instance_of(Issues::CloseService) do |close_service|
+ allow(close_service).to receive(:execute).with(issue, commit: merge_request).and_raise(RuntimeError)
end
- expect { described_class.new(project, user).execute(merge_request) }.to raise_error(RuntimeError)
+ expect { subject }.to raise_error(RuntimeError)
expect(merge_request.reload).to be_merged
end
it 'clean up environments for the merge request' do
- expect_next_instance_of(Ci::StopEnvironmentsService) do |service|
- expect(service).to receive(:execute_for_merge_request).with(merge_request)
+ expect_next_instance_of(Ci::StopEnvironmentsService) do |stop_environment_service|
+ expect(stop_environment_service).to receive(:execute_for_merge_request).with(merge_request)
end
- described_class.new(project, user).execute(merge_request)
+ subject
+ end
+
+ context 'when the merge request has review apps' do
+ it 'cancels all review app deployments' do
+ pipeline = create(:ci_pipeline,
+ source: :merge_request_event,
+ merge_request: merge_request,
+ project: project,
+ sha: merge_request.diff_head_sha,
+ merge_requests_as_head_pipeline: [merge_request])
+
+ review_env_a = create(:environment, project: project, state: :available, name: 'review/a')
+ review_env_b = create(:environment, project: project, state: :available, name: 'review/b')
+ review_env_c = create(:environment, project: project, state: :stopped, name: 'review/c')
+ deploy_env = create(:environment, project: project, state: :available, name: 'deploy')
+
+ review_job_a1 = create(:ci_build, :with_deployment, :start_review_app,
+ pipeline: pipeline, project: project, environment: review_env_a.name)
+ review_job_a2 = create(:ci_build, :with_deployment, :start_review_app,
+ pipeline: pipeline, project: project, environment: review_env_a.name)
+ finished_review_job_a = create(:ci_build, :with_deployment, :start_review_app,
+ pipeline: pipeline, project: project, status: :success, environment: review_env_a.name)
+ review_job_b1 = create(:ci_build, :with_deployment, :start_review_app,
+ pipeline: pipeline, project: project, environment: review_env_b.name)
+ review_job_b2 = create(:ci_build, :start_review_app,
+ pipeline: pipeline, project: project, environment: review_env_b.name)
+ review_job_c1 = create(:ci_build, :with_deployment, :start_review_app,
+ pipeline: pipeline, project: project, environment: review_env_c.name)
+ deploy_job = create(:ci_build, :with_deployment, :deploy_to_production,
+ pipeline: pipeline, project: project, environment: deploy_env.name)
+
+ subject
+
+ expect(review_job_a1.reload.canceled?).to be true
+ expect(review_job_a2.reload.canceled?).to be true
+ expect(finished_review_job_a.reload.status).to eq "success"
+ expect(finished_review_job_a.reload.canceled?).to be false
+ expect(review_job_b1.reload.canceled?).to be true
+ expect(review_job_b2.reload.canceled?).to be false
+ expect(review_job_c1.reload.canceled?).to be false
+ expect(deploy_job.reload.canceled?).to be false
+ end
end
end
end
diff --git a/spec/services/merge_requests/push_options_handler_service_spec.rb b/spec/services/merge_requests/push_options_handler_service_spec.rb
index 420c8513c72..55f92d6bd0a 100644
--- a/spec/services/merge_requests/push_options_handler_service_spec.rb
+++ b/spec/services/merge_requests/push_options_handler_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe MergeRequests::PushOptionsHandlerService do
+RSpec.describe MergeRequests::PushOptionsHandlerService do
include ProjectForksHelper
let(:user) { create(:user) }
diff --git a/spec/services/merge_requests/pushed_branches_service_spec.rb b/spec/services/merge_requests/pushed_branches_service_spec.rb
index 7b5d505f4d9..6e9c77bd3b6 100644
--- a/spec/services/merge_requests/pushed_branches_service_spec.rb
+++ b/spec/services/merge_requests/pushed_branches_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe MergeRequests::PushedBranchesService do
+RSpec.describe MergeRequests::PushedBranchesService do
let(:project) { create(:project) }
let!(:service) { described_class.new(project, nil, changes: pushed_branches) }
diff --git a/spec/services/merge_requests/rebase_service_spec.rb b/spec/services/merge_requests/rebase_service_spec.rb
index 69d555f838d..2e525f2ed01 100644
--- a/spec/services/merge_requests/rebase_service_spec.rb
+++ b/spec/services/merge_requests/rebase_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe MergeRequests::RebaseService do
+RSpec.describe MergeRequests::RebaseService do
include ProjectForksHelper
let(:user) { create(:user) }
diff --git a/spec/services/merge_requests/refresh_service_spec.rb b/spec/services/merge_requests/refresh_service_spec.rb
index e60ff6eb98a..18c4cef7087 100644
--- a/spec/services/merge_requests/refresh_service_spec.rb
+++ b/spec/services/merge_requests/refresh_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe MergeRequests::RefreshService do
+RSpec.describe MergeRequests::RefreshService do
include ProjectForksHelper
include ProjectHelpers
@@ -225,12 +225,13 @@ describe MergeRequests::RefreshService do
context 'when service runs on forked project' do
let(:project) { @fork_project }
- it 'creates legacy detached merge request pipeline for fork merge request', :sidekiq_might_not_need_inline do
+ it 'creates detached merge request pipeline for fork merge request', :sidekiq_inline do
expect { subject }
.to change { @fork_merge_request.pipelines_for_merge_request.count }.by(1)
- expect(@fork_merge_request.pipelines_for_merge_request.first)
- .to be_legacy_detached_merge_request_pipeline
+ merge_request_pipeline = @fork_merge_request.pipelines_for_merge_request.first
+ expect(merge_request_pipeline).to be_detached_merge_request_pipeline
+ expect(merge_request_pipeline.project).to eq(@project)
end
end
diff --git a/spec/services/merge_requests/reload_diffs_service_spec.rb b/spec/services/merge_requests/reload_diffs_service_spec.rb
index d2444af1b0f..3d5b65207e6 100644
--- a/spec/services/merge_requests/reload_diffs_service_spec.rb
+++ b/spec/services/merge_requests/reload_diffs_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe MergeRequests::ReloadDiffsService, :use_clean_rails_memory_store_caching do
+RSpec.describe MergeRequests::ReloadDiffsService, :use_clean_rails_memory_store_caching do
let(:current_user) { create(:user) }
let(:merge_request) { create(:merge_request) }
let(:subject) { described_class.new(merge_request, current_user) }
@@ -34,10 +34,8 @@ describe MergeRequests::ReloadDiffsService, :use_clean_rails_memory_store_cachin
context 'cache clearing' do
it 'clears the cache for older diffs on the merge request' do
- old_diff = merge_request.merge_request_diff
- old_cache_key = old_diff.diffs_collection.cache_key
-
- expect_any_instance_of(Redis).to receive(:del).with(old_cache_key).and_call_original
+ expect_any_instance_of(Redis).to receive(:del).once.and_call_original
+ expect(Rails.cache).to receive(:delete).once.and_call_original
subject.execute
end
diff --git a/spec/services/merge_requests/remove_approval_service_spec.rb b/spec/services/merge_requests/remove_approval_service_spec.rb
new file mode 100644
index 00000000000..40da928e832
--- /dev/null
+++ b/spec/services/merge_requests/remove_approval_service_spec.rb
@@ -0,0 +1,46 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe MergeRequests::RemoveApprovalService do
+ describe '#execute' do
+ let(:user) { create(:user) }
+ let(:project) { create(:project) }
+ let(:merge_request) { create(:merge_request, source_project: project) }
+ let!(:existing_approval) { create(:approval, merge_request: merge_request) }
+
+ subject(:service) { described_class.new(project, user) }
+
+ def execute!
+ service.execute(merge_request)
+ end
+
+ before do
+ project.add_developer(user)
+ end
+
+ context 'with a user who has approved' do
+ let!(:approval) { create(:approval, user: user, merge_request: merge_request) }
+
+ it 'removes the approval' do
+ expect { execute! }.to change { merge_request.approvals.size }.from(2).to(1)
+ end
+
+ it 'creates an unapproval note and triggers web hook' do
+ expect(service).to receive(:execute_hooks).with(merge_request, 'unapproved')
+ expect(SystemNoteService).to receive(:unapprove_mr)
+
+ execute!
+ end
+ end
+
+ context 'with a user who has not approved' do
+ it 'does not create an unapproval note and triggers web hook' do
+ expect(service).not_to receive(:execute_hooks)
+ expect(SystemNoteService).not_to receive(:unapprove_mr)
+
+ execute!
+ end
+ end
+ end
+end
diff --git a/spec/services/merge_requests/reopen_service_spec.rb b/spec/services/merge_requests/reopen_service_spec.rb
index 3807c44b01f..0066834180e 100644
--- a/spec/services/merge_requests/reopen_service_spec.rb
+++ b/spec/services/merge_requests/reopen_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe MergeRequests::ReopenService do
+RSpec.describe MergeRequests::ReopenService do
let(:user) { create(:user) }
let(:user2) { create(:user) }
let(:guest) { create(:user) }
diff --git a/spec/services/merge_requests/resolved_discussion_notification_service_spec.rb b/spec/services/merge_requests/resolved_discussion_notification_service_spec.rb
index 29896db58ac..874cf66659a 100644
--- a/spec/services/merge_requests/resolved_discussion_notification_service_spec.rb
+++ b/spec/services/merge_requests/resolved_discussion_notification_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe MergeRequests::ResolvedDiscussionNotificationService do
+RSpec.describe MergeRequests::ResolvedDiscussionNotificationService do
let(:merge_request) { create(:merge_request) }
let(:user) { create(:user) }
let(:project) { merge_request.project }
diff --git a/spec/services/merge_requests/squash_service_spec.rb b/spec/services/merge_requests/squash_service_spec.rb
index a53314ed737..1ec1dc0f6eb 100644
--- a/spec/services/merge_requests/squash_service_spec.rb
+++ b/spec/services/merge_requests/squash_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe MergeRequests::SquashService do
+RSpec.describe MergeRequests::SquashService do
include GitHelpers
let(:service) { described_class.new(project, user, { merge_request: merge_request }) }
@@ -131,6 +131,42 @@ describe MergeRequests::SquashService do
include_examples 'the squash succeeds'
end
+ context 'when squashing is disabled by default on the project' do
+ # Squashing is disabled by default, but it should still allow you
+ # to squash-and-merge if selected through the UI
+ let(:merge_request) { merge_request_with_only_new_files }
+
+ before do
+ merge_request.project.project_setting.squash_default_off!
+ end
+
+ include_examples 'the squash succeeds'
+ end
+
+ context 'when squashing is forbidden on the project' do
+ let(:merge_request) { merge_request_with_only_new_files }
+
+ before do
+ merge_request.project.project_setting.squash_never!
+ end
+
+ it 'raises a squash error' do
+ expect(service.execute).to match(
+ status: :error,
+ message: a_string_including('does not allow squashing commits when merge requests are accepted'))
+ end
+ end
+
+ context 'when squashing is enabled by default on the project' do
+ let(:merge_request) { merge_request_with_only_new_files }
+
+ before do
+ merge_request.project.project_setting.squash_always!
+ end
+
+ include_examples 'the squash succeeds'
+ end
+
context 'when squashing with files too large to display' do
let(:merge_request) { merge_request_with_large_files }
diff --git a/spec/services/merge_requests/update_service_spec.rb b/spec/services/merge_requests/update_service_spec.rb
index 2b934b24757..c3433c8c9d2 100644
--- a/spec/services/merge_requests/update_service_spec.rb
+++ b/spec/services/merge_requests/update_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe MergeRequests::UpdateService, :mailer do
+RSpec.describe MergeRequests::UpdateService, :mailer do
include ProjectForksHelper
let(:group) { create(:group, :public) }
@@ -737,5 +737,10 @@ describe MergeRequests::UpdateService, :mailer do
.to change { merge_request.reload.force_remove_source_branch? }.from(nil).to(true)
end
end
+
+ it_behaves_like 'issuable record that supports quick actions' do
+ let(:existing_merge_request) { create(:merge_request, source_project: project) }
+ let(:issuable) { described_class.new(project, user, params).execute(existing_merge_request) }
+ end
end
end
diff --git a/spec/services/metrics/dashboard/annotations/create_service_spec.rb b/spec/services/metrics/dashboard/annotations/create_service_spec.rb
index 7dabca3c860..c3fe7238047 100644
--- a/spec/services/metrics/dashboard/annotations/create_service_spec.rb
+++ b/spec/services/metrics/dashboard/annotations/create_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Metrics::Dashboard::Annotations::CreateService do
+RSpec.describe Metrics::Dashboard::Annotations::CreateService do
let_it_be(:user) { create(:user) }
let(:description) { 'test annotation' }
let(:dashboard_path) { 'config/prometheus/common_metrics.yml' }
diff --git a/spec/services/metrics/dashboard/annotations/delete_service_spec.rb b/spec/services/metrics/dashboard/annotations/delete_service_spec.rb
index 95825db6902..ec2bd3772bf 100644
--- a/spec/services/metrics/dashboard/annotations/delete_service_spec.rb
+++ b/spec/services/metrics/dashboard/annotations/delete_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Metrics::Dashboard::Annotations::DeleteService do
+RSpec.describe Metrics::Dashboard::Annotations::DeleteService do
let(:user) { create(:user) }
let(:service_instance) { described_class.new(user, annotation) }
diff --git a/spec/services/metrics/dashboard/clone_dashboard_service_spec.rb b/spec/services/metrics/dashboard/clone_dashboard_service_spec.rb
index 3d26ab2ede5..4a226fe386c 100644
--- a/spec/services/metrics/dashboard/clone_dashboard_service_spec.rb
+++ b/spec/services/metrics/dashboard/clone_dashboard_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Metrics::Dashboard::CloneDashboardService, :use_clean_rails_memory_store_caching do
+RSpec.describe Metrics::Dashboard::CloneDashboardService, :use_clean_rails_memory_store_caching do
include MetricsDashboardHelpers
let_it_be(:user) { create(:user) }
@@ -81,7 +81,22 @@ describe Metrics::Dashboard::CloneDashboardService, :use_clean_rails_memory_stor
allow(::Gitlab::Metrics::Dashboard::Processor).to receive(:new).and_return(double(process: file_content_hash))
end
- it_behaves_like 'valid dashboard cloning process', ::Metrics::Dashboard::SystemDashboardService::DASHBOARD_PATH, [::Gitlab::Metrics::Dashboard::Stages::CommonMetricsInserter, ::Gitlab::Metrics::Dashboard::Stages::CustomMetricsInserter, ::Gitlab::Metrics::Dashboard::Stages::Sorter]
+ it_behaves_like 'valid dashboard cloning process', ::Metrics::Dashboard::SystemDashboardService::DASHBOARD_PATH,
+ [
+ ::Gitlab::Metrics::Dashboard::Stages::CommonMetricsInserter,
+ ::Gitlab::Metrics::Dashboard::Stages::CustomMetricsInserter,
+ ::Gitlab::Metrics::Dashboard::Stages::Sorter
+ ]
+
+ it_behaves_like 'valid dashboard cloning process', ::Metrics::Dashboard::ClusterDashboardService::DASHBOARD_PATH,
+ [
+ ::Gitlab::Metrics::Dashboard::Stages::CommonMetricsInserter,
+ ::Gitlab::Metrics::Dashboard::Stages::Sorter
+ ]
+
+ it_behaves_like 'valid dashboard cloning process',
+ ::Metrics::Dashboard::SelfMonitoringDashboardService::DASHBOARD_PATH,
+ [::Gitlab::Metrics::Dashboard::Stages::CustomMetricsInserter]
context 'selected branch already exists' do
let(:branch) { 'existing_branch' }
diff --git a/spec/services/metrics/dashboard/cluster_dashboard_service_spec.rb b/spec/services/metrics/dashboard/cluster_dashboard_service_spec.rb
new file mode 100644
index 00000000000..f2e32d5eb35
--- /dev/null
+++ b/spec/services/metrics/dashboard/cluster_dashboard_service_spec.rb
@@ -0,0 +1,59 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Metrics::Dashboard::ClusterDashboardService, :use_clean_rails_memory_store_caching do
+ include MetricsDashboardHelpers
+
+ let_it_be(:user) { create(:user) }
+ let_it_be(:cluster_project) { create(:cluster_project) }
+ let_it_be(:cluster) { cluster_project.cluster }
+ let_it_be(:project) { cluster_project.project }
+
+ before do
+ project.add_maintainer(user)
+ end
+
+ describe '.valid_params?' do
+ let(:params) { { cluster: cluster, embedded: 'false' } }
+
+ subject { described_class.valid_params?(params) }
+
+ it { is_expected.to be_truthy }
+
+ context 'with matching dashboard_path' do
+ let(:params) { { dashboard_path: ::Metrics::Dashboard::ClusterDashboardService::DASHBOARD_PATH } }
+
+ it { is_expected.to be_truthy }
+ end
+
+ context 'missing cluster without dashboard_path' do
+ let(:params) { {} }
+
+ it { is_expected.to be_falsey }
+ end
+ end
+
+ describe '#get_dashboard' do
+ let(:service_params) { [project, user, { cluster: cluster, cluster_type: :project }] }
+ let(:service_call) { subject.get_dashboard }
+
+ subject { described_class.new(*service_params) }
+
+ it_behaves_like 'valid dashboard service response'
+ it_behaves_like 'caches the unprocessed dashboard for subsequent calls'
+ it_behaves_like 'refreshes cache when dashboard_version is changed'
+
+ it_behaves_like 'dashboard_version contains SHA256 hash of dashboard file content' do
+ let(:dashboard_path) { described_class::DASHBOARD_PATH }
+ let(:dashboard_version) { subject.send(:dashboard_version) }
+ end
+
+ context 'when called with a non-system dashboard' do
+ let(:dashboard_path) { 'garbage/dashboard/path' }
+
+ # We want to always return the cluster dashboard.
+ it_behaves_like 'valid dashboard service response'
+ end
+ end
+end
diff --git a/spec/services/metrics/dashboard/cluster_metrics_embed_service_spec.rb b/spec/services/metrics/dashboard/cluster_metrics_embed_service_spec.rb
new file mode 100644
index 00000000000..e80911d6265
--- /dev/null
+++ b/spec/services/metrics/dashboard/cluster_metrics_embed_service_spec.rb
@@ -0,0 +1,72 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Metrics::Dashboard::ClusterMetricsEmbedService, :use_clean_rails_memory_store_caching do
+ include MetricsDashboardHelpers
+ using RSpec::Parameterized::TableSyntax
+
+ let_it_be(:user) { create(:user) }
+ let_it_be(:cluster_project) { create(:cluster_project) }
+ let_it_be(:cluster) { cluster_project.cluster }
+ let_it_be(:project) { cluster_project.project }
+
+ before do
+ project.add_maintainer(user)
+ end
+
+ describe '.valid_params?' do
+ let(:valid_params) { { cluster: 1, embedded: 'true', group: 'hello', title: 'world', y_label: 'countries' } }
+
+ subject { described_class }
+
+ it { expect(subject.valid_params?(valid_params)).to be_truthy }
+
+ context 'missing all params' do
+ let(:params) { {} }
+
+ it { expect(subject.valid_params?(params)).to be_falsy }
+ end
+
+ [:cluster, :embedded, :group, :title, :y_label].each do |param_key|
+ it 'returns false with missing param' do
+ params = valid_params.except(param_key)
+
+ expect(subject.valid_params?(params)).to be_falsy
+ end
+ end
+ end
+
+ describe '#get_dashboard' do
+ let(:service_params) do
+ [
+ project,
+ user,
+ {
+ cluster: cluster,
+ cluster_type: :project,
+ embedded: 'true',
+ group: 'Cluster Health',
+ title: 'CPU Usage',
+ y_label: 'CPU (cores)'
+ }
+ ]
+ end
+ let(:service_call) { described_class.new(*service_params).get_dashboard }
+ let(:panel_groups) { service_call[:dashboard][:panel_groups] }
+ let(:panel) { panel_groups.first[:panels].first }
+
+ it_behaves_like 'valid embedded dashboard service response'
+ it_behaves_like 'caches the unprocessed dashboard for subsequent calls'
+
+ it 'returns one panel' do
+ expect(panel_groups.size).to eq 1
+ expect(panel_groups.first[:panels].size).to eq 1
+ end
+
+ it 'returns panel by title and y_label' do
+ expect(panel[:title]).to eq(service_params.last[:title])
+ expect(panel[:y_label]).to eq(service_params.last[:y_label])
+ end
+ end
+end
diff --git a/spec/services/metrics/dashboard/custom_dashboard_service_spec.rb b/spec/services/metrics/dashboard/custom_dashboard_service_spec.rb
index 4966b83bbab..d4391ecb6b9 100644
--- a/spec/services/metrics/dashboard/custom_dashboard_service_spec.rb
+++ b/spec/services/metrics/dashboard/custom_dashboard_service_spec.rb
@@ -2,24 +2,31 @@
require 'spec_helper'
-describe Metrics::Dashboard::CustomDashboardService, :use_clean_rails_memory_store_caching do
+RSpec.describe Metrics::Dashboard::CustomDashboardService, :use_clean_rails_memory_store_caching do
include MetricsDashboardHelpers
let_it_be(:user) { create(:user) }
let_it_be(:project) { create(:project) }
let_it_be(:environment) { create(:environment, project: project) }
+ let(:dashboard_path) { '.gitlab/dashboards/test.yml' }
+ let(:service_params) { [project, user, { environment: environment, dashboard_path: dashboard_path }] }
+
+ subject { described_class.new(*service_params) }
+
before do
project.add_maintainer(user)
end
+ describe '#raw_dashboard' do
+ let(:project) { project_with_dashboard(dashboard_path) }
+
+ it_behaves_like '#raw_dashboard raises error if dashboard loading fails'
+ end
+
describe '#get_dashboard' do
- let(:dashboard_path) { '.gitlab/dashboards/test.yml' }
- let(:service_params) { [project, user, { environment: environment, dashboard_path: dashboard_path }] }
let(:service_call) { subject.get_dashboard }
- subject { described_class.new(*service_params) }
-
context 'when the dashboard does not exist' do
it_behaves_like 'misconfigured dashboard service response', :not_found
@@ -92,7 +99,8 @@ describe Metrics::Dashboard::CustomDashboardService, :use_clean_rails_memory_sto
path: dashboard_path,
display_name: 'test.yml',
default: false,
- system_dashboard: false
+ system_dashboard: false,
+ out_of_the_box_dashboard: false
}]
)
end
diff --git a/spec/services/metrics/dashboard/custom_metric_embed_service_spec.rb b/spec/services/metrics/dashboard/custom_metric_embed_service_spec.rb
index 1a9ddc87ab0..a5f7c2ab8ab 100644
--- a/spec/services/metrics/dashboard/custom_metric_embed_service_spec.rb
+++ b/spec/services/metrics/dashboard/custom_metric_embed_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Metrics::Dashboard::CustomMetricEmbedService do
+RSpec.describe Metrics::Dashboard::CustomMetricEmbedService do
include MetricsDashboardHelpers
let_it_be(:project, reload: true) { build(:project) }
diff --git a/spec/services/metrics/dashboard/default_embed_service_spec.rb b/spec/services/metrics/dashboard/default_embed_service_spec.rb
index 8e32316433d..2ce10eac026 100644
--- a/spec/services/metrics/dashboard/default_embed_service_spec.rb
+++ b/spec/services/metrics/dashboard/default_embed_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Metrics::Dashboard::DefaultEmbedService, :use_clean_rails_memory_store_caching do
+RSpec.describe Metrics::Dashboard::DefaultEmbedService, :use_clean_rails_memory_store_caching do
include MetricsDashboardHelpers
let_it_be(:project) { build(:project) }
diff --git a/spec/services/metrics/dashboard/dynamic_embed_service_spec.rb b/spec/services/metrics/dashboard/dynamic_embed_service_spec.rb
index ee75284b4ce..72b356be60f 100644
--- a/spec/services/metrics/dashboard/dynamic_embed_service_spec.rb
+++ b/spec/services/metrics/dashboard/dynamic_embed_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Metrics::Dashboard::DynamicEmbedService, :use_clean_rails_memory_store_caching do
+RSpec.describe Metrics::Dashboard::DynamicEmbedService, :use_clean_rails_memory_store_caching do
include MetricsDashboardHelpers
let_it_be(:project) { build(:project) }
diff --git a/spec/services/metrics/dashboard/gitlab_alert_embed_service_spec.rb b/spec/services/metrics/dashboard/gitlab_alert_embed_service_spec.rb
index a66150be42c..29c941826b5 100644
--- a/spec/services/metrics/dashboard/gitlab_alert_embed_service_spec.rb
+++ b/spec/services/metrics/dashboard/gitlab_alert_embed_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Metrics::Dashboard::GitlabAlertEmbedService do
+RSpec.describe Metrics::Dashboard::GitlabAlertEmbedService do
include MetricsDashboardHelpers
let_it_be(:alert) { create(:prometheus_alert) }
diff --git a/spec/services/metrics/dashboard/grafana_metric_embed_service_spec.rb b/spec/services/metrics/dashboard/grafana_metric_embed_service_spec.rb
index 3547e1f0f8c..ee3c55cb642 100644
--- a/spec/services/metrics/dashboard/grafana_metric_embed_service_spec.rb
+++ b/spec/services/metrics/dashboard/grafana_metric_embed_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Metrics::Dashboard::GrafanaMetricEmbedService do
+RSpec.describe Metrics::Dashboard::GrafanaMetricEmbedService do
include MetricsDashboardHelpers
include ReactiveCachingHelpers
include GrafanaApiHelpers
@@ -182,7 +182,7 @@ describe Metrics::Dashboard::GrafanaMetricEmbedService do
end
end
-describe Metrics::Dashboard::GrafanaUidParser do
+RSpec.describe Metrics::Dashboard::GrafanaUidParser do
let_it_be(:grafana_integration) { create(:grafana_integration) }
let_it_be(:project) { grafana_integration.project }
@@ -213,7 +213,7 @@ describe Metrics::Dashboard::GrafanaUidParser do
end
end
-describe Metrics::Dashboard::DatasourceNameParser do
+RSpec.describe Metrics::Dashboard::DatasourceNameParser do
include GrafanaApiHelpers
let(:grafana_url) { valid_grafana_dashboard_link('https://gitlab.grafana.net') }
diff --git a/spec/services/metrics/dashboard/pod_dashboard_service_spec.rb b/spec/services/metrics/dashboard/pod_dashboard_service_spec.rb
index 1e62a5504a9..ae0e38a04b2 100644
--- a/spec/services/metrics/dashboard/pod_dashboard_service_spec.rb
+++ b/spec/services/metrics/dashboard/pod_dashboard_service_spec.rb
@@ -2,17 +2,26 @@
require 'spec_helper'
-describe Metrics::Dashboard::PodDashboardService, :use_clean_rails_memory_store_caching do
+RSpec.describe Metrics::Dashboard::PodDashboardService, :use_clean_rails_memory_store_caching do
include MetricsDashboardHelpers
let_it_be(:user) { create(:user) }
let_it_be(:project) { create(:project) }
let_it_be(:environment) { create(:environment, project: project) }
+ let(:dashboard_path) { described_class::DASHBOARD_PATH }
+ let(:service_params) { [project, user, { environment: environment, dashboard_path: dashboard_path }] }
+
before do
project.add_maintainer(user)
end
+ subject { described_class.new(*service_params) }
+
+ describe '#raw_dashboard' do
+ it_behaves_like '#raw_dashboard raises error if dashboard loading fails'
+ end
+
describe '.valid_params?' do
let(:params) { { dashboard_path: described_class::DASHBOARD_PATH } }
@@ -34,14 +43,15 @@ describe Metrics::Dashboard::PodDashboardService, :use_clean_rails_memory_store_
end
describe '#get_dashboard' do
- let(:dashboard_path) { described_class::DASHBOARD_PATH }
- let(:service_params) { [project, user, { environment: environment, dashboard_path: dashboard_path }] }
let(:service_call) { subject.get_dashboard }
- subject { described_class.new(*service_params) }
-
it_behaves_like 'valid dashboard service response'
it_behaves_like 'caches the unprocessed dashboard for subsequent calls'
+ it_behaves_like 'refreshes cache when dashboard_version is changed'
it_behaves_like 'updates gitlab_metrics_dashboard_processing_time_ms metric'
+
+ it_behaves_like 'dashboard_version contains SHA256 hash of dashboard file content' do
+ let(:dashboard_version) { subject.send(:dashboard_version) }
+ end
end
end
diff --git a/spec/services/metrics/dashboard/self_monitoring_dashboard_service_spec.rb b/spec/services/metrics/dashboard/self_monitoring_dashboard_service_spec.rb
index 6c9a380a470..aea3e41a013 100644
--- a/spec/services/metrics/dashboard/self_monitoring_dashboard_service_spec.rb
+++ b/spec/services/metrics/dashboard/self_monitoring_dashboard_service_spec.rb
@@ -2,20 +2,29 @@
require 'spec_helper'
-describe Metrics::Dashboard::SelfMonitoringDashboardService, :use_clean_rails_memory_store_caching do
+RSpec.describe Metrics::Dashboard::SelfMonitoringDashboardService, :use_clean_rails_memory_store_caching do
include MetricsDashboardHelpers
let_it_be(:user) { create(:user) }
let_it_be(:project) { create(:project) }
let_it_be(:environment) { create(:environment, project: project) }
+ let(:service_params) { [project, user, { environment: environment }] }
+
before do
project.add_maintainer(user)
stub_application_setting(self_monitoring_project_id: project.id)
end
+ subject do
+ described_class.new(service_params)
+ end
+
+ describe '#raw_dashboard' do
+ it_behaves_like '#raw_dashboard raises error if dashboard loading fails'
+ end
+
describe '#get_dashboard' do
- let(:service_params) { [project, user, { environment: environment }] }
let(:service_call) { subject.get_dashboard }
subject { described_class.new(*service_params) }
@@ -23,7 +32,13 @@ describe Metrics::Dashboard::SelfMonitoringDashboardService, :use_clean_rails_me
it_behaves_like 'valid dashboard service response'
it_behaves_like 'raises error for users with insufficient permissions'
it_behaves_like 'caches the unprocessed dashboard for subsequent calls'
+ it_behaves_like 'refreshes cache when dashboard_version is changed'
it_behaves_like 'updates gitlab_metrics_dashboard_processing_time_ms metric'
+
+ it_behaves_like 'dashboard_version contains SHA256 hash of dashboard file content' do
+ let(:dashboard_path) { described_class::DASHBOARD_PATH }
+ let(:dashboard_version) { subject.send(:dashboard_version) }
+ end
end
describe '.all_dashboard_paths' do
@@ -35,7 +50,8 @@ describe Metrics::Dashboard::SelfMonitoringDashboardService, :use_clean_rails_me
path: described_class::DASHBOARD_PATH,
display_name: described_class::DASHBOARD_NAME,
default: true,
- system_dashboard: false
+ system_dashboard: false,
+ out_of_the_box_dashboard: true
}]
)
end
diff --git a/spec/services/metrics/dashboard/system_dashboard_service_spec.rb b/spec/services/metrics/dashboard/system_dashboard_service_spec.rb
index 7d58501ae3f..ced7c29b507 100644
--- a/spec/services/metrics/dashboard/system_dashboard_service_spec.rb
+++ b/spec/services/metrics/dashboard/system_dashboard_service_spec.rb
@@ -2,29 +2,39 @@
require 'spec_helper'
-describe Metrics::Dashboard::SystemDashboardService, :use_clean_rails_memory_store_caching do
+RSpec.describe Metrics::Dashboard::SystemDashboardService, :use_clean_rails_memory_store_caching do
include MetricsDashboardHelpers
let_it_be(:user) { create(:user) }
let_it_be(:project) { create(:project) }
let_it_be(:environment) { create(:environment, project: project) }
+ let(:dashboard_path) { described_class::DASHBOARD_PATH }
+ let(:service_params) { [project, user, { environment: environment, dashboard_path: dashboard_path }] }
+
+ subject { described_class.new(*service_params) }
+
before do
project.add_maintainer(user)
end
+ describe '#raw_dashboard' do
+ it_behaves_like '#raw_dashboard raises error if dashboard loading fails'
+ end
+
describe '#get_dashboard' do
- let(:dashboard_path) { described_class::DASHBOARD_PATH }
- let(:service_params) { [project, user, { environment: environment, dashboard_path: dashboard_path }] }
let(:service_call) { subject.get_dashboard }
- subject { described_class.new(*service_params) }
-
it_behaves_like 'valid dashboard service response'
it_behaves_like 'raises error for users with insufficient permissions'
it_behaves_like 'caches the unprocessed dashboard for subsequent calls'
+ it_behaves_like 'refreshes cache when dashboard_version is changed'
it_behaves_like 'updates gitlab_metrics_dashboard_processing_time_ms metric'
+ it_behaves_like 'dashboard_version contains SHA256 hash of dashboard file content' do
+ let(:dashboard_version) { subject.send(:dashboard_version) }
+ end
+
context 'when called with a non-system dashboard' do
let(:dashboard_path) { 'garbage/dashboard/path' }
@@ -42,7 +52,8 @@ describe Metrics::Dashboard::SystemDashboardService, :use_clean_rails_memory_sto
path: described_class::DASHBOARD_PATH,
display_name: described_class::DASHBOARD_NAME,
default: true,
- system_dashboard: true
+ system_dashboard: true,
+ out_of_the_box_dashboard: true
}]
)
end
diff --git a/spec/services/metrics/dashboard/transient_embed_service_spec.rb b/spec/services/metrics/dashboard/transient_embed_service_spec.rb
index 125fff7c23c..3fd0c97d909 100644
--- a/spec/services/metrics/dashboard/transient_embed_service_spec.rb
+++ b/spec/services/metrics/dashboard/transient_embed_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Metrics::Dashboard::TransientEmbedService, :use_clean_rails_memory_store_caching do
+RSpec.describe Metrics::Dashboard::TransientEmbedService, :use_clean_rails_memory_store_caching do
let_it_be(:project) { build(:project) }
let_it_be(:user) { create(:user) }
let_it_be(:environment) { create(:environment, project: project) }
diff --git a/spec/services/metrics/dashboard/update_dashboard_service_spec.rb b/spec/services/metrics/dashboard/update_dashboard_service_spec.rb
index fce027688d9..148005480ea 100644
--- a/spec/services/metrics/dashboard/update_dashboard_service_spec.rb
+++ b/spec/services/metrics/dashboard/update_dashboard_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Metrics::Dashboard::UpdateDashboardService, :use_clean_rails_memory_store_caching do
+RSpec.describe Metrics::Dashboard::UpdateDashboardService, :use_clean_rails_memory_store_caching do
include MetricsDashboardHelpers
let_it_be(:user) { create(:user) }
diff --git a/spec/services/metrics/sample_metrics_service_spec.rb b/spec/services/metrics/sample_metrics_service_spec.rb
index 3b4f7cb8062..b94345500f0 100644
--- a/spec/services/metrics/sample_metrics_service_spec.rb
+++ b/spec/services/metrics/sample_metrics_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Metrics::SampleMetricsService do
+RSpec.describe Metrics::SampleMetricsService do
describe 'query' do
let(:range_start) { '2019-12-02T23:31:45.000Z' }
let(:range_end) { '2019-12-03T00:01:45.000Z' }
diff --git a/spec/services/metrics/users_starred_dashboards/create_service_spec.rb b/spec/services/metrics/users_starred_dashboards/create_service_spec.rb
index eac4965ba44..910b556b8dd 100644
--- a/spec/services/metrics/users_starred_dashboards/create_service_spec.rb
+++ b/spec/services/metrics/users_starred_dashboards/create_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Metrics::UsersStarredDashboards::CreateService do
+RSpec.describe Metrics::UsersStarredDashboards::CreateService do
let_it_be(:user) { create(:user) }
let(:dashboard_path) { 'config/prometheus/common_metrics.yml' }
let(:service_instance) { described_class.new(user, project, dashboard_path) }
diff --git a/spec/services/metrics/users_starred_dashboards/delete_service_spec.rb b/spec/services/metrics/users_starred_dashboards/delete_service_spec.rb
index 68a2fef5931..5cdffe681eb 100644
--- a/spec/services/metrics/users_starred_dashboards/delete_service_spec.rb
+++ b/spec/services/metrics/users_starred_dashboards/delete_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Metrics::UsersStarredDashboards::DeleteService do
+RSpec.describe Metrics::UsersStarredDashboards::DeleteService do
subject(:service_instance) { described_class.new(user, project, dashboard_path) }
let_it_be(:user) { create(:user) }
diff --git a/spec/services/milestones/close_service_spec.rb b/spec/services/milestones/close_service_spec.rb
index 55e705063b2..53751b40667 100644
--- a/spec/services/milestones/close_service_spec.rb
+++ b/spec/services/milestones/close_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Milestones::CloseService do
+RSpec.describe Milestones::CloseService do
let(:user) { create(:user) }
let(:project) { create(:project) }
let(:milestone) { create(:milestone, title: "Milestone v1.2", project: project) }
diff --git a/spec/services/milestones/closed_issues_count_service_spec.rb b/spec/services/milestones/closed_issues_count_service_spec.rb
index b86eede2e22..a3865d08972 100644
--- a/spec/services/milestones/closed_issues_count_service_spec.rb
+++ b/spec/services/milestones/closed_issues_count_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Milestones::ClosedIssuesCountService, :use_clean_rails_memory_store_caching do
+RSpec.describe Milestones::ClosedIssuesCountService, :use_clean_rails_memory_store_caching do
let(:project) { create(:project) }
let(:milestone) { create(:milestone, project: project) }
diff --git a/spec/services/milestones/create_service_spec.rb b/spec/services/milestones/create_service_spec.rb
index 97f6e947539..93ca4ff653f 100644
--- a/spec/services/milestones/create_service_spec.rb
+++ b/spec/services/milestones/create_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Milestones::CreateService do
+RSpec.describe Milestones::CreateService do
let(:project) { create(:project) }
let(:user) { create(:user) }
diff --git a/spec/services/milestones/destroy_service_spec.rb b/spec/services/milestones/destroy_service_spec.rb
index 4f16421c39f..66c5c504c64 100644
--- a/spec/services/milestones/destroy_service_spec.rb
+++ b/spec/services/milestones/destroy_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Milestones::DestroyService do
+RSpec.describe Milestones::DestroyService do
let(:user) { create(:user) }
let(:project) { create(:project, :repository) }
let(:milestone) { create(:milestone, title: 'Milestone v1.0', project: project) }
diff --git a/spec/services/milestones/find_or_create_service_spec.rb b/spec/services/milestones/find_or_create_service_spec.rb
index ae3def30982..1bcaf578441 100644
--- a/spec/services/milestones/find_or_create_service_spec.rb
+++ b/spec/services/milestones/find_or_create_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Milestones::FindOrCreateService do
+RSpec.describe Milestones::FindOrCreateService do
describe '#execute' do
subject(:service) { described_class.new(project, user, params) }
diff --git a/spec/services/milestones/issues_count_service_spec.rb b/spec/services/milestones/issues_count_service_spec.rb
index 22aea884424..c944055e4e7 100644
--- a/spec/services/milestones/issues_count_service_spec.rb
+++ b/spec/services/milestones/issues_count_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Milestones::IssuesCountService, :use_clean_rails_memory_store_caching do
+RSpec.describe Milestones::IssuesCountService, :use_clean_rails_memory_store_caching do
let(:project) { create(:project) }
let(:milestone) { create(:milestone, project: project) }
diff --git a/spec/services/milestones/promote_service_spec.rb b/spec/services/milestones/promote_service_spec.rb
index fa893b86cdb..f0a34241c74 100644
--- a/spec/services/milestones/promote_service_spec.rb
+++ b/spec/services/milestones/promote_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Milestones::PromoteService do
+RSpec.describe Milestones::PromoteService do
let(:group) { create(:group) }
let(:project) { create(:project, namespace: group) }
let(:user) { create(:user) }
diff --git a/spec/services/milestones/transfer_service_spec.rb b/spec/services/milestones/transfer_service_spec.rb
index 9f94d2d320b..4a626fe688a 100644
--- a/spec/services/milestones/transfer_service_spec.rb
+++ b/spec/services/milestones/transfer_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Milestones::TransferService do
+RSpec.describe Milestones::TransferService do
describe '#execute' do
subject(:service) { described_class.new(user, old_group, project) }
diff --git a/spec/services/milestones/update_service_spec.rb b/spec/services/milestones/update_service_spec.rb
index 3b91442c0ba..85fd89c11ac 100644
--- a/spec/services/milestones/update_service_spec.rb
+++ b/spec/services/milestones/update_service_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
require 'spec_helper'
-describe Milestones::UpdateService do
+RSpec.describe Milestones::UpdateService do
let(:project) { create(:project) }
let(:user) { build(:user) }
let(:milestone) { create(:milestone, project: project) }
diff --git a/spec/services/namespaces/check_storage_size_service_spec.rb b/spec/services/namespaces/check_storage_size_service_spec.rb
deleted file mode 100644
index e192f897cf9..00000000000
--- a/spec/services/namespaces/check_storage_size_service_spec.rb
+++ /dev/null
@@ -1,165 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-describe Namespaces::CheckStorageSizeService, '#execute' do
- let(:namespace) { build_stubbed(:namespace) }
- let(:user) { build(:user, namespace: namespace) }
- let(:service) { described_class.new(namespace, user) }
- let(:current_size) { 150.megabytes }
- let(:limit) { 100.megabytes }
-
- subject(:response) { service.execute }
-
- before do
- allow(namespace).to receive(:root_ancestor).and_return(namespace)
-
- root_storage_size = instance_double("RootStorageSize",
- current_size: current_size,
- limit: limit,
- usage_ratio: limit == 0 ? 0 : current_size.to_f / limit.to_f,
- above_size_limit?: current_size > limit
- )
-
- expect(Namespace::RootStorageSize).to receive(:new).and_return(root_storage_size)
- end
-
- context 'feature flag' do
- it 'is successful when disabled' do
- stub_feature_flags(namespace_storage_limit: false)
-
- expect(response).to be_success
- end
-
- it 'errors when enabled' do
- stub_feature_flags(namespace_storage_limit: true)
-
- expect(response).to be_error
- end
-
- it 'is successful when feature flag is activated for another namespace' do
- stub_feature_flags(namespace_storage_limit: build(:namespace))
-
- expect(response).to be_success
- end
-
- it 'errors when feature flag is activated for the current namespace' do
- stub_feature_flags(namespace_storage_limit: namespace)
-
- expect(response).to be_error
- expect(response.message).to be_present
- end
- end
-
- context 'when limit is set to 0' do
- let(:limit) { 0 }
-
- it 'is successful and has no payload' do
- expect(response).to be_success
- expect(response.payload).to be_empty
- end
- end
-
- context 'when current size is below threshold' do
- let(:current_size) { 10.megabytes }
-
- it 'is successful and has no payload' do
- expect(response).to be_success
- expect(response.payload).to be_empty
- end
- end
-
- context 'when not admin of the namespace' do
- let(:other_namespace) { build_stubbed(:namespace) }
-
- subject(:response) { described_class.new(other_namespace, user).execute }
-
- before do
- allow(other_namespace).to receive(:root_ancestor).and_return(other_namespace)
- end
-
- it 'errors and has no payload' do
- expect(response).to be_error
- expect(response.payload).to be_empty
- end
- end
-
- context 'when providing the child namespace' do
- let(:namespace) { build_stubbed(:group) }
- let(:child_namespace) { build_stubbed(:group, parent: namespace) }
-
- subject(:response) { described_class.new(child_namespace, user).execute }
-
- before do
- allow(child_namespace).to receive(:root_ancestor).and_return(namespace)
- namespace.add_owner(user)
- end
-
- it 'uses the root namespace' do
- expect(response).to be_error
- end
- end
-
- describe 'payload alert_level' do
- subject { service.execute.payload[:alert_level] }
-
- context 'when above info threshold' do
- let(:current_size) { 50.megabytes }
-
- it { is_expected.to eq(:info) }
- end
-
- context 'when above warning threshold' do
- let(:current_size) { 75.megabytes }
-
- it { is_expected.to eq(:warning) }
- end
-
- context 'when above alert threshold' do
- let(:current_size) { 95.megabytes }
-
- it { is_expected.to eq(:alert) }
- end
-
- context 'when above error threshold' do
- let(:current_size) { 100.megabytes }
-
- it { is_expected.to eq(:error) }
- end
- end
-
- describe 'payload explanation_message' do
- subject(:response) { service.execute.payload[:explanation_message] }
-
- context 'when above limit' do
- let(:current_size) { 110.megabytes }
-
- it 'returns message with read-only warning' do
- expect(response).to include("#{namespace.name} is now read-only")
- end
- end
-
- context 'when below limit' do
- let(:current_size) { 60.megabytes }
-
- it { is_expected.to include('If you reach 100% storage capacity') }
- end
- end
-
- describe 'payload usage_message' do
- let(:current_size) { 60.megabytes }
-
- subject(:response) { service.execute.payload[:usage_message] }
-
- it 'returns current usage information' do
- expect(response).to include("60 MB of 100 MB")
- expect(response).to include("60%")
- end
- end
-
- describe 'payload root_namespace' do
- subject(:response) { service.execute.payload[:root_namespace] }
-
- it { is_expected.to eq(namespace) }
- end
-end
diff --git a/spec/services/namespaces/statistics_refresher_service_spec.rb b/spec/services/namespaces/statistics_refresher_service_spec.rb
index 1fa0a794edd..d3379e843ec 100644
--- a/spec/services/namespaces/statistics_refresher_service_spec.rb
+++ b/spec/services/namespaces/statistics_refresher_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Namespaces::StatisticsRefresherService, '#execute' do
+RSpec.describe Namespaces::StatisticsRefresherService, '#execute' do
let(:group) { create(:group) }
let(:projects) { create_list(:project, 5, namespace: group) }
let(:service) { described_class.new }
diff --git a/spec/services/note_summary_spec.rb b/spec/services/note_summary_spec.rb
index 038e0cdb703..38174748b19 100644
--- a/spec/services/note_summary_spec.rb
+++ b/spec/services/note_summary_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe NoteSummary do
+RSpec.describe NoteSummary do
let(:project) { build(:project) }
let(:noteable) { build(:issue) }
let(:user) { build(:user) }
diff --git a/spec/services/notes/build_service_spec.rb b/spec/services/notes/build_service_spec.rb
index 984658cbd19..90548cf9a99 100644
--- a/spec/services/notes/build_service_spec.rb
+++ b/spec/services/notes/build_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Notes::BuildService do
+RSpec.describe Notes::BuildService do
let(:note) { create(:discussion_note_on_issue) }
let(:project) { note.project }
let(:author) { note.author }
diff --git a/spec/services/notes/create_service_spec.rb b/spec/services/notes/create_service_spec.rb
index 39d6fd26e31..fd824621db7 100644
--- a/spec/services/notes/create_service_spec.rb
+++ b/spec/services/notes/create_service_spec.rb
@@ -2,12 +2,12 @@
require 'spec_helper'
-describe Notes::CreateService do
+RSpec.describe Notes::CreateService do
let_it_be(:project) { create(:project, :repository) }
let_it_be(:issue) { create(:issue, project: project) }
let_it_be(:user) { create(:user) }
let(:opts) do
- { note: 'Awesome comment', noteable_type: 'Issue', noteable_id: issue.id }
+ { note: 'Awesome comment', noteable_type: 'Issue', noteable_id: issue.id, confidential: true }
end
describe '#execute' do
diff --git a/spec/services/notes/destroy_service_spec.rb b/spec/services/notes/destroy_service_spec.rb
index 258e5c68265..d1076f77cec 100644
--- a/spec/services/notes/destroy_service_spec.rb
+++ b/spec/services/notes/destroy_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Notes::DestroyService do
+RSpec.describe Notes::DestroyService do
let_it_be(:project) { create(:project, :public) }
let_it_be(:issue) { create(:issue, project: project) }
let(:user) { issue.author }
diff --git a/spec/services/notes/post_process_service_spec.rb b/spec/services/notes/post_process_service_spec.rb
index d564cacd2d8..07ef08d36c4 100644
--- a/spec/services/notes/post_process_service_spec.rb
+++ b/spec/services/notes/post_process_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Notes::PostProcessService do
+RSpec.describe Notes::PostProcessService do
let(:project) { create(:project) }
let(:issue) { create(:issue, project: project) }
let(:user) { create(:user) }
diff --git a/spec/services/notes/quick_actions_service_spec.rb b/spec/services/notes/quick_actions_service_spec.rb
index 7eea2a7afc6..d20824efaaa 100644
--- a/spec/services/notes/quick_actions_service_spec.rb
+++ b/spec/services/notes/quick_actions_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Notes::QuickActionsService do
+RSpec.describe Notes::QuickActionsService do
shared_context 'note on noteable' do
let(:project) { create(:project, :repository) }
let(:maintainer) { create(:user).tap { |u| project.add_maintainer(u) } }
diff --git a/spec/services/notes/render_service_spec.rb b/spec/services/notes/render_service_spec.rb
index ad69721d876..09cd7dc572b 100644
--- a/spec/services/notes/render_service_spec.rb
+++ b/spec/services/notes/render_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Notes::RenderService do
+RSpec.describe Notes::RenderService do
describe '#execute' do
it 'renders a Note' do
note = double(:note)
diff --git a/spec/services/notes/resolve_service_spec.rb b/spec/services/notes/resolve_service_spec.rb
index c98384c226e..1c5b308aed1 100644
--- a/spec/services/notes/resolve_service_spec.rb
+++ b/spec/services/notes/resolve_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Notes::ResolveService do
+RSpec.describe Notes::ResolveService do
let(:merge_request) { create(:merge_request) }
let(:note) { create(:diff_note_on_merge_request, noteable: merge_request, project: merge_request.project) }
let(:user) { merge_request.author }
diff --git a/spec/services/notes/update_service_spec.rb b/spec/services/notes/update_service_spec.rb
index ab28e08ec83..70dea99de4a 100644
--- a/spec/services/notes/update_service_spec.rb
+++ b/spec/services/notes/update_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Notes::UpdateService do
+RSpec.describe Notes::UpdateService do
let(:group) { create(:group, :public) }
let(:project) { create(:project, :public, group: group) }
let(:private_group) { create(:group, :private) }
@@ -59,6 +59,45 @@ describe Notes::UpdateService do
end
end
+ context 'setting confidentiality' do
+ let(:opts) { { confidential: true } }
+
+ context 'simple note' do
+ it 'updates the confidentiality' do
+ expect { update_note(opts) }.to change { note.reload.confidential }.from(nil).to(true)
+ end
+ end
+
+ context 'discussion notes' do
+ let(:note) { create(:discussion_note, project: project, noteable: issue, author: user, note: "Old note #{user2.to_reference}") }
+ let!(:response_note_1) { create(:discussion_note, project: project, noteable: issue, in_reply_to: note) }
+ let!(:response_note_2) { create(:discussion_note, project: project, noteable: issue, in_reply_to: note, confidential: false) }
+ let!(:other_note) { create(:note, project: project, noteable: issue) }
+
+ context 'when updating the root note' do
+ it 'updates the confidentiality of the root note and all the responses' do
+ update_note(opts)
+
+ expect(note.reload.confidential).to be_truthy
+ expect(response_note_1.reload.confidential).to be_truthy
+ expect(response_note_2.reload.confidential).to be_truthy
+ expect(other_note.reload.confidential).to be_falsey
+ end
+ end
+
+ context 'when updating one of the response notes' do
+ it 'updates only the confidentiality of the note that is being updated' do
+ Notes::UpdateService.new(project, user, opts).execute(response_note_1)
+
+ expect(note.reload.confidential).to be_falsey
+ expect(response_note_1.reload.confidential).to be_truthy
+ expect(response_note_2.reload.confidential).to be_falsey
+ expect(other_note.reload.confidential).to be_falsey
+ end
+ end
+ end
+ end
+
context 'todos' do
shared_examples 'does not update todos' do
it 'keep todos' do
diff --git a/spec/services/notification_recipients/build_service_spec.rb b/spec/services/notification_recipients/build_service_spec.rb
index e203093623d..5c8add250c2 100644
--- a/spec/services/notification_recipients/build_service_spec.rb
+++ b/spec/services/notification_recipients/build_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe NotificationRecipients::BuildService do
+RSpec.describe NotificationRecipients::BuildService do
let(:service) { described_class }
let(:assignee) { create(:user) }
let(:project) { create(:project, :public) }
diff --git a/spec/services/notification_recipients/builder/default_spec.rb b/spec/services/notification_recipients/builder/default_spec.rb
index 307ca40248e..d25410235c2 100644
--- a/spec/services/notification_recipients/builder/default_spec.rb
+++ b/spec/services/notification_recipients/builder/default_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe NotificationRecipients::Builder::Default do
+RSpec.describe NotificationRecipients::Builder::Default do
describe '#build!' do
let_it_be(:group) { create(:group, :public) }
let_it_be(:project) { create(:project, :public, group: group).tap { |p| p.add_developer(project_watcher) } }
diff --git a/spec/services/notification_recipients/builder/new_note_spec.rb b/spec/services/notification_recipients/builder/new_note_spec.rb
index f88e8b2dfb0..7d2a4f682c5 100644
--- a/spec/services/notification_recipients/builder/new_note_spec.rb
+++ b/spec/services/notification_recipients/builder/new_note_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe NotificationRecipients::Builder::NewNote do
+RSpec.describe NotificationRecipients::Builder::NewNote do
describe '#notification_recipients' do
let_it_be(:group) { create(:group, :public) }
let_it_be(:project) { create(:project, :public, group: group) }
diff --git a/spec/services/notification_service_spec.rb b/spec/services/notification_service_spec.rb
index 3c1c3e2dfc3..2fe7a46de4b 100644
--- a/spec/services/notification_service_spec.rb
+++ b/spec/services/notification_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe NotificationService, :mailer do
+RSpec.describe NotificationService, :mailer do
include EmailSpec::Matchers
include ExternalAuthorizationServiceHelpers
include NotificationHelpers
@@ -343,6 +343,79 @@ describe NotificationService, :mailer do
end
end
+ context 'on service desk issue' do
+ before do
+ allow(Notify).to receive(:service_desk_new_note_email)
+ .with(Integer, Integer).and_return(mailer)
+
+ allow(::Gitlab::IncomingEmail).to receive(:enabled?) { true }
+ allow(::Gitlab::IncomingEmail).to receive(:supports_wildcard?) { true }
+ end
+
+ let(:subject) { NotificationService.new }
+ let(:mailer) { double(deliver_later: true) }
+
+ def should_email!
+ expect(Notify).to receive(:service_desk_new_note_email)
+ .with(issue.id, note.id)
+ end
+
+ def should_not_email!
+ expect(Notify).not_to receive(:service_desk_new_note_email)
+ end
+
+ def execute!
+ subject.new_note(note)
+ end
+
+ def self.it_should_email!
+ it 'sends the email' do
+ should_email!
+ execute!
+ end
+ end
+
+ def self.it_should_not_email!
+ it 'doesn\'t send the email' do
+ should_not_email!
+ execute!
+ end
+ end
+
+ let(:issue) { create(:issue, author: User.support_bot) }
+ let(:project) { issue.project }
+ let(:note) { create(:note, noteable: issue, project: project) }
+
+ context 'a non-service-desk issue' do
+ it_should_not_email!
+ end
+
+ context 'a service-desk issue' do
+ before do
+ issue.update!(service_desk_reply_to: 'service.desk@example.com')
+ project.update!(service_desk_enabled: true)
+ end
+
+ it_should_email!
+
+ context 'where the project has disabled the feature' do
+ before do
+ project.update(service_desk_enabled: false)
+ end
+
+ it_should_not_email!
+ end
+
+ context 'when the support bot has unsubscribed' do
+ before do
+ issue.unsubscribe(User.support_bot, project)
+ end
+
+ it_should_not_email!
+ end
+ end
+ end
+
describe 'new note on issue in project that belongs to a group' do
before do
note.project.namespace_id = group.id
@@ -1950,6 +2023,26 @@ describe NotificationService, :mailer do
let(:notification_trigger) { notification.resolve_all_discussions(merge_request, @u_disabled) }
end
end
+
+ describe '#merge_when_pipeline_succeeds' do
+ it 'send notification that merge will happen when pipeline succeeds' do
+ notification.merge_when_pipeline_succeeds(merge_request, assignee)
+ should_email(merge_request.author)
+ should_email(@u_watcher)
+ should_email(@subscriber)
+ end
+
+ it_behaves_like 'participating notifications' do
+ let(:participant) { create(:user, username: 'user-participant') }
+ let(:issuable) { merge_request }
+ let(:notification_trigger) { notification.merge_when_pipeline_succeeds(merge_request, @u_disabled) }
+ end
+
+ it_behaves_like 'project emails are disabled' do
+ let(:notification_target) { merge_request }
+ let(:notification_trigger) { notification.merge_when_pipeline_succeeds(merge_request, @u_disabled) }
+ end
+ end
end
describe 'Projects', :deliver_mails_inline do
diff --git a/spec/services/packages/composer/composer_json_service_spec.rb b/spec/services/packages/composer/composer_json_service_spec.rb
new file mode 100644
index 00000000000..3996fcea679
--- /dev/null
+++ b/spec/services/packages/composer/composer_json_service_spec.rb
@@ -0,0 +1,39 @@
+# frozen_string_literal: true
+require 'spec_helper'
+
+RSpec.describe Packages::Composer::ComposerJsonService do
+ describe '#execute' do
+ let(:branch) { project.repository.find_branch('master') }
+ let(:target) { branch.target }
+
+ subject { described_class.new(project, target).execute }
+
+ context 'with an existing file' do
+ let(:project) { create(:project, :custom_repo, files: { 'composer.json' => json } ) }
+
+ context 'with a valid file' do
+ let(:json) { '{ "name": "package-name"}' }
+
+ it 'returns the parsed json' do
+ expect(subject).to eq({ 'name' => 'package-name' })
+ end
+ end
+
+ context 'with an invalid file' do
+ let(:json) { '{ name": "package-name"}' }
+
+ it 'raises an error' do
+ expect { subject }.to raise_error(/Invalid/)
+ end
+ end
+ end
+
+ context 'without the composer.json file' do
+ let(:project) { create(:project, :repository) }
+
+ it 'raises an error' do
+ expect { subject }.to raise_error(/not found/)
+ end
+ end
+ end
+end
diff --git a/spec/services/packages/composer/create_package_service_spec.rb b/spec/services/packages/composer/create_package_service_spec.rb
new file mode 100644
index 00000000000..3f9da31cf6e
--- /dev/null
+++ b/spec/services/packages/composer/create_package_service_spec.rb
@@ -0,0 +1,97 @@
+# frozen_string_literal: true
+require 'spec_helper'
+
+RSpec.describe Packages::Composer::CreatePackageService do
+ include PackagesManagerApiSpecHelpers
+
+ let_it_be(:package_name) { 'composer-package-name' }
+ let_it_be(:json) { { name: package_name }.to_json }
+ let_it_be(:project) { create(:project, :custom_repo, files: { 'composer.json' => json } ) }
+ let_it_be(:user) { create(:user) }
+ let(:params) do
+ {
+ branch: branch,
+ tag: tag
+ }
+ end
+
+ describe '#execute' do
+ let(:tag) { nil }
+ let(:branch) { nil }
+
+ subject { described_class.new(project, user, params).execute }
+
+ let(:created_package) { Packages::Package.composer.last }
+
+ context 'without an existing package' do
+ context 'with a branch' do
+ let(:branch) { project.repository.find_branch('master') }
+
+ it 'creates the package' do
+ expect { subject }
+ .to change { Packages::Package.composer.count }.by(1)
+ .and change { Packages::Composer::Metadatum.count }.by(1)
+
+ expect(created_package.name).to eq package_name
+ expect(created_package.version).to eq 'dev-master'
+ expect(created_package.composer_metadatum.target_sha).to eq branch.target
+ expect(created_package.composer_metadatum.composer_json.to_json).to eq json
+ end
+ end
+
+ context 'with a tag' do
+ let(:tag) { project.repository.find_tag('v1.2.3') }
+
+ before do
+ project.repository.add_tag(user, 'v1.2.3', 'master')
+ end
+
+ it 'creates the package' do
+ expect { subject }
+ .to change { Packages::Package.composer.count }.by(1)
+ .and change { Packages::Composer::Metadatum.count }.by(1)
+
+ expect(created_package.name).to eq package_name
+ expect(created_package.version).to eq '1.2.3'
+ end
+ end
+ end
+
+ context 'with an existing package' do
+ let(:branch) { project.repository.find_branch('master') }
+
+ context 'belonging to the same project' do
+ before do
+ described_class.new(project, user, params).execute
+ end
+
+ it 'does not create a new package' do
+ expect { subject }
+ .to change { Packages::Package.composer.count }.by(0)
+ .and change { Packages::Composer::Metadatum.count }.by(0)
+ end
+ end
+
+ context 'belonging to another project' do
+ let(:other_project) { create(:project) }
+ let!(:other_package) { create(:composer_package, name: package_name, version: 'dev-master', project: other_project) }
+
+ it 'fails with an error' do
+ expect { subject }
+ .to raise_error(/is already taken/)
+ end
+ end
+
+ context 'same name but of different type' do
+ let(:other_project) { create(:project) }
+ let!(:other_package) { create(:package, name: package_name, version: 'dev-master', project: other_project) }
+
+ it 'creates the package' do
+ expect { subject }
+ .to change { Packages::Package.composer.count }.by(1)
+ .and change { Packages::Composer::Metadatum.count }.by(1)
+ end
+ end
+ end
+ end
+end
diff --git a/spec/services/packages/composer/version_parser_service_spec.rb b/spec/services/packages/composer/version_parser_service_spec.rb
new file mode 100644
index 00000000000..904c75ab0a1
--- /dev/null
+++ b/spec/services/packages/composer/version_parser_service_spec.rb
@@ -0,0 +1,31 @@
+# frozen_string_literal: true
+require 'spec_helper'
+
+RSpec.describe Packages::Composer::VersionParserService do
+ let_it_be(:params) { {} }
+
+ describe '#execute' do
+ using RSpec::Parameterized::TableSyntax
+
+ subject { described_class.new(tag_name: tagname, branch_name: branchname).execute }
+
+ where(:tagname, :branchname, :expected_version) do
+ nil | 'master' | 'dev-master'
+ nil | 'my-feature' | 'dev-my-feature'
+ nil | 'v1' | '1.x-dev'
+ nil | 'v1.x' | '1.x-dev'
+ nil | 'v1.7.x' | '1.7.x-dev'
+ nil | 'v1.7' | '1.7.x-dev'
+ nil | '1.7.x' | '1.7.x-dev'
+ 'v1.0.0' | nil | '1.0.0'
+ 'v1.0' | nil | '1.0'
+ '1.0' | nil | '1.0'
+ '1.0.2' | nil | '1.0.2'
+ '1.0.2-beta2' | nil | '1.0.2-beta2'
+ end
+
+ with_them do
+ it { is_expected.to eq expected_version }
+ end
+ end
+end
diff --git a/spec/services/packages/conan/create_package_file_service_spec.rb b/spec/services/packages/conan/create_package_file_service_spec.rb
new file mode 100644
index 00000000000..0e9cbba5fc1
--- /dev/null
+++ b/spec/services/packages/conan/create_package_file_service_spec.rb
@@ -0,0 +1,130 @@
+# frozen_string_literal: true
+require 'spec_helper'
+
+RSpec.describe Packages::Conan::CreatePackageFileService do
+ include WorkhorseHelpers
+
+ let_it_be(:package) { create(:conan_package) }
+
+ describe '#execute' do
+ let(:file_name) { 'foo.tgz' }
+
+ subject { described_class.new(package, file, params) }
+
+ shared_examples 'a valid package_file' do
+ let(:params) do
+ {
+ file_name: file_name,
+ 'file.md5': '12345',
+ 'file.sha1': '54321',
+ 'file.size': '128',
+ 'file.type': 'txt',
+ recipe_revision: '0',
+ package_revision: '0',
+ conan_package_reference: '123456789',
+ conan_file_type: :package_file
+ }.with_indifferent_access
+ end
+
+ it 'creates a new package file' do
+ package_file = subject.execute
+
+ expect(package_file).to be_valid
+ expect(package_file.file_name).to eq(file_name)
+ expect(package_file.file_md5).to eq('12345')
+ expect(package_file.size).to eq(128)
+ expect(package_file.conan_file_metadatum).to be_valid
+ expect(package_file.conan_file_metadatum.recipe_revision).to eq('0')
+ expect(package_file.conan_file_metadatum.package_revision).to eq('0')
+ expect(package_file.conan_file_metadatum.conan_package_reference).to eq('123456789')
+ expect(package_file.conan_file_metadatum.conan_file_type).to eq('package_file')
+ expect(package_file.file.read).to eq('content')
+ end
+ end
+
+ shared_examples 'a valid recipe_file' do
+ let(:params) do
+ {
+ file_name: file_name,
+ 'file.md5': '12345',
+ 'file.sha1': '54321',
+ 'file.size': '128',
+ 'file.type': 'txt',
+ recipe_revision: '0',
+ conan_file_type: :recipe_file
+ }.with_indifferent_access
+ end
+
+ it 'creates a new recipe file' do
+ package_file = subject.execute
+
+ expect(package_file).to be_valid
+ expect(package_file.file_name).to eq(file_name)
+ expect(package_file.file_md5).to eq('12345')
+ expect(package_file.size).to eq(128)
+ expect(package_file.conan_file_metadatum).to be_valid
+ expect(package_file.conan_file_metadatum.recipe_revision).to eq('0')
+ expect(package_file.conan_file_metadatum.package_revision).to be_nil
+ expect(package_file.conan_file_metadatum.conan_package_reference).to be_nil
+ expect(package_file.conan_file_metadatum.conan_file_type).to eq('recipe_file')
+ expect(package_file.file.read).to eq('content')
+ end
+ end
+
+ context 'with temp file' do
+ let!(:file) do
+ upload_path = ::Packages::PackageFileUploader.workhorse_local_upload_path
+ file_path = upload_path + '/' + file_name
+
+ FileUtils.mkdir_p(upload_path)
+ File.write(file_path, 'content')
+
+ UploadedFile.new(file_path, filename: File.basename(file_path))
+ end
+
+ before do
+ allow_any_instance_of(Packages::PackageFileUploader).to receive(:size).and_return(128)
+ end
+
+ it_behaves_like 'a valid package_file'
+ it_behaves_like 'a valid recipe_file'
+ end
+
+ context 'with remote file' do
+ let!(:fog_connection) do
+ stub_package_file_object_storage(direct_upload: true)
+ end
+
+ before do
+ allow_any_instance_of(Packages::PackageFileUploader).to receive(:size).and_return(128)
+ end
+
+ let(:tmp_object) do
+ fog_connection.directories.new(key: 'packages').files.create(
+ key: "tmp/uploads/#{file_name}",
+ body: 'content'
+ )
+ end
+
+ let(:file) { fog_to_uploaded_file(tmp_object) }
+
+ it_behaves_like 'a valid package_file'
+ it_behaves_like 'a valid recipe_file'
+ end
+
+ context 'file is missing' do
+ let(:file) { nil }
+ let(:params) do
+ {
+ file_name: file_name,
+ recipe_revision: '0',
+ conan_file_type: :recipe_file
+ }
+ end
+
+ it 'raises an error' do
+ expect { subject.execute }.to raise_error(ActiveRecord::RecordInvalid)
+ end
+ end
+ end
+end
diff --git a/spec/services/packages/conan/create_package_service_spec.rb b/spec/services/packages/conan/create_package_service_spec.rb
new file mode 100644
index 00000000000..f8068f6e57b
--- /dev/null
+++ b/spec/services/packages/conan/create_package_service_spec.rb
@@ -0,0 +1,48 @@
+# frozen_string_literal: true
+require 'spec_helper'
+
+RSpec.describe Packages::Conan::CreatePackageService do
+ let_it_be(:project) { create(:project) }
+ let_it_be(:user) { create(:user) }
+
+ subject { described_class.new(project, user, params) }
+
+ describe '#execute' do
+ context 'valid params' do
+ let(:params) do
+ {
+ package_name: 'my-pkg',
+ package_version: '1.0.0',
+ package_username: ::Packages::Conan::Metadatum.package_username_from(full_path: project.full_path),
+ package_channel: 'stable'
+ }
+ end
+
+ it 'creates a new package' do
+ package = subject.execute
+
+ expect(package).to be_valid
+ expect(package.name).to eq(params[:package_name])
+ expect(package.version).to eq(params[:package_version])
+ expect(package.package_type).to eq('conan')
+ expect(package.conan_metadatum.package_username).to eq(params[:package_username])
+ expect(package.conan_metadatum.package_channel).to eq(params[:package_channel])
+ end
+ end
+
+ context 'invalid params' do
+ let(:params) do
+ {
+ package_name: 'my-pkg',
+ package_version: '1.0.0',
+ package_username: 'foo/bar',
+ package_channel: 'stable'
+ }
+ end
+
+ it 'fails' do
+ expect { subject.execute }.to raise_exception(ActiveRecord::RecordInvalid)
+ end
+ end
+ end
+end
diff --git a/spec/services/packages/conan/search_service_spec.rb b/spec/services/packages/conan/search_service_spec.rb
new file mode 100644
index 00000000000..39d284ee088
--- /dev/null
+++ b/spec/services/packages/conan/search_service_spec.rb
@@ -0,0 +1,74 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Packages::Conan::SearchService do
+ let_it_be(:user) { create(:user) }
+ let_it_be(:project) { create(:project, :public) }
+ let!(:conan_package) { create(:conan_package, project: project) }
+ let!(:conan_package2) { create(:conan_package, project: project) }
+
+ subject { described_class.new(user, query: query) }
+
+ before do
+ project.add_developer(user)
+ end
+
+ describe '#execute' do
+ context 'with wildcard' do
+ let(:partial_name) { conan_package.name.first[0, 3] }
+ let(:query) { "#{partial_name}*" }
+
+ it 'makes a wildcard query' do
+ result = subject.execute
+
+ expect(result.status).to eq :success
+ expect(result.payload).to eq(results: [conan_package.conan_recipe, conan_package2.conan_recipe])
+ end
+ end
+
+ context 'with only wildcard' do
+ let(:query) { '*' }
+
+ it 'returns empty' do
+ result = subject.execute
+
+ expect(result.status).to eq :success
+ expect(result.payload).to eq(results: [])
+ end
+ end
+
+ context 'with no wildcard' do
+ let(:query) { conan_package.name }
+
+ it 'makes a search using the beginning of the recipe' do
+ result = subject.execute
+
+ expect(result.status).to eq :success
+ expect(result.payload).to eq(results: [conan_package.conan_recipe])
+ end
+ end
+
+ context 'with full recipe match' do
+ let(:query) { conan_package.conan_recipe }
+
+ it 'makes an exact search' do
+ result = subject.execute
+
+ expect(result.status).to eq :success
+ expect(result.payload).to eq(results: [conan_package.conan_recipe])
+ end
+ end
+
+ context 'with malicious query' do
+ let(:query) { 'DROP TABLE foo;' }
+
+ it 'returns empty' do
+ result = subject.execute
+
+ expect(result.status).to eq :success
+ expect(result.payload).to eq(results: [])
+ end
+ end
+ end
+end
diff --git a/spec/services/packages/create_dependency_service_spec.rb b/spec/services/packages/create_dependency_service_spec.rb
new file mode 100644
index 00000000000..00e5e5c6d96
--- /dev/null
+++ b/spec/services/packages/create_dependency_service_spec.rb
@@ -0,0 +1,113 @@
+# frozen_string_literal: true
+require 'spec_helper'
+
+RSpec.describe Packages::CreateDependencyService do
+ describe '#execute' do
+ let_it_be(:namespace) {create(:namespace)}
+ let_it_be(:version) { '1.0.1' }
+ let_it_be(:package_name) { "@#{namespace.path}/my-app".freeze }
+
+ context 'when packages are published' do
+ let(:json_file) { 'packages/npm/payload.json' }
+ let(:params) do
+ Gitlab::Json.parse(fixture_file(json_file)
+ .gsub('@root/npm-test', package_name)
+ .gsub('1.0.1', version))
+ .with_indifferent_access
+ end
+ let(:package_version) { params[:versions].each_key.first }
+ let(:dependencies) { params[:versions][package_version] }
+ let(:package) { create(:npm_package) }
+ let(:dependency_names) { package.dependency_links.flat_map(&:dependency).map(&:name).sort }
+ let(:dependency_link_types) { package.dependency_links.map(&:dependency_type).sort }
+
+ subject { described_class.new(package, dependencies).execute }
+
+ it 'creates dependencies and links' do
+ expect(Packages::Dependency)
+ .to receive(:ids_for_package_names_and_version_patterns)
+ .once
+ .and_call_original
+
+ expect { subject }
+ .to change { Packages::Dependency.count }.by(1)
+ .and change { Packages::DependencyLink.count }.by(1)
+ expect(dependency_names).to match_array(%w(express))
+ expect(dependency_link_types).to match_array(%w(dependencies))
+ end
+
+ context 'with repeated packages' do
+ let(:json_file) { 'packages/npm/payload_with_duplicated_packages.json' }
+
+ it 'creates dependencies and links' do
+ expect(Packages::Dependency)
+ .to receive(:ids_for_package_names_and_version_patterns)
+ .exactly(4).times
+ .and_call_original
+
+ expect { subject }
+ .to change { Packages::Dependency.count }.by(4)
+ .and change { Packages::DependencyLink.count }.by(6)
+ expect(dependency_names).to match_array(%w(d3 d3 d3 dagre-d3 dagre-d3 express))
+ expect(dependency_link_types).to match_array(%w(bundleDependencies dependencies dependencies devDependencies devDependencies peerDependencies))
+ end
+ end
+
+ context 'with dependencies bulk insert conflicts' do
+ let_it_be(:rows) { [{ name: 'express', version_pattern: '^4.16.4' }] }
+
+ it 'creates dependences and links' do
+ original_bulk_insert = ::Gitlab::Database.method(:bulk_insert)
+ expect(::Gitlab::Database)
+ .to receive(:bulk_insert) do |table, rows, return_ids: false, disable_quote: [], on_conflict: nil|
+ call_count = table == Packages::Dependency.table_name ? 2 : 1
+ call_count.times { original_bulk_insert.call(table, rows, return_ids: return_ids, disable_quote: disable_quote, on_conflict: on_conflict) }
+ end.twice
+ expect(Packages::Dependency)
+ .to receive(:ids_for_package_names_and_version_patterns)
+ .twice
+ .and_call_original
+
+ expect { subject }
+ .to change { Packages::Dependency.count }.by(1)
+ .and change { Packages::DependencyLink.count }.by(1)
+ expect(dependency_names).to match_array(%w(express))
+ expect(dependency_link_types).to match_array(%w(dependencies))
+ end
+ end
+
+ context 'with existing dependencies' do
+ let(:other_package) { create(:npm_package) }
+
+ before do
+ described_class.new(other_package, dependencies).execute
+ end
+
+ it 'reuses them' do
+ expect { subject }
+ .to not_change { Packages::Dependency.count }
+ .and change { Packages::DependencyLink.count }.by(1)
+ end
+ end
+
+ context 'with a dependency not described with a hash' do
+ let(:invalid_dependencies) { dependencies.tap { |d| d['bundleDependencies'] = false } }
+
+ subject { described_class.new(package, invalid_dependencies).execute }
+
+ it 'creates dependencies and links' do
+ expect(Packages::Dependency)
+ .to receive(:ids_for_package_names_and_version_patterns)
+ .once
+ .and_call_original
+
+ expect { subject }
+ .to change { Packages::Dependency.count }.by(1)
+ .and change { Packages::DependencyLink.count }.by(1)
+ expect(dependency_names).to match_array(%w(express))
+ expect(dependency_link_types).to match_array(%w(dependencies))
+ end
+ end
+ end
+ end
+end
diff --git a/spec/services/packages/create_package_file_service_spec.rb b/spec/services/packages/create_package_file_service_spec.rb
new file mode 100644
index 00000000000..93dde54916a
--- /dev/null
+++ b/spec/services/packages/create_package_file_service_spec.rb
@@ -0,0 +1,38 @@
+# frozen_string_literal: true
+require 'spec_helper'
+
+RSpec.describe Packages::CreatePackageFileService do
+ let(:package) { create(:maven_package) }
+
+ describe '#execute' do
+ context 'with valid params' do
+ let(:params) do
+ {
+ file: Tempfile.new,
+ file_name: 'foo.jar'
+ }
+ end
+
+ it 'creates a new package file' do
+ package_file = described_class.new(package, params).execute
+
+ expect(package_file).to be_valid
+ expect(package_file.file_name).to eq('foo.jar')
+ end
+ end
+
+ context 'file is missing' do
+ let(:params) do
+ {
+ file_name: 'foo.jar'
+ }
+ end
+
+ it 'raises an error' do
+ service = described_class.new(package, params)
+
+ expect { service.execute }.to raise_error(ActiveRecord::RecordInvalid)
+ end
+ end
+ end
+end
diff --git a/spec/services/packages/maven/create_package_service_spec.rb b/spec/services/packages/maven/create_package_service_spec.rb
new file mode 100644
index 00000000000..bfdf62008ba
--- /dev/null
+++ b/spec/services/packages/maven/create_package_service_spec.rb
@@ -0,0 +1,77 @@
+# frozen_string_literal: true
+require 'spec_helper'
+
+RSpec.describe Packages::Maven::CreatePackageService do
+ let(:project) { create(:project) }
+ let(:user) { create(:user) }
+ let(:app_name) { 'my-app' }
+ let(:version) { '1.0-SNAPSHOT' }
+ let(:path) { "my/company/app/#{app_name}" }
+ let(:path_with_version) { "#{path}/#{version}" }
+
+ describe '#execute' do
+ subject(:package) { described_class.new(project, user, params).execute }
+
+ context 'with version' do
+ let(:params) do
+ {
+ path: path_with_version,
+ name: path,
+ version: version
+ }
+ end
+
+ it 'creates a new package with metadatum' do
+ expect(package).to be_valid
+ expect(package.name).to eq(path)
+ expect(package.version).to eq(version)
+ expect(package.package_type).to eq('maven')
+ expect(package.maven_metadatum).to be_valid
+ expect(package.maven_metadatum.path).to eq(path_with_version)
+ expect(package.maven_metadatum.app_group).to eq('my.company.app')
+ expect(package.maven_metadatum.app_name).to eq(app_name)
+ expect(package.maven_metadatum.app_version).to eq(version)
+ end
+
+ it_behaves_like 'assigns build to package'
+ end
+
+ context 'without version' do
+ let(:params) do
+ {
+ path: path,
+ name: path,
+ version: nil
+ }
+ end
+
+ it 'creates a new package with metadatum' do
+ package = described_class.new(project, user, params).execute
+
+ expect(package).to be_valid
+ expect(package.name).to eq(path)
+ expect(package.version).to be nil
+ expect(package.maven_metadatum).to be_valid
+ expect(package.maven_metadatum.path).to eq(path)
+ expect(package.maven_metadatum.app_group).to eq('my.company.app')
+ expect(package.maven_metadatum.app_name).to eq(app_name)
+ expect(package.maven_metadatum.app_version).to be nil
+ end
+ end
+
+ context 'path is missing' do
+ let(:params) do
+ {
+ name: path,
+ version: version
+ }
+ end
+
+ it 'raises an error' do
+ service = described_class.new(project, user, params)
+
+ expect { service.execute }.to raise_error(ActiveRecord::RecordInvalid)
+ end
+ end
+ end
+end
diff --git a/spec/services/packages/maven/find_or_create_package_service_spec.rb b/spec/services/packages/maven/find_or_create_package_service_spec.rb
new file mode 100644
index 00000000000..c9441324216
--- /dev/null
+++ b/spec/services/packages/maven/find_or_create_package_service_spec.rb
@@ -0,0 +1,38 @@
+# frozen_string_literal: true
+require 'spec_helper'
+
+RSpec.describe Packages::Maven::FindOrCreatePackageService do
+ let_it_be(:project) { create(:project) }
+ let_it_be(:user) { create(:user) }
+ let_it_be(:app_name) { 'my-app' }
+ let_it_be(:version) { '1.0-SNAPSHOT' }
+ let_it_be(:path) { "my/company/app/#{app_name}" }
+ let_it_be(:path_with_version) { "#{path}/#{version}" }
+ let_it_be(:params) do
+ {
+ path: path_with_version,
+ name: path,
+ version: version
+ }
+ end
+
+ describe '#execute' do
+ subject { described_class.new(project, user, params).execute }
+
+ context 'without any existing package' do
+ it 'creates a package' do
+ expect { subject }.to change { Packages::Package.count }.by(1)
+ end
+ end
+
+ context 'with an existing package' do
+ let_it_be(:existing_package) { create(:maven_package, name: path, version: version, project: project) }
+
+ it { is_expected.to eq existing_package }
+ it "doesn't create a new package" do
+ expect { subject }
+ .to not_change { Packages::Package.count }
+ end
+ end
+ end
+end
diff --git a/spec/services/packages/npm/create_package_service_spec.rb b/spec/services/packages/npm/create_package_service_spec.rb
new file mode 100644
index 00000000000..25bbbf82bec
--- /dev/null
+++ b/spec/services/packages/npm/create_package_service_spec.rb
@@ -0,0 +1,96 @@
+# frozen_string_literal: true
+require 'spec_helper'
+
+RSpec.describe Packages::Npm::CreatePackageService do
+ let(:namespace) {create(:namespace)}
+ let(:project) { create(:project, namespace: namespace) }
+ let(:user) { create(:user) }
+ let(:version) { '1.0.1' }
+
+ let(:params) do
+ Gitlab::Json.parse(fixture_file('packages/npm/payload.json')
+ .gsub('@root/npm-test', package_name)
+ .gsub('1.0.1', version)).with_indifferent_access
+ .merge!(override)
+ end
+ let(:override) { {} }
+ let(:package_name) { "@#{namespace.path}/my-app".freeze }
+
+ subject { described_class.new(project, user, params).execute }
+
+ shared_examples 'valid package' do
+ it 'creates a package' do
+ expect { subject }
+ .to change { Packages::Package.count }.by(1)
+ .and change { Packages::Package.npm.count }.by(1)
+ .and change { Packages::Tag.count }.by(1)
+ end
+
+ it { is_expected.to be_valid }
+
+ it 'creates a package with name and version' do
+ package = subject
+
+ expect(package.name).to eq(package_name)
+ expect(package.version).to eq(version)
+ end
+
+ it { expect(subject.name).to eq(package_name) }
+ it { expect(subject.version).to eq(version) }
+ end
+
+ describe '#execute' do
+ context 'scoped package' do
+ it_behaves_like 'valid package'
+
+ it_behaves_like 'assigns build to package'
+ end
+
+ context 'invalid package name' do
+ let(:package_name) { "@#{namespace.path}/my-group/my-app".freeze }
+
+ it { expect { subject }.to raise_error(ActiveRecord::RecordInvalid) }
+ end
+
+ context 'package already exists' do
+ let(:package_name) { "@#{namespace.path}/my_package" }
+ let!(:existing_package) { create(:npm_package, project: project, name: package_name, version: '1.0.1') }
+
+ it { expect(subject[:http_status]).to eq 403 }
+ it { expect(subject[:message]).to be 'Package already exists.' }
+ end
+
+ context 'with incorrect namespace' do
+ let(:package_name) { '@my_other_namespace/my-app' }
+
+ it 'raises a RecordInvalid error' do
+ expect { subject }.to raise_error(ActiveRecord::RecordInvalid)
+ end
+ end
+
+ context 'with empty versions' do
+ let(:override) { { versions: {} } }
+
+ it { expect(subject[:http_status]).to eq 400 }
+ it { expect(subject[:message]).to eq 'Version is empty.' }
+ end
+
+ context 'with invalid versions' do
+ using RSpec::Parameterized::TableSyntax
+
+ where(:version) do
+ [
+ '1',
+ '1.2',
+ '1./2.3',
+ '../../../../../1.2.3',
+ '%2e%2e%2f1.2.3'
+ ]
+ end
+
+ with_them do
+ it { expect { subject }.to raise_error(ActiveRecord::RecordInvalid, 'Validation failed: Version is invalid') }
+ end
+ end
+ end
+end
diff --git a/spec/services/packages/npm/create_tag_service_spec.rb b/spec/services/packages/npm/create_tag_service_spec.rb
new file mode 100644
index 00000000000..e7a784068fa
--- /dev/null
+++ b/spec/services/packages/npm/create_tag_service_spec.rb
@@ -0,0 +1,53 @@
+# frozen_string_literal: true
+require 'spec_helper'
+
+RSpec.describe Packages::Npm::CreateTagService do
+ let(:package) { create(:npm_package) }
+ let(:tag_name) { 'test-tag' }
+
+ describe '#execute' do
+ subject { described_class.new(package, tag_name).execute }
+
+ shared_examples 'it creates the tag' do
+ it { expect { subject }.to change { Packages::Tag.count }.by(1) }
+ it { expect(subject.name).to eq(tag_name) }
+ it 'adds tag to the package' do
+ tag = subject
+ expect(package.reload.tags).to match_array([tag])
+ end
+ end
+
+ context 'with no existing tag name' do
+ it_behaves_like 'it creates the tag'
+ end
+
+ context 'with exisiting tag name' do
+ let!(:package_tag2) { create(:packages_tag, package: package2, name: tag_name) }
+
+ context 'on package with different name' do
+ let!(:package2) { create(:npm_package, project: package.project) }
+
+ it_behaves_like 'it creates the tag'
+ end
+
+ context 'on different package type' do
+ let!(:package2) { create(:conan_package, project: package.project, name: 'conan_package_name', version: package.version) }
+
+ it_behaves_like 'it creates the tag'
+ end
+
+ context 'on same package with different version' do
+ let!(:package2) { create(:npm_package, project: package.project, name: package.name, version: '5.0.0-testing') }
+
+ it { expect { subject }.to not_change { Packages::Tag.count } }
+ it { expect(subject.name).to eq(tag_name) }
+
+ it 'adds tag to the package' do
+ tag = subject
+ expect(package.reload.tags).to match_array([tag])
+ expect(package2.reload.tags).to be_empty
+ end
+ end
+ end
+ end
+end
diff --git a/spec/services/packages/nuget/create_dependency_service_spec.rb b/spec/services/packages/nuget/create_dependency_service_spec.rb
new file mode 100644
index 00000000000..268c8837e25
--- /dev/null
+++ b/spec/services/packages/nuget/create_dependency_service_spec.rb
@@ -0,0 +1,76 @@
+# frozen_string_literal: true
+require 'spec_helper'
+
+RSpec.describe Packages::Nuget::CreateDependencyService do
+ let_it_be(:package, reload: true) { create(:nuget_package) }
+
+ describe '#execute' do
+ RSpec.shared_examples 'creating dependencies, links and nuget metadata for' do |expected_dependency_names, dependency_count, dependency_link_count|
+ let(:dependencies_with_metadata) { dependencies.select { |dep| dep[:target_framework].present? } }
+
+ it 'creates dependencies, links and nuget metadata' do
+ expect { subject }
+ .to change { Packages::Dependency.count }.by(dependency_count)
+ .and change { Packages::DependencyLink.count }.by(dependency_link_count)
+ .and change { Packages::Nuget::DependencyLinkMetadatum.count }.by(dependencies_with_metadata.size)
+ expect(expected_dependency_names).to contain_exactly(*dependency_names)
+ expect(package.dependency_links.map(&:dependency_type).uniq).to contain_exactly('dependencies')
+
+ dependencies_with_metadata.each do |dependency|
+ name = dependency[:name]
+ version_pattern = service.send(:version_or_empty_string, dependency[:version])
+ metadatum = package.dependency_links.joins(:dependency)
+ .find_by(packages_dependencies: { name: name, version_pattern: version_pattern })
+ .nuget_metadatum
+ expect(metadatum.target_framework).to eq dependency[:target_framework]
+ end
+ end
+ end
+
+ let_it_be(:dependencies) do
+ [
+ { name: 'Moqi', version: '2.5.6' },
+ { name: 'Castle.Core' },
+ { name: 'Test.Dependency', version: '2.3.7', target_framework: '.NETStandard2.0' },
+ { name: 'Newtonsoft.Json', version: '12.0.3', target_framework: '.NETStandard2.0' }
+ ]
+ end
+
+ let(:dependency_names) { package.dependency_links.flat_map(&:dependency).map(&:name) }
+ let(:service) { described_class.new(package, dependencies) }
+
+ subject { service.execute }
+
+ it_behaves_like 'creating dependencies, links and nuget metadata for', %w(Castle.Core Moqi Newtonsoft.Json Test.Dependency), 4, 4
+
+ context 'with existing dependencies' do
+ let_it_be(:exisiting_dependency) { create(:packages_dependency, name: 'Moqi', version_pattern: '2.5.6') }
+
+ it_behaves_like 'creating dependencies, links and nuget metadata for', %w(Castle.Core Moqi Newtonsoft.Json Test.Dependency), 3, 4
+ end
+
+ context 'with dependencies with no target framework' do
+ let_it_be(:dependencies) do
+ [
+ { name: 'Moqi', version: '2.5.6' },
+ { name: 'Castle.Core' },
+ { name: 'Test.Dependency', version: '2.3.7' },
+ { name: 'Newtonsoft.Json', version: '12.0.3' }
+ ]
+ end
+
+ it_behaves_like 'creating dependencies, links and nuget metadata for', %w(Castle.Core Moqi Newtonsoft.Json Test.Dependency), 4, 4
+ end
+
+ context 'with empty dependencies' do
+ let_it_be(:dependencies) { [] }
+
+ it 'is a no op' do
+ expect(service).not_to receive(:create_dependency_links)
+ expect(service).not_to receive(:create_dependency_link_metadata)
+
+ subject
+ end
+ end
+ end
+end
diff --git a/spec/services/packages/nuget/create_package_service_spec.rb b/spec/services/packages/nuget/create_package_service_spec.rb
new file mode 100644
index 00000000000..1579b42d9ad
--- /dev/null
+++ b/spec/services/packages/nuget/create_package_service_spec.rb
@@ -0,0 +1,34 @@
+# frozen_string_literal: true
+require 'spec_helper'
+
+RSpec.describe Packages::Nuget::CreatePackageService do
+ let_it_be(:project) { create(:project) }
+ let_it_be(:user) { create(:user) }
+ let_it_be(:params) { {} }
+
+ describe '#execute' do
+ subject { described_class.new(project, user, params).execute }
+
+ it 'creates the package' do
+ expect { subject }.to change { Packages::Package.count }.by(1)
+ package = Packages::Package.last
+
+ expect(package).to be_valid
+ expect(package.name).to eq(Packages::Nuget::CreatePackageService::TEMPORARY_PACKAGE_NAME)
+ expect(package.version).to start_with(Packages::Nuget::CreatePackageService::PACKAGE_VERSION)
+ expect(package.package_type).to eq('nuget')
+ end
+
+ it 'can create two packages in a row' do
+ expect { subject }.to change { Packages::Package.count }.by(1)
+ expect { described_class.new(project, user, params).execute }.to change { Packages::Package.count }.by(1)
+
+ package = Packages::Package.last
+
+ expect(package).to be_valid
+ expect(package.name).to eq(Packages::Nuget::CreatePackageService::TEMPORARY_PACKAGE_NAME)
+ expect(package.version).to start_with(Packages::Nuget::CreatePackageService::PACKAGE_VERSION)
+ expect(package.package_type).to eq('nuget')
+ end
+ end
+end
diff --git a/spec/services/packages/nuget/metadata_extraction_service_spec.rb b/spec/services/packages/nuget/metadata_extraction_service_spec.rb
new file mode 100644
index 00000000000..39fc0f9e6a1
--- /dev/null
+++ b/spec/services/packages/nuget/metadata_extraction_service_spec.rb
@@ -0,0 +1,106 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Packages::Nuget::MetadataExtractionService do
+ let(:package_file) { create(:nuget_package).package_files.first }
+ let(:service) { described_class.new(package_file.id) }
+
+ describe '#execute' do
+ subject { service.execute }
+
+ context 'with valid package file id' do
+ expected_metadata = {
+ package_name: 'DummyProject.DummyPackage',
+ package_version: '1.0.0',
+ package_dependencies: [
+ {
+ name: 'Newtonsoft.Json',
+ target_framework: '.NETCoreApp3.0',
+ version: '12.0.3'
+ }
+ ],
+ package_tags: []
+ }
+
+ it { is_expected.to eq(expected_metadata) }
+ end
+
+ context 'with nuspec file' do
+ before do
+ allow(service).to receive(:nuspec_file).and_return(fixture_file(nuspec_filepath))
+ end
+
+ context 'with dependencies' do
+ let(:nuspec_filepath) { 'packages/nuget/with_dependencies.nuspec' }
+
+ it { is_expected.to have_key(:package_dependencies) }
+
+ it 'extracts dependencies' do
+ dependencies = subject[:package_dependencies]
+
+ expect(dependencies).to include(name: 'Moqi', version: '2.5.6')
+ expect(dependencies).to include(name: 'Castle.Core')
+ expect(dependencies).to include(name: 'Test.Dependency', version: '2.3.7', target_framework: '.NETStandard2.0')
+ expect(dependencies).to include(name: 'Newtonsoft.Json', version: '12.0.3', target_framework: '.NETStandard2.0')
+ end
+ end
+
+ context 'with a nuspec file with metadata' do
+ let(:nuspec_filepath) { 'packages/nuget/with_metadata.nuspec' }
+
+ it { expect(subject[:package_tags].sort).to eq(%w(foo bar test tag1 tag2 tag3 tag4 tag5).sort) }
+ end
+ end
+
+ context 'with a nuspec file with metadata' do
+ let_it_be(:nuspec_filepath) { 'packages/nuget/with_metadata.nuspec' }
+
+ before do
+ allow(service).to receive(:nuspec_file).and_return(fixture_file(nuspec_filepath))
+ end
+
+ it { expect(subject[:license_url]).to eq('https://opensource.org/licenses/MIT') }
+ it { expect(subject[:project_url]).to eq('https://gitlab.com/gitlab-org/gitlab') }
+ it { expect(subject[:icon_url]).to eq('https://opensource.org/files/osi_keyhole_300X300_90ppi_0.png') }
+ end
+
+ context 'with invalid package file id' do
+ let(:package_file) { OpenStruct.new(id: 555) }
+
+ it { expect { subject }.to raise_error(::Packages::Nuget::MetadataExtractionService::ExtractionError, 'invalid package file') }
+ end
+
+ context 'linked to a non nuget package' do
+ before do
+ package_file.package.maven!
+ end
+
+ it { expect { subject }.to raise_error(::Packages::Nuget::MetadataExtractionService::ExtractionError, 'invalid package file') }
+ end
+
+ context 'with a 0 byte package file id' do
+ before do
+ allow_any_instance_of(Packages::PackageFileUploader).to receive(:size).and_return(0)
+ end
+
+ it { expect { subject }.to raise_error(::Packages::Nuget::MetadataExtractionService::ExtractionError, 'invalid package file') }
+ end
+
+ context 'without the nuspec file' do
+ before do
+ allow_any_instance_of(Zip::File).to receive(:glob).and_return([])
+ end
+
+ it { expect { subject }.to raise_error(::Packages::Nuget::MetadataExtractionService::ExtractionError, 'nuspec file not found') }
+ end
+
+ context 'with a too big nuspec file' do
+ before do
+ allow_any_instance_of(Zip::File).to receive(:glob).and_return([OpenStruct.new(size: 6.megabytes)])
+ end
+
+ it { expect { subject }.to raise_error(::Packages::Nuget::MetadataExtractionService::ExtractionError, 'nuspec file too big') }
+ end
+ end
+end
diff --git a/spec/services/packages/nuget/search_service_spec.rb b/spec/services/packages/nuget/search_service_spec.rb
new file mode 100644
index 00000000000..d163e7087e4
--- /dev/null
+++ b/spec/services/packages/nuget/search_service_spec.rb
@@ -0,0 +1,116 @@
+# frozen_string_literal: true
+require 'spec_helper'
+
+RSpec.describe Packages::Nuget::SearchService do
+ let_it_be(:project) { create(:project) }
+ let_it_be(:package_a) { create(:nuget_package, project: project, name: 'DummyPackageA') }
+ let_it_be(:packages_b) { create_list(:nuget_package, 5, project: project, name: 'DummyPackageB') }
+ let_it_be(:packages_c) { create_list(:nuget_package, 5, project: project, name: 'DummyPackageC') }
+ let_it_be(:package_d) { create(:nuget_package, project: project, name: 'FooBarD') }
+ let_it_be(:other_package_a) { create(:nuget_package, name: 'DummyPackageA') }
+ let_it_be(:other_package_a) { create(:nuget_package, name: 'DummyPackageB') }
+ let(:search_term) { 'ummy' }
+ let(:per_page) { 5 }
+ let(:padding) { 0 }
+ let(:include_prerelease_versions) { true }
+ let(:options) { { include_prerelease_versions: include_prerelease_versions, per_page: per_page, padding: padding } }
+
+ describe '#execute' do
+ subject { described_class.new(project, search_term, options).execute }
+
+ it { expect_search_results 3, package_a, packages_b, packages_c }
+
+ context 'with a smaller per page count' do
+ let(:per_page) { 2 }
+
+ it { expect_search_results 3, package_a, packages_b }
+ end
+
+ context 'with 0 per page count' do
+ let(:per_page) { 0 }
+
+ it { expect_search_results 3, [] }
+ end
+
+ context 'with a negative per page count' do
+ let(:per_page) { -1 }
+
+ it { expect { subject }.to raise_error(ArgumentError, 'negative per_page') }
+ end
+
+ context 'with a padding' do
+ let(:padding) { 2 }
+
+ it { expect_search_results 3, packages_c }
+ end
+
+ context 'with a too big padding' do
+ let(:padding) { 5 }
+
+ it { expect_search_results 3, [] }
+ end
+
+ context 'with a negative padding' do
+ let(:padding) { -1 }
+
+ it { expect { subject }.to raise_error(ArgumentError, 'negative padding') }
+ end
+
+ context 'with search term' do
+ let(:search_term) { 'umm' }
+
+ it { expect_search_results 3, package_a, packages_b, packages_c }
+ end
+
+ context 'with nil search term' do
+ let(:search_term) { nil }
+
+ it { expect_search_results 4, package_a, packages_b, packages_c, package_d }
+ end
+
+ context 'with empty search term' do
+ let(:search_term) { '' }
+
+ it { expect_search_results 4, package_a, packages_b, packages_c, package_d }
+ end
+
+ context 'with prefix search term' do
+ let(:search_term) { 'dummy' }
+
+ it { expect_search_results 3, package_a, packages_b, packages_c }
+ end
+
+ context 'with suffix search term' do
+ let(:search_term) { 'packagec' }
+
+ it { expect_search_results 1, packages_c }
+ end
+
+ context 'with pre release packages' do
+ let_it_be(:package_e) { create(:nuget_package, project: project, name: 'DummyPackageE', version: '3.2.1-alpha') }
+
+ context 'including them' do
+ it { expect_search_results 4, package_a, packages_b, packages_c, package_e }
+ end
+
+ context 'excluding them' do
+ let(:include_prerelease_versions) { false }
+
+ it { expect_search_results 3, package_a, packages_b, packages_c }
+
+ context 'when mixed with release versions' do
+ let_it_be(:package_e_release) { create(:nuget_package, project: project, name: 'DummyPackageE', version: '3.2.1') }
+
+ it { expect_search_results 4, package_a, packages_b, packages_c, package_e_release }
+ end
+ end
+ end
+
+ def expect_search_results(total_count, *results)
+ search = subject
+
+ expect(search.total_count).to eq total_count
+ expect(search.results).to match_array(Array.wrap(results).flatten)
+ end
+ end
+end
diff --git a/spec/services/packages/nuget/sync_metadatum_service_spec.rb b/spec/services/packages/nuget/sync_metadatum_service_spec.rb
new file mode 100644
index 00000000000..32093c48b76
--- /dev/null
+++ b/spec/services/packages/nuget/sync_metadatum_service_spec.rb
@@ -0,0 +1,57 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Packages::Nuget::SyncMetadatumService do
+ let_it_be(:package, reload: true) { create(:nuget_package) }
+ let_it_be(:metadata) do
+ {
+ project_url: 'https://test.org/test',
+ license_url: 'https://test.org/MIT',
+ icon_url: 'https://test.org/icon.png'
+ }
+ end
+
+ let(:service) { described_class.new(package, metadata) }
+ let(:nuget_metadatum) { package.nuget_metadatum }
+
+ describe '#execute' do
+ subject { service.execute }
+
+ RSpec.shared_examples 'saving metadatum attributes' do
+ it 'saves nuget metadatum' do
+ subject
+
+ metadata.each do |attribute, expected_value|
+ expect(nuget_metadatum.send(attribute)).to eq(expected_value)
+ end
+ end
+ end
+
+ it 'creates a nuget metadatum' do
+ expect { subject }
+ .to change { package.nuget_metadatum.present? }.from(false).to(true)
+ end
+
+ it_behaves_like 'saving metadatum attributes'
+
+ context 'with exisiting nuget metadatum' do
+ let_it_be(:package) { create(:nuget_package, :with_metadatum) }
+
+ it 'does not create a nuget metadatum' do
+ expect { subject }.to change { ::Packages::Nuget::Metadatum.count }.by(0)
+ end
+
+ it_behaves_like 'saving metadatum attributes'
+
+ context 'with empty metadata' do
+ let_it_be(:metadata) { {} }
+
+ it 'destroys the nuget metadatum' do
+ expect { subject }
+ .to change { package.reload.nuget_metadatum.present? }.from(true).to(false)
+ end
+ end
+ end
+ end
+end
diff --git a/spec/services/packages/nuget/update_package_from_metadata_service_spec.rb b/spec/services/packages/nuget/update_package_from_metadata_service_spec.rb
new file mode 100644
index 00000000000..b7c780c1ee2
--- /dev/null
+++ b/spec/services/packages/nuget/update_package_from_metadata_service_spec.rb
@@ -0,0 +1,237 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Packages::Nuget::UpdatePackageFromMetadataService, :clean_gitlab_redis_shared_state do
+ include ExclusiveLeaseHelpers
+
+ let(:package) { create(:nuget_package) }
+ let(:package_file) { package.package_files.first }
+ let(:service) { described_class.new(package_file) }
+ let(:package_name) { 'DummyProject.DummyPackage' }
+ let(:package_version) { '1.0.0' }
+ let(:package_file_name) { 'dummyproject.dummypackage.1.0.0.nupkg' }
+
+ RSpec.shared_examples 'raising an' do |error_class|
+ it "raises an #{error_class}" do
+ expect { subject }.to raise_error(error_class)
+ end
+ end
+
+ describe '#execute' do
+ subject { service.execute }
+
+ before do
+ stub_package_file_object_storage(enabled: true, direct_upload: true)
+ end
+
+ RSpec.shared_examples 'taking the lease' do
+ before do
+ allow(service).to receive(:lease_release?).and_return(false)
+ end
+
+ it 'takes the lease' do
+ expect(service).to receive(:try_obtain_lease).and_call_original
+
+ subject
+
+ expect(service.exclusive_lease.exists?).to be_truthy
+ end
+ end
+
+ RSpec.shared_examples 'not updating the package if the lease is taken' do
+ context 'without obtaining the exclusive lease' do
+ let(:lease_key) { "packages:nuget:update_package_from_metadata_service:package:#{package_id}" }
+ let(:metadata) { { package_name: package_name, package_version: package_version } }
+ let(:package_from_package_file) { package_file.package }
+
+ before do
+ stub_exclusive_lease_taken(lease_key, timeout: 1.hour)
+ # to allow the above stub, we need to stub the metadata function as the
+ # original implementation will try to get an exclusive lease on the
+ # file in object storage
+ allow(service).to receive(:metadata).and_return(metadata)
+ end
+
+ it 'does not update the package' do
+ expect(service).to receive(:try_obtain_lease).and_call_original
+
+ expect { subject }
+ .to change { ::Packages::Package.count }.by(0)
+ .and change { Packages::DependencyLink.count }.by(0)
+ expect(package_file.reload.file_name).not_to eq(package_file_name)
+ expect(package_file.package.reload.name).not_to eq(package_name)
+ expect(package_file.package.version).not_to eq(package_version)
+ end
+ end
+ end
+
+ context 'with no existing package' do
+ let(:package_id) { package.id }
+
+ it 'updates package and package file' do
+ expect { subject }
+ .to change { ::Packages::Package.count }.by(1)
+ .and change { Packages::Dependency.count }.by(1)
+ .and change { Packages::DependencyLink.count }.by(1)
+ .and change { ::Packages::Nuget::Metadatum.count }.by(0)
+
+ expect(package.reload.name).to eq(package_name)
+ expect(package.version).to eq(package_version)
+ expect(package_file.reload.file_name).to eq(package_file_name)
+ # hard reset needed to properly reload package_file.file
+ expect(Packages::PackageFile.find(package_file.id).file.size).not_to eq 0
+ end
+
+ it_behaves_like 'taking the lease'
+
+ it_behaves_like 'not updating the package if the lease is taken'
+ end
+
+ context 'with existing package' do
+ let!(:existing_package) { create(:nuget_package, project: package.project, name: package_name, version: package_version) }
+ let(:package_id) { existing_package.id }
+
+ it 'link existing package and updates package file' do
+ expect(service).to receive(:try_obtain_lease).and_call_original
+
+ expect { subject }
+ .to change { ::Packages::Package.count }.by(-1)
+ .and change { Packages::Dependency.count }.by(0)
+ .and change { Packages::DependencyLink.count }.by(0)
+ .and change { Packages::Nuget::DependencyLinkMetadatum.count }.by(0)
+ .and change { ::Packages::Nuget::Metadatum.count }.by(0)
+ expect(package_file.reload.file_name).to eq(package_file_name)
+ expect(package_file.package).to eq(existing_package)
+ end
+
+ it_behaves_like 'taking the lease'
+
+ it_behaves_like 'not updating the package if the lease is taken'
+ end
+
+ context 'with a nuspec file with metadata' do
+ let(:nuspec_filepath) { 'packages/nuget/with_metadata.nuspec' }
+ let(:expected_tags) { %w(foo bar test tag1 tag2 tag3 tag4 tag5) }
+
+ before do
+ allow_any_instance_of(Packages::Nuget::MetadataExtractionService)
+ .to receive(:nuspec_file)
+ .and_return(fixture_file(nuspec_filepath))
+ end
+
+ it 'creates tags' do
+ expect(service).to receive(:try_obtain_lease).and_call_original
+ expect { subject }.to change { ::Packages::Tag.count }.by(8)
+ expect(package.reload.tags.map(&:name)).to contain_exactly(*expected_tags)
+ end
+
+ context 'with existing package and tags' do
+ let!(:existing_package) { create(:nuget_package, project: package.project, name: 'DummyProject.WithMetadata', version: '1.2.3') }
+ let!(:tag1) { create(:packages_tag, package: existing_package, name: 'tag1') }
+ let!(:tag2) { create(:packages_tag, package: existing_package, name: 'tag2') }
+ let!(:tag3) { create(:packages_tag, package: existing_package, name: 'tag_not_in_metadata') }
+
+ it 'creates tags and deletes those not in metadata' do
+ expect(service).to receive(:try_obtain_lease).and_call_original
+ expect { subject }.to change { ::Packages::Tag.count }.by(5)
+ expect(existing_package.tags.map(&:name)).to contain_exactly(*expected_tags)
+ end
+ end
+
+ it 'creates nuget metadatum' do
+ expect { subject }
+ .to change { ::Packages::Package.count }.by(1)
+ .and change { ::Packages::Nuget::Metadatum.count }.by(1)
+
+ metadatum = package_file.reload.package.nuget_metadatum
+ expect(metadatum.license_url).to eq('https://opensource.org/licenses/MIT')
+ expect(metadatum.project_url).to eq('https://gitlab.com/gitlab-org/gitlab')
+ expect(metadatum.icon_url).to eq('https://opensource.org/files/osi_keyhole_300X300_90ppi_0.png')
+ end
+
+ context 'with too long url' do
+ let_it_be(:too_long_url) { "http://localhost/#{'bananas' * 50}" }
+
+ let(:metadata) { { package_name: package_name, package_version: package_version, license_url: too_long_url } }
+
+ before do
+ allow(service).to receive(:metadata).and_return(metadata)
+ end
+
+ it_behaves_like 'raising an', ::Packages::Nuget::UpdatePackageFromMetadataService::InvalidMetadataError
+ end
+ end
+
+ context 'with nuspec file with dependencies' do
+ let(:nuspec_filepath) { 'packages/nuget/with_dependencies.nuspec' }
+ let(:package_name) { 'Test.Package' }
+ let(:package_version) { '3.5.2' }
+ let(:package_file_name) { 'test.package.3.5.2.nupkg' }
+
+ before do
+ allow_any_instance_of(Packages::Nuget::MetadataExtractionService)
+ .to receive(:nuspec_file)
+ .and_return(fixture_file(nuspec_filepath))
+ end
+
+ it 'updates package and package file' do
+ expect { subject }
+ .to change { ::Packages::Package.count }.by(1)
+ .and change { Packages::Dependency.count }.by(4)
+ .and change { Packages::DependencyLink.count }.by(4)
+ .and change { Packages::Nuget::DependencyLinkMetadatum.count }.by(2)
+
+ expect(package.reload.name).to eq(package_name)
+ expect(package.version).to eq(package_version)
+ expect(package_file.reload.file_name).to eq(package_file_name)
+ # hard reset needed to properly reload package_file.file
+ expect(Packages::PackageFile.find(package_file.id).file.size).not_to eq 0
+ end
+ end
+
+ context 'with package file not containing a nuspec file' do
+ before do
+ allow_any_instance_of(Zip::File).to receive(:glob).and_return([])
+ end
+
+ it_behaves_like 'raising an', ::Packages::Nuget::MetadataExtractionService::ExtractionError
+ end
+
+ context 'with package file with a blank package name' do
+ before do
+ allow(service).to receive(:package_name).and_return('')
+ end
+
+ it_behaves_like 'raising an', ::Packages::Nuget::UpdatePackageFromMetadataService::InvalidMetadataError
+ end
+
+ context 'with package file with a blank package version' do
+ before do
+ allow(service).to receive(:package_version).and_return('')
+ end
+
+ it_behaves_like 'raising an', ::Packages::Nuget::UpdatePackageFromMetadataService::InvalidMetadataError
+ end
+
+ context 'with an invalid package version' do
+ invalid_versions = [
+ '555',
+ '1.2',
+ '1./2.3',
+ '../../../../../1.2.3',
+ '%2e%2e%2f1.2.3'
+ ]
+
+ invalid_versions.each do |invalid_version|
+ it "raises an error for version #{invalid_version}" do
+ allow(service).to receive(:package_version).and_return(invalid_version)
+
+ expect { subject }.to raise_error(ActiveRecord::RecordInvalid, 'Validation failed: Version is invalid')
+ expect(package_file.file_name).not_to include(invalid_version)
+ expect(package_file.file.file.path).not_to include(invalid_version)
+ end
+ end
+ end
+ end
+end
diff --git a/spec/services/packages/pypi/create_package_service_spec.rb b/spec/services/packages/pypi/create_package_service_spec.rb
new file mode 100644
index 00000000000..250b43d1f75
--- /dev/null
+++ b/spec/services/packages/pypi/create_package_service_spec.rb
@@ -0,0 +1,83 @@
+# frozen_string_literal: true
+require 'spec_helper'
+
+RSpec.describe Packages::Pypi::CreatePackageService do
+ include PackagesManagerApiSpecHelpers
+
+ let_it_be(:project) { create(:project) }
+ let_it_be(:user) { create(:user) }
+ let_it_be(:params) do
+ {
+ name: 'foo',
+ version: '1.0',
+ content: temp_file('foo.tgz'),
+ requires_python: '>=2.7',
+ sha256_digest: '123',
+ md5_digest: '567'
+ }
+ end
+
+ describe '#execute' do
+ subject { described_class.new(project, user, params).execute }
+
+ let(:created_package) { Packages::Package.pypi.last }
+
+ context 'without an existing package' do
+ it 'creates the package' do
+ expect { subject }.to change { Packages::Package.pypi.count }.by(1)
+
+ expect(created_package.name).to eq 'foo'
+ expect(created_package.version).to eq '1.0'
+
+ expect(created_package.pypi_metadatum.required_python).to eq '>=2.7'
+ expect(created_package.package_files.size).to eq 1
+ expect(created_package.package_files.first.file_name).to eq 'foo.tgz'
+ expect(created_package.package_files.first.file_sha256).to eq '123'
+ expect(created_package.package_files.first.file_md5).to eq '567'
+ end
+ end
+
+ context 'with an existing package' do
+ before do
+ described_class.new(project, user, params).execute
+ end
+
+ context 'with an existing file' do
+ before do
+ params[:content] = temp_file('foo.tgz')
+ params[:sha256_digest] = 'abc'
+ params[:md5_digest] = 'def'
+ end
+
+ it 'replaces the file' do
+ expect { subject }
+ .to change { Packages::Package.pypi.count }.by(0)
+ .and change { Packages::PackageFile.count }.by(1)
+
+ expect(created_package.package_files.size).to eq 2
+ expect(created_package.package_files.first.file_name).to eq 'foo.tgz'
+ expect(created_package.package_files.first.file_sha256).to eq '123'
+ expect(created_package.package_files.first.file_md5).to eq '567'
+ expect(created_package.package_files.last.file_name).to eq 'foo.tgz'
+ expect(created_package.package_files.last.file_sha256).to eq 'abc'
+ expect(created_package.package_files.last.file_md5).to eq 'def'
+ end
+ end
+
+ context 'without an existing file' do
+ before do
+ params[:content] = temp_file('another.tgz')
+ end
+
+ it 'adds the file' do
+ expect { subject }
+ .to change { Packages::Package.pypi.count }.by(0)
+ .and change { Packages::PackageFile.count }.by(1)
+
+ expect(created_package.package_files.size).to eq 2
+ expect(created_package.package_files.map(&:file_name).sort).to eq ['another.tgz', 'foo.tgz']
+ end
+ end
+ end
+ end
+end
diff --git a/spec/services/packages/remove_tag_service_spec.rb b/spec/services/packages/remove_tag_service_spec.rb
new file mode 100644
index 00000000000..084635824e5
--- /dev/null
+++ b/spec/services/packages/remove_tag_service_spec.rb
@@ -0,0 +1,20 @@
+# frozen_string_literal: true
+require 'spec_helper'
+
+RSpec.describe Packages::RemoveTagService do
+ let!(:package_tag) { create(:packages_tag) }
+
+ describe '#execute' do
+ subject { described_class.new(package_tag).execute }
+
+ context 'with existing tag' do
+ it { expect { subject }.to change { Packages::Tag.count }.by(-1) }
+ end
+
+ context 'with nil' do
+ subject { described_class.new(nil) }
+
+ it { expect { subject }.to raise_error(ArgumentError) }
+ end
+ end
+end
diff --git a/spec/services/packages/update_tags_service_spec.rb b/spec/services/packages/update_tags_service_spec.rb
new file mode 100644
index 00000000000..4a122d1c718
--- /dev/null
+++ b/spec/services/packages/update_tags_service_spec.rb
@@ -0,0 +1,59 @@
+# frozen_string_literal: true
+require 'spec_helper'
+
+RSpec.describe Packages::UpdateTagsService do
+ let_it_be(:package, reload: true) { create(:nuget_package) }
+
+ let(:tags) { %w(test-tag tag1 tag2 tag3) }
+ let(:service) { described_class.new(package, tags) }
+
+ describe '#execute' do
+ subject { service.execute }
+
+ RSpec.shared_examples 'updating tags' do |tags_count|
+ it 'updates a tag' do
+ expect { subject }.to change { Packages::Tag.count }.by(tags_count)
+ expect(package.reload.tags.map(&:name)).to contain_exactly(*tags)
+ end
+ end
+
+ it_behaves_like 'updating tags', 4
+
+ context 'with an existing tag' do
+ before do
+ create(:packages_tag, package: package2, name: 'test-tag')
+ end
+
+ context 'on the same package' do
+ let_it_be(:package2) { package }
+
+ it_behaves_like 'updating tags', 3
+
+ context 'with different name' do
+ before do
+ create(:packages_tag, package: package2, name: 'to_be_destroyed')
+ end
+
+ it_behaves_like 'updating tags', 2
+ end
+ end
+
+ context 'on a different package' do
+ let_it_be(:package2) { create(:nuget_package) }
+
+ it_behaves_like 'updating tags', 4
+ end
+ end
+
+ context 'with empty tags' do
+ let(:tags) { [] }
+
+ it 'is a no op' do
+ expect(package).not_to receive(:tags)
+ expect(::Gitlab::Database).not_to receive(:bulk_insert)
+
+ subject
+ end
+ end
+ end
+end
diff --git a/spec/services/pages/delete_services_spec.rb b/spec/services/pages/delete_services_spec.rb
index c253f294e80..f6d4694b4dd 100644
--- a/spec/services/pages/delete_services_spec.rb
+++ b/spec/services/pages/delete_services_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Pages::DeleteService do
+RSpec.describe Pages::DeleteService do
let_it_be(:project) { create(:project, path: "my.project")}
let_it_be(:admin) { create(:admin) }
let_it_be(:domain) { create(:pages_domain, project: project) }
diff --git a/spec/services/pages_domains/create_acme_order_service_spec.rb b/spec/services/pages_domains/create_acme_order_service_spec.rb
index d59aa9b979e..35b2cc56973 100644
--- a/spec/services/pages_domains/create_acme_order_service_spec.rb
+++ b/spec/services/pages_domains/create_acme_order_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe PagesDomains::CreateAcmeOrderService do
+RSpec.describe PagesDomains::CreateAcmeOrderService do
include LetsEncryptHelpers
let(:pages_domain) { create(:pages_domain) }
diff --git a/spec/services/pages_domains/obtain_lets_encrypt_certificate_service_spec.rb b/spec/services/pages_domains/obtain_lets_encrypt_certificate_service_spec.rb
index 22fcc6b9a79..4d489d7fe4b 100644
--- a/spec/services/pages_domains/obtain_lets_encrypt_certificate_service_spec.rb
+++ b/spec/services/pages_domains/obtain_lets_encrypt_certificate_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe PagesDomains::ObtainLetsEncryptCertificateService do
+RSpec.describe PagesDomains::ObtainLetsEncryptCertificateService do
include LetsEncryptHelpers
let(:pages_domain) { create(:pages_domain, :without_certificate, :without_key) }
diff --git a/spec/services/pages_domains/retry_acme_order_service_spec.rb b/spec/services/pages_domains/retry_acme_order_service_spec.rb
index 0185f10864c..601de24e766 100644
--- a/spec/services/pages_domains/retry_acme_order_service_spec.rb
+++ b/spec/services/pages_domains/retry_acme_order_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe PagesDomains::RetryAcmeOrderService do
+RSpec.describe PagesDomains::RetryAcmeOrderService do
let(:domain) { create(:pages_domain, auto_ssl_enabled: true, auto_ssl_failed: true) }
let(:service) { described_class.new(domain) }
diff --git a/spec/services/personal_access_tokens/create_service_spec.rb b/spec/services/personal_access_tokens/create_service_spec.rb
index 9190434b96a..475ade95948 100644
--- a/spec/services/personal_access_tokens/create_service_spec.rb
+++ b/spec/services/personal_access_tokens/create_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe PersonalAccessTokens::CreateService do
+RSpec.describe PersonalAccessTokens::CreateService do
describe '#execute' do
context 'with valid params' do
it 'creates personal access token record' do
diff --git a/spec/services/personal_access_tokens/last_used_service_spec.rb b/spec/services/personal_access_tokens/last_used_service_spec.rb
new file mode 100644
index 00000000000..6fc74e27dd9
--- /dev/null
+++ b/spec/services/personal_access_tokens/last_used_service_spec.rb
@@ -0,0 +1,47 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe PersonalAccessTokens::LastUsedService do
+ describe '#execute' do
+ subject { described_class.new(personal_access_token).execute }
+
+ context 'when the personal access token has not been used recently' do
+ let_it_be(:personal_access_token) { create(:personal_access_token, last_used_at: 1.year.ago) }
+
+ it 'updates the last_used_at timestamp' do
+ expect { subject }.to change { personal_access_token.last_used_at }
+ end
+
+ it 'does not run on read-only GitLab instances' do
+ allow(::Gitlab::Database).to receive(:read_only?).and_return(true)
+
+ expect { subject }.not_to change { personal_access_token.last_used_at }
+ end
+ end
+
+ context 'when the personal access token has been used recently' do
+ let_it_be(:personal_access_token) { create(:personal_access_token, last_used_at: 1.minute.ago) }
+
+ it 'does not update the last_used_at timestamp' do
+ expect { subject }.not_to change { personal_access_token.last_used_at }
+ end
+ end
+
+ context 'when the last_used_at timestamp is nil' do
+ let_it_be(:personal_access_token) { create(:personal_access_token, last_used_at: nil) }
+
+ it 'updates the last_used_at timestamp' do
+ expect { subject }.to change { personal_access_token.last_used_at }
+ end
+ end
+
+ context 'when not a personal access token' do
+ let_it_be(:personal_access_token) { create(:oauth_access_token) }
+
+ it 'does not execute' do
+ expect(subject).to be_nil
+ end
+ end
+ end
+end
diff --git a/spec/services/pod_logs/base_service_spec.rb b/spec/services/pod_logs/base_service_spec.rb
index bc4989b59d9..6f7731fda3a 100644
--- a/spec/services/pod_logs/base_service_spec.rb
+++ b/spec/services/pod_logs/base_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe ::PodLogs::BaseService do
+RSpec.describe ::PodLogs::BaseService do
include KubernetesHelpers
let_it_be(:cluster) { create(:cluster, :provided_by_gcp, environment_scope: '*') }
diff --git a/spec/services/pod_logs/elasticsearch_service_spec.rb b/spec/services/pod_logs/elasticsearch_service_spec.rb
index 8060d07461a..9431e47c6f2 100644
--- a/spec/services/pod_logs/elasticsearch_service_spec.rb
+++ b/spec/services/pod_logs/elasticsearch_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe ::PodLogs::ElasticsearchService do
+RSpec.describe ::PodLogs::ElasticsearchService do
let_it_be(:cluster) { create(:cluster, :provided_by_gcp, environment_scope: '*') }
let(:namespace) { 'autodevops-deploy-9-production' }
diff --git a/spec/services/pod_logs/kubernetes_service_spec.rb b/spec/services/pod_logs/kubernetes_service_spec.rb
index a1f7645323b..3e31ff15c1b 100644
--- a/spec/services/pod_logs/kubernetes_service_spec.rb
+++ b/spec/services/pod_logs/kubernetes_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe ::PodLogs::KubernetesService do
+RSpec.describe ::PodLogs::KubernetesService do
include KubernetesHelpers
let_it_be(:cluster) { create(:cluster, :provided_by_gcp, environment_scope: '*') }
diff --git a/spec/services/post_receive_service_spec.rb b/spec/services/post_receive_service_spec.rb
index 25f4122f134..c726e1851a7 100644
--- a/spec/services/post_receive_service_spec.rb
+++ b/spec/services/post_receive_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe PostReceiveService do
+RSpec.describe PostReceiveService do
include Gitlab::Routing
let_it_be(:user) { create(:user) }
@@ -166,41 +166,6 @@ describe PostReceiveService do
expect(subject).to include(build_alert_message(message))
end
end
-
- context 'storage size limit alerts' do
- let(:check_storage_size_response) { ServiceResponse.success }
-
- before do
- expect_next_instance_of(Namespaces::CheckStorageSizeService, project.namespace, user) do |check_storage_size_service|
- expect(check_storage_size_service).to receive(:execute).and_return(check_storage_size_response)
- end
- end
-
- context 'when there is no payload' do
- it 'adds no alert' do
- expect(subject.size).to eq(1)
- end
- end
-
- context 'when there is payload' do
- let(:check_storage_size_response) do
- ServiceResponse.success(
- payload: {
- alert_level: :info,
- usage_message: "Usage",
- explanation_message: "Explanation"
- }
- )
- end
-
- it 'adds an alert' do
- response = subject
-
- expect(response.size).to eq(2)
- expect(response).to include(build_alert_message("##### INFO #####\nUsage\nExplanation"))
- end
- end
- end
end
context 'with PersonalSnippet' do
diff --git a/spec/services/preview_markdown_service_spec.rb b/spec/services/preview_markdown_service_spec.rb
index d25e9958831..2509d1300b3 100644
--- a/spec/services/preview_markdown_service_spec.rb
+++ b/spec/services/preview_markdown_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe PreviewMarkdownService do
+RSpec.describe PreviewMarkdownService do
let(:user) { create(:user) }
let(:project) { create(:project, :repository) }
diff --git a/spec/services/projects/after_import_service_spec.rb b/spec/services/projects/after_import_service_spec.rb
index 82f654cea10..a109348ea19 100644
--- a/spec/services/projects/after_import_service_spec.rb
+++ b/spec/services/projects/after_import_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::AfterImportService do
+RSpec.describe Projects::AfterImportService do
include GitHelpers
subject { described_class.new(project) }
@@ -72,6 +72,26 @@ describe Projects::AfterImportService do
end
end
+ context 'when housekeeping service lease is taken' do
+ let(:exception) { Projects::HousekeepingService::LeaseTaken.new }
+
+ it 'logs the error message' do
+ allow_next_instance_of(Projects::HousekeepingService) do |instance|
+ expect(instance).to receive(:execute).and_raise(exception)
+ end
+
+ expect(Gitlab::Import::Logger).to receive(:info).with(
+ {
+ message: 'Project housekeeping failed',
+ project_full_path: project.full_path,
+ project_id: project.id,
+ 'error.message' => exception.to_s
+ }).and_call_original
+
+ subject.execute
+ end
+ end
+
context 'when after import action throw retriable exception one time' do
let(:exception) { GRPC::DeadlineExceeded.new }
diff --git a/spec/services/projects/after_rename_service_spec.rb b/spec/services/projects/after_rename_service_spec.rb
index b81dd3d7e3f..52136b37c66 100644
--- a/spec/services/projects/after_rename_service_spec.rb
+++ b/spec/services/projects/after_rename_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::AfterRenameService do
+RSpec.describe Projects::AfterRenameService do
let(:rugged_config) { rugged_repo(project.repository).config }
let(:legacy_storage) { Storage::LegacyProject.new(project) }
let(:hashed_storage) { Storage::Hashed.new(project) }
diff --git a/spec/services/projects/alerting/notify_service_spec.rb b/spec/services/projects/alerting/notify_service_spec.rb
index 2f8c2049f85..123b0bad2a8 100644
--- a/spec/services/projects/alerting/notify_service_spec.rb
+++ b/spec/services/projects/alerting/notify_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::Alerting::NotifyService do
+RSpec.describe Projects::Alerting::NotifyService do
let_it_be(:project, reload: true) { create(:project) }
before do
@@ -21,7 +21,7 @@ describe Projects::Alerting::NotifyService do
it 'processes issues' do
expect(IncidentManagement::ProcessAlertWorker)
.to receive(:perform_async)
- .with(project.id, kind_of(Hash), kind_of(Integer))
+ .with(nil, nil, kind_of(Integer))
.once
Sidekiq::Testing.inline! do
@@ -64,12 +64,6 @@ describe Projects::Alerting::NotifyService do
end
end
- shared_examples 'NotifyService does not create alert' do
- it 'does not create alert' do
- expect { subject }.not_to change(AlertManagement::Alert, :count)
- end
- end
-
describe '#execute' do
let(:token) { 'invalid-token' }
let(:starts_at) { Time.current.change(usec: 0) }
@@ -107,60 +101,64 @@ describe Projects::Alerting::NotifyService do
end
context 'with valid payload' do
+ shared_examples 'assigns the alert properties' do
+ it 'ensure that created alert has all data properly assigned' do
+ subject
+
+ expect(last_alert_attributes).to match(
+ project_id: project.id,
+ title: payload_raw.fetch(:title),
+ started_at: Time.zone.parse(payload_raw.fetch(:start_time)),
+ severity: payload_raw.fetch(:severity),
+ status: AlertManagement::Alert::STATUSES[:triggered],
+ events: 1,
+ hosts: payload_raw.fetch(:hosts),
+ payload: payload_raw.with_indifferent_access,
+ issue_id: nil,
+ description: payload_raw.fetch(:description),
+ monitoring_tool: payload_raw.fetch(:monitoring_tool),
+ service: payload_raw.fetch(:service),
+ fingerprint: Digest::SHA1.hexdigest(fingerprint),
+ ended_at: nil,
+ prometheus_alert_id: nil,
+ environment_id: nil
+ )
+ end
+ end
+
let(:last_alert_attributes) do
AlertManagement::Alert.last.attributes
.except('id', 'iid', 'created_at', 'updated_at')
.with_indifferent_access
end
- it 'creates AlertManagement::Alert' do
- expect { subject }.to change(AlertManagement::Alert, :count).by(1)
- end
-
- it 'created alert has all data properly assigned' do
- subject
-
- expect(last_alert_attributes).to match(
- project_id: project.id,
- title: payload_raw.fetch(:title),
- started_at: Time.zone.parse(payload_raw.fetch(:start_time)),
- severity: payload_raw.fetch(:severity),
- status: AlertManagement::Alert::STATUSES[:triggered],
- events: 1,
- hosts: payload_raw.fetch(:hosts),
- payload: payload_raw.with_indifferent_access,
- issue_id: nil,
- description: payload_raw.fetch(:description),
- monitoring_tool: payload_raw.fetch(:monitoring_tool),
- service: payload_raw.fetch(:service),
- fingerprint: Digest::SHA1.hexdigest(fingerprint),
- ended_at: nil
- )
- end
-
- it 'executes the alert service hooks' do
- slack_service = create(:service, type: 'SlackService', project: project, alert_events: true, active: true)
- subject
-
- expect(ProjectServiceWorker).to have_received(:perform_async).with(slack_service.id, an_instance_of(Hash))
- end
+ it_behaves_like 'creates an alert management alert'
+ it_behaves_like 'assigns the alert properties'
context 'existing alert with same fingerprint' do
let(:fingerprint_sha) { Digest::SHA1.hexdigest(fingerprint) }
- let!(:existing_alert) { create(:alert_management_alert, project: project, fingerprint: fingerprint_sha) }
+ let!(:alert) { create(:alert_management_alert, project: project, fingerprint: fingerprint_sha) }
+
+ it_behaves_like 'adds an alert management alert event'
+
+ context 'existing alert is resolved' do
+ let!(:alert) { create(:alert_management_alert, :resolved, project: project, fingerprint: fingerprint_sha) }
- it 'does not create AlertManagement::Alert' do
- expect { subject }.not_to change(AlertManagement::Alert, :count)
+ it_behaves_like 'creates an alert management alert'
+ it_behaves_like 'assigns the alert properties'
end
- it 'increments the existing alert count' do
- expect { subject }.to change { existing_alert.reload.events }.from(1).to(2)
+ context 'existing alert is ignored' do
+ let!(:alert) { create(:alert_management_alert, :ignored, project: project, fingerprint: fingerprint_sha) }
+
+ it_behaves_like 'adds an alert management alert event'
end
- it 'does not executes the alert service hooks' do
- subject
+ context 'two existing alerts, one resolved one open' do
+ let!(:resolved_existing_alert) { create(:alert_management_alert, :resolved, project: project, fingerprint: fingerprint_sha) }
+ let!(:alert) { create(:alert_management_alert, project: project, fingerprint: fingerprint_sha) }
- expect(ProjectServiceWorker).not_to have_received(:perform_async)
+ it_behaves_like 'adds an alert management alert event'
end
end
@@ -172,9 +170,7 @@ describe Projects::Alerting::NotifyService do
}
end
- it 'creates AlertManagement::Alert' do
- expect { subject }.to change(AlertManagement::Alert, :count).by(1)
- end
+ it_behaves_like 'creates an alert management alert'
it 'created alert has all data properly assigned' do
subject
@@ -193,7 +189,9 @@ describe Projects::Alerting::NotifyService do
monitoring_tool: nil,
service: nil,
fingerprint: nil,
- ended_at: nil
+ ended_at: nil,
+ prometheus_alert_id: nil,
+ environment_id: nil
)
end
end
@@ -214,19 +212,19 @@ describe Projects::Alerting::NotifyService do
end
it_behaves_like 'does not process incident issues due to error', http_status: :bad_request
- it_behaves_like 'NotifyService does not create alert'
+ it_behaves_like 'does not an create alert management alert'
end
context 'when alert already exists' do
let(:fingerprint_sha) { Digest::SHA1.hexdigest(fingerprint) }
- let!(:existing_alert) { create(:alert_management_alert, project: project, fingerprint: fingerprint_sha) }
+ let!(:alert) { create(:alert_management_alert, project: project, fingerprint: fingerprint_sha) }
context 'when existing alert does not have an associated issue' do
it_behaves_like 'processes incident issues'
end
context 'when existing alert has an associated issue' do
- let!(:existing_alert) { create(:alert_management_alert, :with_issue, project: project, fingerprint: fingerprint_sha) }
+ let!(:alert) { create(:alert_management_alert, :with_issue, project: project, fingerprint: fingerprint_sha) }
it_behaves_like 'does not process incident issues'
end
@@ -242,14 +240,14 @@ describe Projects::Alerting::NotifyService do
context 'with invalid token' do
it_behaves_like 'does not process incident issues due to error', http_status: :unauthorized
- it_behaves_like 'NotifyService does not create alert'
+ it_behaves_like 'does not an create alert management alert'
end
context 'with deactivated Alerts Service' do
let!(:alerts_service) { create(:alerts_service, :inactive, project: project) }
it_behaves_like 'does not process incident issues due to error', http_status: :forbidden
- it_behaves_like 'NotifyService does not create alert'
+ it_behaves_like 'does not an create alert management alert'
end
end
end
diff --git a/spec/services/projects/auto_devops/disable_service_spec.rb b/spec/services/projects/auto_devops/disable_service_spec.rb
index fb1ab3f9949..1f161990fb2 100644
--- a/spec/services/projects/auto_devops/disable_service_spec.rb
+++ b/spec/services/projects/auto_devops/disable_service_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
require 'spec_helper'
-describe Projects::AutoDevops::DisableService, '#execute' do
+RSpec.describe Projects::AutoDevops::DisableService, '#execute' do
let(:project) { create(:project, :repository, :auto_devops) }
let(:auto_devops) { project.auto_devops }
diff --git a/spec/services/projects/autocomplete_service_spec.rb b/spec/services/projects/autocomplete_service_spec.rb
index b625653bc77..336aa37096a 100644
--- a/spec/services/projects/autocomplete_service_spec.rb
+++ b/spec/services/projects/autocomplete_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::AutocompleteService do
+RSpec.describe Projects::AutocompleteService do
describe '#issues' do
describe 'confidential issues' do
let(:author) { create(:user) }
diff --git a/spec/services/projects/batch_open_issues_count_service_spec.rb b/spec/services/projects/batch_open_issues_count_service_spec.rb
index 8cb0ce03fba..82d50604309 100644
--- a/spec/services/projects/batch_open_issues_count_service_spec.rb
+++ b/spec/services/projects/batch_open_issues_count_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::BatchOpenIssuesCountService do
+RSpec.describe Projects::BatchOpenIssuesCountService do
let!(:project_1) { create(:project) }
let!(:project_2) { create(:project) }
diff --git a/spec/services/projects/cleanup_service_spec.rb b/spec/services/projects/cleanup_service_spec.rb
index 5c246854eb7..528f31456a9 100644
--- a/spec/services/projects/cleanup_service_spec.rb
+++ b/spec/services/projects/cleanup_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::CleanupService do
+RSpec.describe Projects::CleanupService do
let(:project) { create(:project, :repository, bfg_object_map: fixture_file_upload('spec/fixtures/bfg_object_map.txt')) }
let(:object_map) { project.bfg_object_map }
diff --git a/spec/services/projects/container_repository/cleanup_tags_service_spec.rb b/spec/services/projects/container_repository/cleanup_tags_service_spec.rb
index 11ea7d51673..2c708e75a25 100644
--- a/spec/services/projects/container_repository/cleanup_tags_service_spec.rb
+++ b/spec/services/projects/container_repository/cleanup_tags_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::ContainerRepository::CleanupTagsService do
+RSpec.describe Projects::ContainerRepository::CleanupTagsService do
let_it_be(:user) { create(:user) }
let_it_be(:project, reload: true) { create(:project, :private) }
let_it_be(:repository) { create(:container_repository, :root, project: project) }
diff --git a/spec/services/projects/container_repository/delete_tags_service_spec.rb b/spec/services/projects/container_repository/delete_tags_service_spec.rb
index e17e4b6f7c9..3d065deefdf 100644
--- a/spec/services/projects/container_repository/delete_tags_service_spec.rb
+++ b/spec/services/projects/container_repository/delete_tags_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::ContainerRepository::DeleteTagsService do
+RSpec.describe Projects::ContainerRepository::DeleteTagsService do
let_it_be(:user) { create(:user) }
let_it_be(:project) { create(:project, :private) }
let_it_be(:repository) { create(:container_repository, :root, project: project) }
@@ -20,6 +20,31 @@ describe Projects::ContainerRepository::DeleteTagsService do
tags: %w(latest A Ba Bb C D E))
end
+ RSpec.shared_examples 'logging a success response' do
+ it 'logs an info message' do
+ expect(service).to receive(:log_info).with(
+ service_class: 'Projects::ContainerRepository::DeleteTagsService',
+ message: 'deleted tags',
+ container_repository_id: repository.id,
+ deleted_tags_count: tags.size
+ )
+
+ subject
+ end
+ end
+
+ RSpec.shared_examples 'logging an error response' do |message: 'could not delete tags'|
+ it 'logs an error message' do
+ expect(service).to receive(:log_error).with(
+ service_class: 'Projects::ContainerRepository::DeleteTagsService',
+ message: message,
+ container_repository_id: repository.id
+ )
+
+ subject
+ end
+ end
+
describe '#execute' do
let(:tags) { %w[A] }
@@ -47,11 +72,8 @@ describe Projects::ContainerRepository::DeleteTagsService do
let_it_be(:tags) { %w[A Ba] }
it 'deletes the tags by name' do
- stub_request(:delete, "http://registry.gitlab/v2/#{repository.path}/tags/reference/A")
- .to_return(status: 200, body: "")
-
- stub_request(:delete, "http://registry.gitlab/v2/#{repository.path}/tags/reference/Ba")
- .to_return(status: 200, body: "")
+ stub_delete_reference_request('A')
+ stub_delete_reference_request('Ba')
expect_delete_tag_by_name('A')
expect_delete_tag_by_name('Ba')
@@ -60,26 +82,29 @@ describe Projects::ContainerRepository::DeleteTagsService do
end
it 'succeeds when tag delete returns 404' do
- stub_request(:delete, "http://registry.gitlab/v2/#{repository.path}/tags/reference/A")
- .to_return(status: 200, body: "")
-
- stub_request(:delete, "http://registry.gitlab/v2/#{repository.path}/tags/reference/Ba")
- .to_return(status: 404, body: "")
+ stub_delete_reference_request('A')
+ stub_delete_reference_request('Ba', 404)
is_expected.to include(status: :success)
end
+ it_behaves_like 'logging a success response' do
+ before do
+ stub_delete_reference_request('A')
+ stub_delete_reference_request('Ba')
+ end
+ end
+
context 'with failures' do
context 'when the delete request fails' do
before do
- stub_request(:delete, "http://registry.gitlab/v2/#{repository.path}/tags/reference/A")
- .to_return(status: 500, body: "")
-
- stub_request(:delete, "http://registry.gitlab/v2/#{repository.path}/tags/reference/Ba")
- .to_return(status: 500, body: "")
+ stub_delete_reference_request('A', 500)
+ stub_delete_reference_request('Ba', 500)
end
it { is_expected.to include(status: :error) }
+
+ it_behaves_like 'logging an error response'
end
end
end
@@ -104,19 +129,35 @@ describe Projects::ContainerRepository::DeleteTagsService do
end
end
end
+
context 'and the feature is disabled' do
+ let_it_be(:tags) { %w[A Ba] }
+
before do
stub_feature_flags(container_registry_fast_tag_delete: false)
+ stub_upload("{\n \"config\": {\n }\n}", 'sha256:4435000728ee66e6a80e55637fc22725c256b61de344a2ecdeaac6bdb36e8bc3')
+ stub_put_manifest_request('A')
+ stub_put_manifest_request('Ba')
end
it 'fallbacks to slow delete' do
expect(service).not_to receive(:fast_delete)
- expect(service).to receive(:slow_delete).with(repository, tags)
+ expect(service).to receive(:slow_delete).with(repository, tags).and_call_original
+
+ expect_delete_tag_by_digest('sha256:dummy')
subject
end
+
+ it_behaves_like 'logging a success response' do
+ before do
+ allow(service).to receive(:slow_delete).and_call_original
+ expect_delete_tag_by_digest('sha256:dummy')
+ end
+ end
end
end
+
context 'when the registry does not support fast delete' do
let_it_be(:project) { create(:project, :private) }
let_it_be(:repository) { create(:container_repository, :root, project: project) }
@@ -155,11 +196,8 @@ describe Projects::ContainerRepository::DeleteTagsService do
it 'deletes the tags using a dummy image' do
stub_upload("{\n \"config\": {\n }\n}", 'sha256:4435000728ee66e6a80e55637fc22725c256b61de344a2ecdeaac6bdb36e8bc3')
- stub_request(:put, "http://registry.gitlab/v2/#{repository.path}/manifests/A")
- .to_return(status: 200, body: "", headers: { 'docker-content-digest' => 'sha256:dummy' })
-
- stub_request(:put, "http://registry.gitlab/v2/#{repository.path}/manifests/Ba")
- .to_return(status: 200, body: "", headers: { 'docker-content-digest' => 'sha256:dummy' })
+ stub_put_manifest_request('A')
+ stub_put_manifest_request('Ba')
expect_delete_tag_by_digest('sha256:dummy')
@@ -169,11 +207,8 @@ describe Projects::ContainerRepository::DeleteTagsService do
it 'succeeds when tag delete returns 404' do
stub_upload("{\n \"config\": {\n }\n}", 'sha256:4435000728ee66e6a80e55637fc22725c256b61de344a2ecdeaac6bdb36e8bc3')
- stub_request(:put, "http://registry.gitlab/v2/#{repository.path}/manifests/A")
- .to_return(status: 200, body: "", headers: { 'docker-content-digest' => 'sha256:dummy' })
-
- stub_request(:put, "http://registry.gitlab/v2/#{repository.path}/manifests/Ba")
- .to_return(status: 200, body: "", headers: { 'docker-content-digest' => 'sha256:dummy' })
+ stub_put_manifest_request('A')
+ stub_put_manifest_request('Ba')
stub_request(:delete, "http://registry.gitlab/v2/#{repository.path}/manifests/sha256:dummy")
.to_return(status: 404, body: "", headers: {})
@@ -181,6 +216,15 @@ describe Projects::ContainerRepository::DeleteTagsService do
is_expected.to include(status: :success)
end
+ it_behaves_like 'logging a success response' do
+ before do
+ stub_upload("{\n \"config\": {\n }\n}", 'sha256:4435000728ee66e6a80e55637fc22725c256b61de344a2ecdeaac6bdb36e8bc3')
+ stub_put_manifest_request('A')
+ stub_put_manifest_request('Ba')
+ expect_delete_tag_by_digest('sha256:dummy')
+ end
+ end
+
context 'with failures' do
context 'when the dummy manifest generation fails' do
before do
@@ -188,23 +232,23 @@ describe Projects::ContainerRepository::DeleteTagsService do
end
it { is_expected.to include(status: :error) }
+
+ it_behaves_like 'logging an error response', message: 'could not generate manifest'
end
context 'when updating the tags fails' do
before do
stub_upload("{\n \"config\": {\n }\n}", 'sha256:4435000728ee66e6a80e55637fc22725c256b61de344a2ecdeaac6bdb36e8bc3')
- stub_request(:put, "http://registry.gitlab/v2/#{repository.path}/manifests/A")
- .to_return(status: 500, body: "", headers: { 'docker-content-digest' => 'sha256:dummy' })
-
- stub_request(:put, "http://registry.gitlab/v2/#{repository.path}/manifests/Ba")
- .to_return(status: 500, body: "", headers: { 'docker-content-digest' => 'sha256:dummy' })
+ stub_put_manifest_request('A', 500)
+ stub_put_manifest_request('Ba', 500)
stub_request(:delete, "http://registry.gitlab/v2/#{repository.path}/manifests/sha256:4435000728ee66e6a80e55637fc22725c256b61de344a2ecdeaac6bdb36e8bc3")
.to_return(status: 200, body: "", headers: {})
end
it { is_expected.to include(status: :error) }
+ it_behaves_like 'logging an error response'
end
end
end
@@ -214,6 +258,16 @@ describe Projects::ContainerRepository::DeleteTagsService do
private
+ def stub_delete_reference_request(tag, status = 200)
+ stub_request(:delete, "http://registry.gitlab/v2/#{repository.path}/tags/reference/#{tag}")
+ .to_return(status: status, body: '')
+ end
+
+ def stub_put_manifest_request(tag, status = 200, headers = { 'docker-content-digest' => 'sha256:dummy' })
+ stub_request(:put, "http://registry.gitlab/v2/#{repository.path}/manifests/#{tag}")
+ .to_return(status: status, body: '', headers: headers)
+ end
+
def stub_tag_digest(tag, digest)
stub_request(:head, "http://registry.gitlab/v2/#{repository.path}/manifests/#{tag}")
.to_return(status: 200, body: "", headers: { 'docker-content-digest' => digest })
diff --git a/spec/services/projects/container_repository/destroy_service_spec.rb b/spec/services/projects/container_repository/destroy_service_spec.rb
index 753b7540d7f..20e75d94e05 100644
--- a/spec/services/projects/container_repository/destroy_service_spec.rb
+++ b/spec/services/projects/container_repository/destroy_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::ContainerRepository::DestroyService do
+RSpec.describe Projects::ContainerRepository::DestroyService do
let_it_be(:user) { create(:user) }
let_it_be(:project) { create(:project, :private) }
diff --git a/spec/services/projects/count_service_spec.rb b/spec/services/projects/count_service_spec.rb
index e345b508f53..11b2b57a277 100644
--- a/spec/services/projects/count_service_spec.rb
+++ b/spec/services/projects/count_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::CountService do
+RSpec.describe Projects::CountService do
let(:project) { build(:project, id: 1) }
let(:service) { described_class.new(project) }
diff --git a/spec/services/projects/create_from_template_service_spec.rb b/spec/services/projects/create_from_template_service_spec.rb
index 0b4772e8f02..7e23daabcd3 100644
--- a/spec/services/projects/create_from_template_service_spec.rb
+++ b/spec/services/projects/create_from_template_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::CreateFromTemplateService do
+RSpec.describe Projects::CreateFromTemplateService do
let(:user) { create(:user) }
let(:template_name) { 'rails' }
let(:project_params) do
diff --git a/spec/services/projects/create_service_spec.rb b/spec/services/projects/create_service_spec.rb
index e70ee05ed31..9eb7cacbbcb 100644
--- a/spec/services/projects/create_service_spec.rb
+++ b/spec/services/projects/create_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::CreateService, '#execute' do
+RSpec.describe Projects::CreateService, '#execute' do
include ExternalAuthorizationServiceHelpers
include GitHelpers
@@ -240,13 +240,21 @@ describe Projects::CreateService, '#execute' do
end
context 'import data' do
- it 'stores import data and URL' do
- import_data = { data: { 'test' => 'some data' } }
- project = create_project(user, { name: 'test', import_url: 'http://import-url', import_data: import_data })
+ let(:import_data) { { data: { 'test' => 'some data' } } }
+ let(:imported_project) { create_project(user, { name: 'test', import_url: 'http://import-url', import_data: import_data }) }
+
+ it 'does not write repository config' do
+ expect_next_instance_of(Project) do |project|
+ expect(project).not_to receive(:write_repository_config)
+ end
- expect(project.import_data).to be_persisted
- expect(project.import_data.data).to eq(import_data[:data])
- expect(project.import_url).to eq('http://import-url')
+ imported_project
+ end
+
+ it 'stores import data and URL' do
+ expect(imported_project.import_data).to be_persisted
+ expect(imported_project.import_data.data).to eq(import_data[:data])
+ expect(imported_project.import_url).to eq('http://import-url')
end
end
@@ -438,14 +446,35 @@ describe Projects::CreateService, '#execute' do
end
context 'when readme initialization is requested' do
- it 'creates README.md' do
+ let(:project) { create_project(user, opts) }
+
+ before do
opts[:initialize_with_readme] = '1'
+ end
- project = create_project(user, opts)
+ shared_examples 'creates README.md' do
+ it { expect(project.repository.commit_count).to be(1) }
+ it { expect(project.repository.readme.name).to eql('README.md') }
+ it { expect(project.repository.readme.data).to include('# GitLab') }
+ end
- expect(project.repository.commit_count).to be(1)
- expect(project.repository.readme.name).to eql('README.md')
- expect(project.repository.readme.data).to include('# GitLab')
+ it_behaves_like 'creates README.md'
+
+ context 'and a default_branch_name is specified' do
+ before do
+ allow(Gitlab::CurrentSettings)
+ .to receive(:default_branch_name)
+ .and_return('example_branch')
+ end
+
+ it_behaves_like 'creates README.md'
+
+ it 'creates README.md within the specified branch rather than master' do
+ branches = project.repository.branches
+
+ expect(branches.size).to eq(1)
+ expect(branches.collect(&:name)).to contain_exactly('example_branch')
+ end
end
end
@@ -647,10 +676,6 @@ describe Projects::CreateService, '#execute' do
end
it 'updates authorization for current_user' do
- expect(Users::RefreshAuthorizedProjectsService).to(
- receive(:new).with(user).and_call_original
- )
-
project = create_project(user, opts)
expect(
@@ -682,10 +707,6 @@ describe Projects::CreateService, '#execute' do
end
it 'updates authorization for current_user' do
- expect(Users::RefreshAuthorizedProjectsService).to(
- receive(:new).with(user).and_call_original
- )
-
project = create_project(user, opts)
expect(
diff --git a/spec/services/projects/deploy_tokens/create_service_spec.rb b/spec/services/projects/deploy_tokens/create_service_spec.rb
index 5c3ada8af4e..831dbc06588 100644
--- a/spec/services/projects/deploy_tokens/create_service_spec.rb
+++ b/spec/services/projects/deploy_tokens/create_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::DeployTokens::CreateService do
+RSpec.describe Projects::DeployTokens::CreateService do
it_behaves_like 'a deploy token creation service' do
let(:entity) { create(:project) }
let(:deploy_token_class) { ProjectDeployToken }
diff --git a/spec/services/projects/deploy_tokens/destroy_service_spec.rb b/spec/services/projects/deploy_tokens/destroy_service_spec.rb
index 24407f46615..edb2345aa6c 100644
--- a/spec/services/projects/deploy_tokens/destroy_service_spec.rb
+++ b/spec/services/projects/deploy_tokens/destroy_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::DeployTokens::DestroyService do
+RSpec.describe Projects::DeployTokens::DestroyService do
it_behaves_like 'a deploy token deletion service' do
let_it_be(:entity) { create(:project) }
let_it_be(:deploy_token_class) { ProjectDeployToken }
diff --git a/spec/services/projects/destroy_rollback_service_spec.rb b/spec/services/projects/destroy_rollback_service_spec.rb
index 8facf17dc45..f63939337b8 100644
--- a/spec/services/projects/destroy_rollback_service_spec.rb
+++ b/spec/services/projects/destroy_rollback_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::DestroyRollbackService do
+RSpec.describe Projects::DestroyRollbackService do
let_it_be(:user) { create(:user) }
let_it_be(:project) { create(:project, :repository, namespace: user.namespace) }
let(:repository) { project.repository }
diff --git a/spec/services/projects/destroy_service_spec.rb b/spec/services/projects/destroy_service_spec.rb
index 58c40d04fe9..56b19c33ece 100644
--- a/spec/services/projects/destroy_service_spec.rb
+++ b/spec/services/projects/destroy_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::DestroyService do
+RSpec.describe Projects::DestroyService do
include ProjectForksHelper
let_it_be(:user) { create(:user) }
diff --git a/spec/services/projects/detect_repository_languages_service_spec.rb b/spec/services/projects/detect_repository_languages_service_spec.rb
index 76600b0e77c..cf4c7a5024d 100644
--- a/spec/services/projects/detect_repository_languages_service_spec.rb
+++ b/spec/services/projects/detect_repository_languages_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::DetectRepositoryLanguagesService, :clean_gitlab_redis_shared_state do
+RSpec.describe Projects::DetectRepositoryLanguagesService, :clean_gitlab_redis_shared_state do
let_it_be(:project, reload: true) { create(:project, :repository) }
subject { described_class.new(project) }
diff --git a/spec/services/projects/download_service_spec.rb b/spec/services/projects/download_service_spec.rb
index 06efc2ff825..0f743eaa7f5 100644
--- a/spec/services/projects/download_service_spec.rb
+++ b/spec/services/projects/download_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::DownloadService do
+RSpec.describe Projects::DownloadService do
describe 'File service' do
before do
@user = create(:user)
diff --git a/spec/services/projects/enable_deploy_key_service_spec.rb b/spec/services/projects/enable_deploy_key_service_spec.rb
index 64de373d7f6..f297ec374cf 100644
--- a/spec/services/projects/enable_deploy_key_service_spec.rb
+++ b/spec/services/projects/enable_deploy_key_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::EnableDeployKeyService do
+RSpec.describe Projects::EnableDeployKeyService do
let(:deploy_key) { create(:deploy_key, public: true) }
let(:project) { create(:project) }
let(:user) { project.creator}
diff --git a/spec/services/projects/fetch_statistics_increment_service_spec.rb b/spec/services/projects/fetch_statistics_increment_service_spec.rb
index fcfb138aad6..16121a42c39 100644
--- a/spec/services/projects/fetch_statistics_increment_service_spec.rb
+++ b/spec/services/projects/fetch_statistics_increment_service_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
module Projects
- describe FetchStatisticsIncrementService do
+ RSpec.describe FetchStatisticsIncrementService do
let(:project) { create(:project) }
describe '#execute' do
diff --git a/spec/services/projects/fork_service_spec.rb b/spec/services/projects/fork_service_spec.rb
index 112a41c773b..c49aa42b147 100644
--- a/spec/services/projects/fork_service_spec.rb
+++ b/spec/services/projects/fork_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::ForkService do
+RSpec.describe Projects::ForkService do
include ProjectForksHelper
shared_examples 'forks count cache refresh' do
@@ -10,6 +10,7 @@ describe Projects::ForkService do
expect(from_project.forks_count).to be_zero
fork_project(from_project, to_user)
+ BatchLoader::Executor.clear_current
expect(from_project.forks_count).to eq(1)
end
@@ -327,7 +328,7 @@ describe Projects::ForkService do
destination_storage_name: 'test_second_storage'
)
Projects::UpdateRepositoryStorageService.new(storage_move).execute
- fork_after_move = fork_project(project)
+ fork_after_move = fork_project(project.reload)
pool_repository_before_move = PoolRepository.joins(:shard)
.find_by(source_project: project, shards: { name: 'default' })
pool_repository_after_move = PoolRepository.joins(:shard)
@@ -405,6 +406,7 @@ describe Projects::ForkService do
expect(fork_from_project.forks_count).to be_zero
subject.execute(fork_to_project)
+ BatchLoader::Executor.clear_current
expect(fork_from_project.forks_count).to eq(1)
end
diff --git a/spec/services/projects/forks_count_service_spec.rb b/spec/services/projects/forks_count_service_spec.rb
index 21a75eafc7a..31662f78973 100644
--- a/spec/services/projects/forks_count_service_spec.rb
+++ b/spec/services/projects/forks_count_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::ForksCountService, :use_clean_rails_memory_store_caching do
+RSpec.describe Projects::ForksCountService, :use_clean_rails_memory_store_caching do
let(:project) { build(:project) }
subject { described_class.new(project) }
diff --git a/spec/services/projects/git_deduplication_service_spec.rb b/spec/services/projects/git_deduplication_service_spec.rb
index 9e6279da7de..b98db5bc41b 100644
--- a/spec/services/projects/git_deduplication_service_spec.rb
+++ b/spec/services/projects/git_deduplication_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::GitDeduplicationService do
+RSpec.describe Projects::GitDeduplicationService do
include ExclusiveLeaseHelpers
let(:pool) { create(:pool_repository, :ready) }
@@ -139,7 +139,7 @@ describe Projects::GitDeduplicationService do
end
it 'fails when a lease is already out' do
- expect(service).to receive(:log_error).with('Cannot obtain an exclusive lease. There must be another instance already in execution.')
+ expect(service).to receive(:log_error).with("Cannot obtain an exclusive lease for #{service.class.name}. There must be another instance already in execution.")
service.execute
end
diff --git a/spec/services/projects/gitlab_projects_import_service_spec.rb b/spec/services/projects/gitlab_projects_import_service_spec.rb
index 1662d4577aa..09d093a9916 100644
--- a/spec/services/projects/gitlab_projects_import_service_spec.rb
+++ b/spec/services/projects/gitlab_projects_import_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::GitlabProjectsImportService do
+RSpec.describe Projects::GitlabProjectsImportService do
let_it_be(:namespace) { create(:namespace) }
let(:path) { 'test-path' }
let(:file) { fixture_file_upload('spec/fixtures/project_export.tar.gz') }
diff --git a/spec/services/projects/group_links/create_service_spec.rb b/spec/services/projects/group_links/create_service_spec.rb
index 22f7c8bdcb4..6468e3007c2 100644
--- a/spec/services/projects/group_links/create_service_spec.rb
+++ b/spec/services/projects/group_links/create_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::GroupLinks::CreateService, '#execute' do
+RSpec.describe Projects::GroupLinks::CreateService, '#execute' do
let_it_be(:user) { create :user }
let_it_be(:group) { create :group }
let_it_be(:project) { create :project }
@@ -23,7 +23,7 @@ describe Projects::GroupLinks::CreateService, '#execute' do
expect { subject.execute(group) }.to change { project.project_group_links.count }.from(0).to(1)
end
- it 'updates authorization' do
+ it 'updates authorization', :sidekiq_inline do
expect { subject.execute(group) }.to(
change { Ability.allowed?(user, :read_project, project) }
.from(false).to(true))
@@ -36,4 +36,50 @@ describe Projects::GroupLinks::CreateService, '#execute' do
it 'returns error if user is not allowed to share with a group' do
expect { subject.execute(create(:group)) }.not_to change { project.project_group_links.count }
end
+
+ context 'with specialized_project_authorization_workers' do
+ let_it_be(:other_user) { create(:user) }
+
+ before do
+ group.add_developer(other_user)
+ end
+
+ it 'schedules authorization update for users with access to group' do
+ expect(AuthorizedProjectsWorker).not_to(
+ receive(:bulk_perform_async)
+ )
+ expect(AuthorizedProjectUpdate::ProjectGroupLinkCreateWorker).to(
+ receive(:perform_async).and_call_original
+ )
+ expect(AuthorizedProjectUpdate::UserRefreshWithLowUrgencyWorker).to(
+ receive(:bulk_perform_in)
+ .with(1.hour,
+ array_including([user.id], [other_user.id]),
+ batch_delay: 30.seconds, batch_size: 100)
+ .and_call_original
+ )
+
+ subject.execute(group)
+ end
+
+ context 'when feature is disabled' do
+ before do
+ stub_feature_flags(specialized_project_authorization_project_share_worker: false)
+ end
+
+ it 'uses AuthorizedProjectsWorker' do
+ expect(AuthorizedProjectsWorker).to(
+ receive(:bulk_perform_async).with(array_including([user.id], [other_user.id])).and_call_original
+ )
+ expect(AuthorizedProjectUpdate::ProjectCreateWorker).not_to(
+ receive(:perform_async)
+ )
+ expect(AuthorizedProjectUpdate::UserRefreshWithLowUrgencyWorker).not_to(
+ receive(:bulk_perform_in)
+ )
+
+ subject.execute(group)
+ end
+ end
+ end
end
diff --git a/spec/services/projects/group_links/destroy_service_spec.rb b/spec/services/projects/group_links/destroy_service_spec.rb
index 0a8c9580e70..459b79b2d7d 100644
--- a/spec/services/projects/group_links/destroy_service_spec.rb
+++ b/spec/services/projects/group_links/destroy_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::GroupLinks::DestroyService, '#execute' do
+RSpec.describe Projects::GroupLinks::DestroyService, '#execute' do
let_it_be(:user) { create :user }
let_it_be(:project) { create(:project, :private) }
let_it_be(:group) { create(:group) }
diff --git a/spec/services/projects/group_links/update_service_spec.rb b/spec/services/projects/group_links/update_service_spec.rb
index 5be2ae1e0f7..053c5eb611e 100644
--- a/spec/services/projects/group_links/update_service_spec.rb
+++ b/spec/services/projects/group_links/update_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::GroupLinks::UpdateService, '#execute' do
+RSpec.describe Projects::GroupLinks::UpdateService, '#execute' do
let_it_be(:user) { create :user }
let_it_be(:group) { create :group }
let_it_be(:project) { create :project }
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 070dd5fc1b8..5e1b6f2e404 100644
--- a/spec/services/projects/hashed_storage/base_attachment_service_spec.rb
+++ b/spec/services/projects/hashed_storage/base_attachment_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::HashedStorage::BaseAttachmentService do
+RSpec.describe Projects::HashedStorage::BaseAttachmentService do
let(:project) { create(:project, :repository, storage_version: 0, skip_disk_validation: true) }
subject(:service) { described_class.new(project: project, old_disk_path: project.full_path, logger: nil) }
diff --git a/spec/services/projects/hashed_storage/migrate_attachments_service_spec.rb b/spec/services/projects/hashed_storage/migrate_attachments_service_spec.rb
index 7c7e188a12d..c8f24c6ce00 100644
--- a/spec/services/projects/hashed_storage/migrate_attachments_service_spec.rb
+++ b/spec/services/projects/hashed_storage/migrate_attachments_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::HashedStorage::MigrateAttachmentsService do
+RSpec.describe Projects::HashedStorage::MigrateAttachmentsService do
subject(:service) { described_class.new(project: project, old_disk_path: project.full_path, logger: nil) }
let(:project) { create(:project, :repository, storage_version: 1, skip_disk_validation: true) }
diff --git a/spec/services/projects/hashed_storage/migrate_repository_service_spec.rb b/spec/services/projects/hashed_storage/migrate_repository_service_spec.rb
index f1eaf8324e0..e03e75653ff 100644
--- a/spec/services/projects/hashed_storage/migrate_repository_service_spec.rb
+++ b/spec/services/projects/hashed_storage/migrate_repository_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::HashedStorage::MigrateRepositoryService do
+RSpec.describe Projects::HashedStorage::MigrateRepositoryService do
include GitHelpers
let(:gitlab_shell) { Gitlab::Shell.new }
diff --git a/spec/services/projects/hashed_storage/migration_service_spec.rb b/spec/services/projects/hashed_storage/migration_service_spec.rb
index 0a7975305dc..ef96c17dd85 100644
--- a/spec/services/projects/hashed_storage/migration_service_spec.rb
+++ b/spec/services/projects/hashed_storage/migration_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::HashedStorage::MigrationService do
+RSpec.describe Projects::HashedStorage::MigrationService do
let(:project) { create(:project, :empty_repo, :wiki_repo, :legacy_storage) }
let(:logger) { double }
let!(:project_attachment) { build(:file_uploader, project: project) }
diff --git a/spec/services/projects/hashed_storage/rollback_attachments_service_spec.rb b/spec/services/projects/hashed_storage/rollback_attachments_service_spec.rb
index 54695e6e48f..d4cb46c82ad 100644
--- a/spec/services/projects/hashed_storage/rollback_attachments_service_spec.rb
+++ b/spec/services/projects/hashed_storage/rollback_attachments_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::HashedStorage::RollbackAttachmentsService do
+RSpec.describe Projects::HashedStorage::RollbackAttachmentsService do
subject(:service) { described_class.new(project: project, old_disk_path: project.disk_path, logger: nil) }
let(:project) { create(:project, :repository, skip_disk_validation: true) }
diff --git a/spec/services/projects/hashed_storage/rollback_repository_service_spec.rb b/spec/services/projects/hashed_storage/rollback_repository_service_spec.rb
index 1c0f446d9cf..f2b1ce30a54 100644
--- a/spec/services/projects/hashed_storage/rollback_repository_service_spec.rb
+++ b/spec/services/projects/hashed_storage/rollback_repository_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::HashedStorage::RollbackRepositoryService, :clean_gitlab_redis_shared_state do
+RSpec.describe Projects::HashedStorage::RollbackRepositoryService, :clean_gitlab_redis_shared_state do
include GitHelpers
let(:gitlab_shell) { Gitlab::Shell.new }
diff --git a/spec/services/projects/hashed_storage/rollback_service_spec.rb b/spec/services/projects/hashed_storage/rollback_service_spec.rb
index e6b7daba99e..0bd63f2da2a 100644
--- a/spec/services/projects/hashed_storage/rollback_service_spec.rb
+++ b/spec/services/projects/hashed_storage/rollback_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::HashedStorage::RollbackService do
+RSpec.describe Projects::HashedStorage::RollbackService do
let(:project) { create(:project, :empty_repo, :wiki_repo) }
let(:logger) { double }
let!(:project_attachment) { build(:file_uploader, project: project) }
diff --git a/spec/services/projects/housekeeping_service_spec.rb b/spec/services/projects/housekeeping_service_spec.rb
index 98a27a71c26..18871f010f8 100644
--- a/spec/services/projects/housekeeping_service_spec.rb
+++ b/spec/services/projects/housekeeping_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::HousekeepingService do
+RSpec.describe Projects::HousekeepingService do
subject { described_class.new(project) }
let_it_be(:project) { create(:project, :repository) }
diff --git a/spec/services/projects/import_error_filter_spec.rb b/spec/services/projects/import_error_filter_spec.rb
index 312b658de89..fd31cd52cc4 100644
--- a/spec/services/projects/import_error_filter_spec.rb
+++ b/spec/services/projects/import_error_filter_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::ImportErrorFilter do
+RSpec.describe Projects::ImportErrorFilter do
it 'filters any full paths' do
message = 'Error importing into /my/folder Permission denied @ unlink_internal - /var/opt/gitlab/gitlab-rails/shared/a/b/c/uploads/file'
diff --git a/spec/services/projects/import_export/export_service_spec.rb b/spec/services/projects/import_export/export_service_spec.rb
index 19891341311..111c1264777 100644
--- a/spec/services/projects/import_export/export_service_spec.rb
+++ b/spec/services/projects/import_export/export_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::ImportExport::ExportService do
+RSpec.describe Projects::ImportExport::ExportService do
describe '#execute' do
let!(:user) { create(:user) }
let(:project) { create(:project) }
diff --git a/spec/services/projects/import_service_spec.rb b/spec/services/projects/import_service_spec.rb
index ca6750b373d..92e18b6cb46 100644
--- a/spec/services/projects/import_service_spec.rb
+++ b/spec/services/projects/import_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::ImportService do
+RSpec.describe Projects::ImportService do
let!(:project) { create(:project) }
let(:user) { project.creator }
diff --git a/spec/services/projects/lfs_pointers/lfs_download_link_list_service_spec.rb b/spec/services/projects/lfs_pointers/lfs_download_link_list_service_spec.rb
index 99d35fdc7f7..66a450bd734 100644
--- a/spec/services/projects/lfs_pointers/lfs_download_link_list_service_spec.rb
+++ b/spec/services/projects/lfs_pointers/lfs_download_link_list_service_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
require 'spec_helper'
-describe Projects::LfsPointers::LfsDownloadLinkListService do
+RSpec.describe Projects::LfsPointers::LfsDownloadLinkListService do
let(:import_url) { 'http://www.gitlab.com/demo/repo.git' }
let(:lfs_endpoint) { "#{import_url}/info/lfs/objects/batch" }
let!(:project) { create(:project, import_url: import_url) }
diff --git a/spec/services/projects/lfs_pointers/lfs_download_service_spec.rb b/spec/services/projects/lfs_pointers/lfs_download_service_spec.rb
index 496d1fe67f2..a606371099d 100644
--- a/spec/services/projects/lfs_pointers/lfs_download_service_spec.rb
+++ b/spec/services/projects/lfs_pointers/lfs_download_service_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
require 'spec_helper'
-describe Projects::LfsPointers::LfsDownloadService do
+RSpec.describe Projects::LfsPointers::LfsDownloadService do
include StubRequests
let(:project) { create(:project) }
diff --git a/spec/services/projects/lfs_pointers/lfs_import_service_spec.rb b/spec/services/projects/lfs_pointers/lfs_import_service_spec.rb
index 016028a96bf..b36b0b8d6b2 100644
--- a/spec/services/projects/lfs_pointers/lfs_import_service_spec.rb
+++ b/spec/services/projects/lfs_pointers/lfs_import_service_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
require 'spec_helper'
-describe Projects::LfsPointers::LfsImportService do
+RSpec.describe Projects::LfsPointers::LfsImportService do
let(:project) { create(:project) }
let(:user) { project.creator }
let(:import_url) { 'http://www.gitlab.com/demo/repo.git' }
diff --git a/spec/services/projects/lfs_pointers/lfs_link_service_spec.rb b/spec/services/projects/lfs_pointers/lfs_link_service_spec.rb
index b64662f3782..d59f5dbae19 100644
--- a/spec/services/projects/lfs_pointers/lfs_link_service_spec.rb
+++ b/spec/services/projects/lfs_pointers/lfs_link_service_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
require 'spec_helper'
-describe Projects::LfsPointers::LfsLinkService do
+RSpec.describe Projects::LfsPointers::LfsLinkService do
let!(:project) { create(:project, lfs_enabled: true) }
let!(:lfs_objects_project) { create_list(:lfs_objects_project, 2, project: project) }
let(:new_oids) { { 'oid1' => 123, 'oid2' => 125 } }
diff --git a/spec/services/projects/lfs_pointers/lfs_object_download_list_service_spec.rb b/spec/services/projects/lfs_pointers/lfs_object_download_list_service_spec.rb
index e94d8a85987..0799a33f856 100644
--- a/spec/services/projects/lfs_pointers/lfs_object_download_list_service_spec.rb
+++ b/spec/services/projects/lfs_pointers/lfs_object_download_list_service_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
require 'spec_helper'
-describe Projects::LfsPointers::LfsObjectDownloadListService do
+RSpec.describe Projects::LfsPointers::LfsObjectDownloadListService do
let(:import_url) { 'http://www.gitlab.com/demo/repo.git' }
let(:default_endpoint) { "#{import_url}/info/lfs/objects/batch"}
let(:group) { create(:group, lfs_enabled: true)}
diff --git a/spec/services/projects/move_access_service_spec.rb b/spec/services/projects/move_access_service_spec.rb
index efa34c84522..de3871414af 100644
--- a/spec/services/projects/move_access_service_spec.rb
+++ b/spec/services/projects/move_access_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::MoveAccessService do
+RSpec.describe Projects::MoveAccessService do
let(:user) { create(:user) }
let(:group) { create(:group) }
let(:project_with_access) { create(:project, namespace: user.namespace) }
diff --git a/spec/services/projects/move_deploy_keys_projects_service_spec.rb b/spec/services/projects/move_deploy_keys_projects_service_spec.rb
index a5d28fb0fbf..e69b4dd4fc7 100644
--- a/spec/services/projects/move_deploy_keys_projects_service_spec.rb
+++ b/spec/services/projects/move_deploy_keys_projects_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::MoveDeployKeysProjectsService do
+RSpec.describe Projects::MoveDeployKeysProjectsService do
let!(:user) { create(:user) }
let!(:project_with_deploy_keys) { create(:project, namespace: user.namespace) }
let!(:target_project) { create(:project, namespace: user.namespace) }
diff --git a/spec/services/projects/move_forks_service_spec.rb b/spec/services/projects/move_forks_service_spec.rb
index 8f9f048d5ff..7d3637b7758 100644
--- a/spec/services/projects/move_forks_service_spec.rb
+++ b/spec/services/projects/move_forks_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::MoveForksService do
+RSpec.describe Projects::MoveForksService do
include ProjectForksHelper
let!(:user) { create(:user) }
diff --git a/spec/services/projects/move_lfs_objects_projects_service_spec.rb b/spec/services/projects/move_lfs_objects_projects_service_spec.rb
index 114509229c5..b73286fba9a 100644
--- a/spec/services/projects/move_lfs_objects_projects_service_spec.rb
+++ b/spec/services/projects/move_lfs_objects_projects_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::MoveLfsObjectsProjectsService do
+RSpec.describe Projects::MoveLfsObjectsProjectsService do
let!(:user) { create(:user) }
let!(:project_with_lfs_objects) { create(:project, namespace: user.namespace) }
let!(:target_project) { create(:project, namespace: user.namespace) }
diff --git a/spec/services/projects/move_notification_settings_service_spec.rb b/spec/services/projects/move_notification_settings_service_spec.rb
index 54d85404bf6..7c9f1dd30d2 100644
--- a/spec/services/projects/move_notification_settings_service_spec.rb
+++ b/spec/services/projects/move_notification_settings_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::MoveNotificationSettingsService do
+RSpec.describe Projects::MoveNotificationSettingsService do
let(:user) { create(:user) }
let(:project_with_notifications) { create(:project, namespace: user.namespace) }
let(:target_project) { create(:project, namespace: user.namespace) }
diff --git a/spec/services/projects/move_project_authorizations_service_spec.rb b/spec/services/projects/move_project_authorizations_service_spec.rb
index fe3ba31c881..a37b4d807a0 100644
--- a/spec/services/projects/move_project_authorizations_service_spec.rb
+++ b/spec/services/projects/move_project_authorizations_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::MoveProjectAuthorizationsService do
+RSpec.describe Projects::MoveProjectAuthorizationsService do
let!(:user) { create(:user) }
let(:project_with_users) { create(:project, namespace: user.namespace) }
let(:target_project) { create(:project, namespace: user.namespace) }
diff --git a/spec/services/projects/move_project_group_links_service_spec.rb b/spec/services/projects/move_project_group_links_service_spec.rb
index 6140d679929..196a8f2b339 100644
--- a/spec/services/projects/move_project_group_links_service_spec.rb
+++ b/spec/services/projects/move_project_group_links_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::MoveProjectGroupLinksService do
+RSpec.describe Projects::MoveProjectGroupLinksService do
let!(:user) { create(:user) }
let(:project_with_groups) { create(:project, namespace: user.namespace) }
let(:target_project) { create(:project, namespace: user.namespace) }
diff --git a/spec/services/projects/move_project_members_service_spec.rb b/spec/services/projects/move_project_members_service_spec.rb
index bdd5cd6a87a..f14f00e3866 100644
--- a/spec/services/projects/move_project_members_service_spec.rb
+++ b/spec/services/projects/move_project_members_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::MoveProjectMembersService do
+RSpec.describe Projects::MoveProjectMembersService do
let!(:user) { create(:user) }
let(:project_with_users) { create(:project, namespace: user.namespace) }
let(:target_project) { create(:project, namespace: user.namespace) }
diff --git a/spec/services/projects/move_users_star_projects_service_spec.rb b/spec/services/projects/move_users_star_projects_service_spec.rb
index cde188f9f5f..0f766ebd0ec 100644
--- a/spec/services/projects/move_users_star_projects_service_spec.rb
+++ b/spec/services/projects/move_users_star_projects_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::MoveUsersStarProjectsService do
+RSpec.describe Projects::MoveUsersStarProjectsService do
let!(:user) { create(:user) }
let!(:project_with_stars) { create(:project, namespace: user.namespace) }
let!(:target_project) { create(:project, namespace: user.namespace) }
diff --git a/spec/services/projects/open_issues_count_service_spec.rb b/spec/services/projects/open_issues_count_service_spec.rb
index c1d49befeb9..c739fea5ecf 100644
--- a/spec/services/projects/open_issues_count_service_spec.rb
+++ b/spec/services/projects/open_issues_count_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::OpenIssuesCountService, :use_clean_rails_memory_store_caching do
+RSpec.describe Projects::OpenIssuesCountService, :use_clean_rails_memory_store_caching do
let(:project) { create(:project) }
subject { described_class.new(project) }
diff --git a/spec/services/projects/open_merge_requests_count_service_spec.rb b/spec/services/projects/open_merge_requests_count_service_spec.rb
index 7d848f9f2c3..6caef181e77 100644
--- a/spec/services/projects/open_merge_requests_count_service_spec.rb
+++ b/spec/services/projects/open_merge_requests_count_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::OpenMergeRequestsCountService, :use_clean_rails_memory_store_caching do
+RSpec.describe Projects::OpenMergeRequestsCountService, :use_clean_rails_memory_store_caching do
let_it_be(:project) { create(:project) }
subject { described_class.new(project) }
diff --git a/spec/services/projects/operations/update_service_spec.rb b/spec/services/projects/operations/update_service_spec.rb
index f4d62b48fe5..3cfc9844d65 100644
--- a/spec/services/projects/operations/update_service_spec.rb
+++ b/spec/services/projects/operations/update_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::Operations::UpdateService do
+RSpec.describe Projects::Operations::UpdateService do
let_it_be(:user) { create(:user) }
let_it_be(:project, refind: true) { create(:project) }
diff --git a/spec/services/projects/overwrite_project_service_spec.rb b/spec/services/projects/overwrite_project_service_spec.rb
index def39ad3789..e4495da9807 100644
--- a/spec/services/projects/overwrite_project_service_spec.rb
+++ b/spec/services/projects/overwrite_project_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::OverwriteProjectService do
+RSpec.describe Projects::OverwriteProjectService do
include ProjectForksHelper
let(:user) { create(:user) }
diff --git a/spec/services/projects/participants_service_spec.rb b/spec/services/projects/participants_service_spec.rb
index f4a04159db4..33a3e37a2d2 100644
--- a/spec/services/projects/participants_service_spec.rb
+++ b/spec/services/projects/participants_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::ParticipantsService do
+RSpec.describe Projects::ParticipantsService do
describe '#groups' do
let_it_be(:user) { create(:user) }
let_it_be(:project) { create(:project, :public) }
diff --git a/spec/services/projects/prometheus/alerts/create_events_service_spec.rb b/spec/services/projects/prometheus/alerts/create_events_service_spec.rb
deleted file mode 100644
index 61236b5bbdb..00000000000
--- a/spec/services/projects/prometheus/alerts/create_events_service_spec.rb
+++ /dev/null
@@ -1,312 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-describe Projects::Prometheus::Alerts::CreateEventsService do
- let(:user) { create(:user) }
- let_it_be(:project) { create(:project) }
- let(:metric) { create(:prometheus_metric, project: project) }
- let(:service) { described_class.new(project, user, alerts_payload) }
-
- shared_examples 'events persisted' do |expected_count|
- subject { service.execute }
-
- it 'returns proper amount of created events' do
- expect(subject.size).to eq(expected_count)
- end
-
- it 'increments event count' do
- expect { subject }.to change { PrometheusAlertEvent.count }.to(expected_count)
- end
- end
-
- shared_examples 'no events persisted' do
- subject { service.execute }
-
- it 'returns no created events' do
- expect(subject).to be_empty
- end
-
- it 'does not change event count' do
- expect { subject }.not_to change { PrometheusAlertEvent.count }
- end
- end
-
- shared_examples 'self managed events persisted' do
- subject { service.execute }
-
- it 'returns created events' do
- expect(subject).not_to be_empty
- end
-
- it 'does change self managed event count' do
- expect { subject }.to change { SelfManagedPrometheusAlertEvent.count }
- end
- end
-
- context 'with valid alerts_payload' do
- let!(:alert) { create(:prometheus_alert, prometheus_metric: metric, project: project) }
-
- let(:events) { service.execute }
-
- context 'with a firing payload' do
- let(:started_at) { truncate_to_second(Time.current) }
- let(:firing_event) { alert_payload(status: 'firing', started_at: started_at) }
- let(:alerts_payload) { { 'alerts' => [firing_event] } }
-
- it_behaves_like 'events persisted', 1
-
- it 'returns created event' do
- event = events.first
-
- expect(event).to be_firing
- expect(event.started_at).to eq(started_at)
- expect(event.ended_at).to be_nil
- end
-
- context 'with 2 different firing events' do
- let(:another_firing_event) { alert_payload(status: 'firing', started_at: started_at + 1) }
- let(:alerts_payload) { { 'alerts' => [firing_event, another_firing_event] } }
-
- it_behaves_like 'events persisted', 2
- end
-
- context 'with already persisted firing event' do
- before do
- service.execute
- end
-
- it_behaves_like 'no events persisted'
- end
-
- context 'with duplicate payload' do
- let(:alerts_payload) { { 'alerts' => [firing_event, firing_event] } }
-
- it_behaves_like 'events persisted', 1
- end
- end
-
- context 'with a resolved payload' do
- let(:started_at) { truncate_to_second(Time.current) }
- let(:ended_at) { started_at + 1 }
- let(:resolved_event) { alert_payload(status: 'resolved', started_at: started_at, ended_at: ended_at) }
- let(:alerts_payload) { { 'alerts' => [resolved_event] } }
- let(:payload_key) { Gitlab::Alerting::Alert.new(project: project, payload: resolved_event).gitlab_fingerprint }
-
- context 'with a matching firing event' do
- before do
- create(:prometheus_alert_event,
- prometheus_alert: alert,
- payload_key: payload_key,
- started_at: started_at)
- end
-
- it 'does not create an additional event' do
- expect { service.execute }.not_to change { PrometheusAlertEvent.count }
- end
-
- it 'marks firing event as `resolved`' do
- expect(events.size).to eq(1)
-
- event = events.first
- expect(event).to be_resolved
- expect(event.started_at).to eq(started_at)
- expect(event.ended_at).to eq(ended_at)
- end
-
- context 'with duplicate payload' do
- let(:alerts_payload) { { 'alerts' => [resolved_event, resolved_event] } }
-
- it 'does not create an additional event' do
- expect { service.execute }.not_to change { PrometheusAlertEvent.count }
- end
-
- it 'marks firing event as `resolved` only once' do
- expect(events.size).to eq(1)
- end
- end
- end
-
- context 'without a matching firing event' do
- context 'due to payload_key' do
- let(:payload_key) { 'some other payload_key' }
-
- before do
- create(:prometheus_alert_event,
- prometheus_alert: alert,
- payload_key: payload_key,
- started_at: started_at)
- end
-
- it_behaves_like 'no events persisted'
- end
-
- context 'due to status' do
- before do
- create(:prometheus_alert_event, :resolved,
- prometheus_alert: alert,
- started_at: started_at)
- end
-
- it_behaves_like 'no events persisted'
- end
- end
-
- context 'with already resolved event' do
- before do
- service.execute
- end
-
- it_behaves_like 'no events persisted'
- end
- end
-
- context 'with a metric from another project' do
- let(:another_project) { create(:project) }
- let(:metric) { create(:prometheus_metric, project: another_project) }
- let(:alerts_payload) { { 'alerts' => [alert_payload] } }
-
- let!(:alert) do
- create(:prometheus_alert,
- prometheus_metric: metric,
- project: another_project)
- end
-
- it_behaves_like 'no events persisted'
- end
- end
-
- context 'with invalid payload' do
- let(:alert) { create(:prometheus_alert, prometheus_metric: metric, project: project) }
-
- describe '`alerts` key' do
- context 'is missing' do
- let(:alerts_payload) { {} }
-
- it_behaves_like 'no events persisted'
- end
-
- context 'is nil' do
- let(:alerts_payload) { { 'alerts' => nil } }
-
- it_behaves_like 'no events persisted'
- end
-
- context 'is empty' do
- let(:alerts_payload) { { 'alerts' => [] } }
-
- it_behaves_like 'no events persisted'
- end
-
- context 'is not a Hash' do
- let(:alerts_payload) { { 'alerts' => [:not_a_hash] } }
-
- it_behaves_like 'no events persisted'
- end
-
- describe '`status`' do
- context 'is missing' do
- let(:alerts_payload) { { 'alerts' => [alert_payload(status: nil)] } }
-
- it_behaves_like 'no events persisted'
- end
-
- context 'is invalid' do
- let(:alerts_payload) { { 'alerts' => [alert_payload(status: 'invalid')] } }
-
- it_behaves_like 'no events persisted'
- end
- end
-
- describe '`started_at`' do
- context 'is missing' do
- let(:alerts_payload) { { 'alerts' => [alert_payload(started_at: nil)] } }
-
- it_behaves_like 'no events persisted'
- end
-
- context 'is invalid' do
- let(:alerts_payload) { { 'alerts' => [alert_payload(started_at: 'invalid date')] } }
-
- it_behaves_like 'no events persisted'
- end
- end
-
- describe '`ended_at`' do
- context 'is missing and status is resolved' do
- let(:alerts_payload) { { 'alerts' => [alert_payload(ended_at: nil, status: 'resolved')] } }
-
- it_behaves_like 'no events persisted'
- end
-
- context 'is invalid and status is resolved' do
- let(:alerts_payload) { { 'alerts' => [alert_payload(ended_at: 'invalid date', status: 'resolved')] } }
-
- it_behaves_like 'no events persisted'
- end
- end
-
- describe '`labels`' do
- describe '`gitlab_alert_id`' do
- context 'is missing' do
- let(:alerts_payload) { { 'alerts' => [alert_payload(gitlab_alert_id: nil)] } }
-
- it_behaves_like 'no events persisted'
- end
-
- context 'is missing but title is given' do
- let(:alerts_payload) { { 'alerts' => [alert_payload(gitlab_alert_id: nil, title: 'alert')] } }
-
- it_behaves_like 'self managed events persisted'
- end
-
- context 'is missing and environment name is given' do
- let(:environment) { create(:environment, project: project) }
- let(:alerts_payload) { { 'alerts' => [alert_payload(gitlab_alert_id: nil, title: 'alert', environment: environment.name)] } }
-
- it_behaves_like 'self managed events persisted'
-
- it 'associates the environment to the alert event' do
- service.execute
-
- expect(SelfManagedPrometheusAlertEvent.last.environment).to eq environment
- end
- end
-
- context 'is invalid' do
- let(:alerts_payload) { { 'alerts' => [alert_payload(gitlab_alert_id: '-1')] } }
-
- it_behaves_like 'no events persisted'
- end
- end
- end
- end
- end
-
- private
-
- def alert_payload(status: 'firing', started_at: Time.current, ended_at: Time.current, gitlab_alert_id: alert.prometheus_metric_id, title: nil, environment: nil)
- payload = {}
-
- payload['status'] = status if status
- payload['startsAt'] = utc_rfc3339(started_at) if started_at
- payload['endsAt'] = utc_rfc3339(ended_at) if ended_at
- payload['labels'] = {}
- payload['labels']['gitlab_alert_id'] = gitlab_alert_id.to_s if gitlab_alert_id
- payload['labels']['alertname'] = title if title
- payload['labels']['gitlab_environment_name'] = environment if environment
-
- payload
- end
-
- # Example: 2018-09-27T18:25:31.079079416Z
- def utc_rfc3339(date)
- date.utc.rfc3339
- rescue
- date
- end
-
- def truncate_to_second(date)
- date.change(usec: 0)
- end
-end
diff --git a/spec/services/projects/prometheus/alerts/create_service_spec.rb b/spec/services/projects/prometheus/alerts/create_service_spec.rb
index 50c776df734..c0bc9336558 100644
--- a/spec/services/projects/prometheus/alerts/create_service_spec.rb
+++ b/spec/services/projects/prometheus/alerts/create_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::Prometheus::Alerts::CreateService do
+RSpec.describe Projects::Prometheus::Alerts::CreateService do
let_it_be(:project) { create(:project) }
let_it_be(:user) { create(:user) }
diff --git a/spec/services/projects/prometheus/alerts/destroy_service_spec.rb b/spec/services/projects/prometheus/alerts/destroy_service_spec.rb
index 7205ace8308..573711051b7 100644
--- a/spec/services/projects/prometheus/alerts/destroy_service_spec.rb
+++ b/spec/services/projects/prometheus/alerts/destroy_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::Prometheus::Alerts::DestroyService do
+RSpec.describe Projects::Prometheus::Alerts::DestroyService do
let_it_be(:project) { create(:project) }
let_it_be(:user) { create(:user) }
let_it_be(:alert) { create(:prometheus_alert, project: project) }
diff --git a/spec/services/projects/prometheus/alerts/notify_service_spec.rb b/spec/services/projects/prometheus/alerts/notify_service_spec.rb
index 95acedb1e76..aae257e3e3a 100644
--- a/spec/services/projects/prometheus/alerts/notify_service_spec.rb
+++ b/spec/services/projects/prometheus/alerts/notify_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::Prometheus::Alerts::NotifyService do
+RSpec.describe Projects::Prometheus::Alerts::NotifyService do
include PrometheusHelpers
let_it_be(:project, reload: true) { create(:project) }
@@ -36,48 +36,8 @@ describe Projects::Prometheus::Alerts::NotifyService do
end
end
- shared_examples 'processes incident issues' do |amount|
- let(:create_incident_service) { spy }
-
- it 'processes issues' do
- expect(IncidentManagement::ProcessPrometheusAlertWorker)
- .to receive(:perform_async)
- .with(project.id, kind_of(Hash))
- .exactly(amount).times
-
- Sidekiq::Testing.inline! do
- expect(subject).to be_success
- end
- end
- end
-
- shared_examples 'does not process incident issues' do
- it 'does not process issues' do
- expect(IncidentManagement::ProcessPrometheusAlertWorker)
- .not_to receive(:perform_async)
-
- expect(subject).to be_success
- end
- end
-
- shared_examples 'persists events' do
- let(:create_events_service) { spy }
-
- it 'persists events' do
- expect(Projects::Prometheus::Alerts::CreateEventsService)
- .to receive(:new)
- .and_return(create_events_service)
-
- expect(create_events_service)
- .to receive(:execute)
-
- expect(subject).to be_success
- end
- end
-
shared_examples 'notifies alerts' do
it_behaves_like 'sends notification email'
- it_behaves_like 'persists events'
end
shared_examples 'no notifications' do |http_status:|
@@ -102,6 +62,41 @@ describe Projects::Prometheus::Alerts::NotifyService do
let(:payload_alert_firing) { payload_raw['alerts'].first }
let(:token) { 'token' }
+ context 'with environment specific clusters' do
+ let(:prd_cluster) do
+ cluster
+ end
+
+ let(:stg_cluster) do
+ create(:cluster, :provided_by_user, projects: [project], enabled: true, environment_scope: 'stg/*')
+ end
+
+ let(:stg_environment) do
+ create(:environment, project: project, name: 'stg/1')
+ end
+
+ let(:alert_firing) do
+ create(:prometheus_alert, project: project, environment: stg_environment)
+ end
+
+ before do
+ create(:clusters_applications_prometheus, :installed,
+ cluster: prd_cluster, alert_manager_token: token)
+ create(:clusters_applications_prometheus, :installed,
+ cluster: stg_cluster, alert_manager_token: nil)
+ end
+
+ context 'without token' do
+ let(:token_input) { nil }
+
+ it_behaves_like 'notifies alerts'
+ end
+
+ context 'with token' do
+ it_behaves_like 'no notifications', http_status: :unauthorized
+ end
+ end
+
context 'with project specific cluster' do
using RSpec::Parameterized::TableSyntax
@@ -222,8 +217,6 @@ describe Projects::Prometheus::Alerts::NotifyService do
context 'when incident_management_setting does not exist' do
let!(:setting) { nil }
- it_behaves_like 'persists events'
-
it 'does not send notification email', :sidekiq_might_not_need_inline do
expect_any_instance_of(NotificationService)
.not_to receive(:async)
@@ -241,8 +234,6 @@ describe Projects::Prometheus::Alerts::NotifyService do
create(:project_incident_management_setting, send_email: false, project: project)
end
- it_behaves_like 'persists events'
-
it 'does not send notification' do
expect(NotificationService).not_to receive(:new)
@@ -276,45 +267,6 @@ describe Projects::Prometheus::Alerts::NotifyService do
end
end
end
-
- context 'process incident issues' do
- before do
- create(:prometheus_service, project: project)
- create(:project_alerting_setting, project: project, token: token)
- end
-
- context 'with create_issue setting enabled' do
- before do
- setting.update!(create_issue: true)
- end
-
- it_behaves_like 'processes incident issues', 2
-
- context 'multiple firing alerts' do
- let(:payload_raw) do
- prometheus_alert_payload(firing: [alert_firing, alert_firing], resolved: [])
- end
-
- it_behaves_like 'processes incident issues', 2
- end
-
- context 'without firing alerts' do
- let(:payload_raw) do
- prometheus_alert_payload(firing: [], resolved: [alert_resolved])
- end
-
- it_behaves_like 'processes incident issues', 1
- end
- end
-
- context 'with create_issue setting disabled' do
- before do
- setting.update!(create_issue: false)
- end
-
- it_behaves_like 'does not process incident issues'
- end
- end
end
context 'with invalid payload' do
@@ -345,13 +297,6 @@ describe Projects::Prometheus::Alerts::NotifyService do
subject
end
-
- it 'does not process issues' do
- expect(IncidentManagement::ProcessPrometheusAlertWorker)
- .not_to receive(:perform_async)
-
- subject
- end
end
end
diff --git a/spec/services/projects/prometheus/alerts/update_service_spec.rb b/spec/services/projects/prometheus/alerts/update_service_spec.rb
index 8a99c2679f7..e831d001838 100644
--- a/spec/services/projects/prometheus/alerts/update_service_spec.rb
+++ b/spec/services/projects/prometheus/alerts/update_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::Prometheus::Alerts::UpdateService do
+RSpec.describe Projects::Prometheus::Alerts::UpdateService do
let_it_be(:project) { create(:project) }
let_it_be(:user) { create(:user) }
let_it_be(:environment) { create(:environment, project: project) }
diff --git a/spec/services/projects/prometheus/metrics/destroy_service_spec.rb b/spec/services/projects/prometheus/metrics/destroy_service_spec.rb
index 81fce82cf46..17cc88b27b6 100644
--- a/spec/services/projects/prometheus/metrics/destroy_service_spec.rb
+++ b/spec/services/projects/prometheus/metrics/destroy_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::Prometheus::Metrics::DestroyService do
+RSpec.describe Projects::Prometheus::Metrics::DestroyService do
let(:metric) { create(:prometheus_metric) }
subject { described_class.new(metric) }
diff --git a/spec/services/projects/prometheus/metrics/update_service_spec.rb b/spec/services/projects/prometheus/metrics/update_service_spec.rb
index a53c6ae37cd..bf87093150c 100644
--- a/spec/services/projects/prometheus/metrics/update_service_spec.rb
+++ b/spec/services/projects/prometheus/metrics/update_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::Prometheus::Metrics::UpdateService do
+RSpec.describe Projects::Prometheus::Metrics::UpdateService do
let(:metric) { create(:prometheus_metric) }
it 'updates the prometheus metric' do
diff --git a/spec/services/projects/propagate_service_template_spec.rb b/spec/services/projects/propagate_service_template_spec.rb
index ddc27c037f8..266bf2cc213 100644
--- a/spec/services/projects/propagate_service_template_spec.rb
+++ b/spec/services/projects/propagate_service_template_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::PropagateServiceTemplate do
+RSpec.describe Projects::PropagateServiceTemplate do
describe '.propagate' do
let!(:service_template) do
PushoverService.create(
diff --git a/spec/services/projects/protect_default_branch_service_spec.rb b/spec/services/projects/protect_default_branch_service_spec.rb
index c0b819ab17b..a485a64ca35 100644
--- a/spec/services/projects/protect_default_branch_service_spec.rb
+++ b/spec/services/projects/protect_default_branch_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::ProtectDefaultBranchService do
+RSpec.describe Projects::ProtectDefaultBranchService do
let(:service) { described_class.new(project) }
let(:project) { create(:project) }
diff --git a/spec/services/projects/repository_languages_service_spec.rb b/spec/services/projects/repository_languages_service_spec.rb
index 46c5095327d..cb61a7a1a3e 100644
--- a/spec/services/projects/repository_languages_service_spec.rb
+++ b/spec/services/projects/repository_languages_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::RepositoryLanguagesService do
+RSpec.describe Projects::RepositoryLanguagesService do
let(:service) { described_class.new(project, project.owner) }
context 'when detected_repository_languages flag is set' do
diff --git a/spec/services/projects/transfer_service_spec.rb b/spec/services/projects/transfer_service_spec.rb
index 0e2431c0e44..72426a6f6ec 100644
--- a/spec/services/projects/transfer_service_spec.rb
+++ b/spec/services/projects/transfer_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::TransferService do
+RSpec.describe Projects::TransferService do
include GitHelpers
let(:user) { create(:user) }
diff --git a/spec/services/projects/unlink_fork_service_spec.rb b/spec/services/projects/unlink_fork_service_spec.rb
index a6bdc69cdca..6a2c55a5e55 100644
--- a/spec/services/projects/unlink_fork_service_spec.rb
+++ b/spec/services/projects/unlink_fork_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::UnlinkForkService, :use_clean_rails_memory_store_caching do
+RSpec.describe Projects::UnlinkForkService, :use_clean_rails_memory_store_caching do
include ProjectForksHelper
subject { described_class.new(forked_project, user) }
@@ -53,6 +53,7 @@ describe Projects::UnlinkForkService, :use_clean_rails_memory_store_caching do
expect(source.forks_count).to eq(1)
subject.execute
+ BatchLoader::Executor.clear_current
expect(source.forks_count).to be_zero
end
@@ -146,6 +147,7 @@ describe Projects::UnlinkForkService, :use_clean_rails_memory_store_caching do
expect(project.forks_count).to eq(2)
subject.execute
+ BatchLoader::Executor.clear_current
expect(project.forks_count).to be_zero
end
@@ -212,6 +214,7 @@ describe Projects::UnlinkForkService, :use_clean_rails_memory_store_caching do
expect(forked_project.forks_count).to eq(1)
subject.execute
+ BatchLoader::Executor.clear_current
expect(project.forks_count).to eq(1)
expect(forked_project.forks_count).to eq(0)
diff --git a/spec/services/projects/update_pages_configuration_service_spec.rb b/spec/services/projects/update_pages_configuration_service_spec.rb
index 363d3df0f84..c4c9fc779fa 100644
--- a/spec/services/projects/update_pages_configuration_service_spec.rb
+++ b/spec/services/projects/update_pages_configuration_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::UpdatePagesConfigurationService do
+RSpec.describe Projects::UpdatePagesConfigurationService do
let(:project) { create(:project) }
let(:service) { described_class.new(project) }
diff --git a/spec/services/projects/update_pages_service_spec.rb b/spec/services/projects/update_pages_service_spec.rb
index 29c3c300d1b..2e02cb56668 100644
--- a/spec/services/projects/update_pages_service_spec.rb
+++ b/spec/services/projects/update_pages_service_spec.rb
@@ -2,7 +2,7 @@
require "spec_helper"
-describe Projects::UpdatePagesService do
+RSpec.describe Projects::UpdatePagesService do
let_it_be(:project, refind: true) { create(:project, :repository) }
let_it_be(:pipeline) { create(:ci_pipeline, project: project, sha: project.commit('HEAD').sha) }
let(:build) { create(:ci_build, pipeline: pipeline, ref: 'HEAD') }
diff --git a/spec/services/projects/update_remote_mirror_service_spec.rb b/spec/services/projects/update_remote_mirror_service_spec.rb
index 418973fb0a6..f0a8074f46c 100644
--- a/spec/services/projects/update_remote_mirror_service_spec.rb
+++ b/spec/services/projects/update_remote_mirror_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::UpdateRemoteMirrorService do
+RSpec.describe Projects::UpdateRemoteMirrorService do
let(:project) { create(:project, :repository) }
let(:remote_project) { create(:forked_project_with_submodules) }
let(:remote_mirror) { create(:remote_mirror, project: project, enabled: true) }
diff --git a/spec/services/projects/update_repository_storage_service_spec.rb b/spec/services/projects/update_repository_storage_service_spec.rb
index e37580e7367..57e02c26b71 100644
--- a/spec/services/projects/update_repository_storage_service_spec.rb
+++ b/spec/services/projects/update_repository_storage_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::UpdateRepositoryStorageService do
+RSpec.describe Projects::UpdateRepositoryStorageService do
include Gitlab::ShellAdapter
subject { described_class.new(repository_storage_move) }
@@ -37,14 +37,15 @@ describe Projects::UpdateRepositoryStorageService do
project.repository.path_to_repo
end
- expect(project_repository_double).to receive(:create_repository)
- .and_return(true)
expect(project_repository_double).to receive(:replicate)
.with(project.repository.raw)
expect(project_repository_double).to receive(:checksum)
.and_return(checksum)
+ expect(GitlabShellWorker).to receive(:perform_async).with(:mv_repository, 'default', anything, anything)
+ .and_call_original
result = subject.execute
+ project.reload
expect(result).to be_success
expect(project).not_to be_repository_read_only
@@ -70,8 +71,6 @@ describe Projects::UpdateRepositoryStorageService do
allow(Gitlab::GitalyClient).to receive(:filesystem_id).with('default').and_call_original
allow(Gitlab::GitalyClient).to receive(:filesystem_id).with('test_second_storage').and_return(SecureRandom.uuid)
- expect(project_repository_double).to receive(:create_repository)
- .and_return(true)
expect(project_repository_double).to receive(:replicate)
.with(project.repository.raw)
.and_raise(Gitlab::Git::CommandError)
@@ -90,8 +89,6 @@ describe Projects::UpdateRepositoryStorageService do
allow(Gitlab::GitalyClient).to receive(:filesystem_id).with('default').and_call_original
allow(Gitlab::GitalyClient).to receive(:filesystem_id).with('test_second_storage').and_return(SecureRandom.uuid)
- expect(project_repository_double).to receive(:create_repository)
- .and_return(true)
expect(project_repository_double).to receive(:replicate)
.with(project.repository.raw)
expect(project_repository_double).to receive(:checksum)
@@ -113,20 +110,43 @@ describe Projects::UpdateRepositoryStorageService do
allow(Gitlab::GitalyClient).to receive(:filesystem_id).with('default').and_call_original
allow(Gitlab::GitalyClient).to receive(:filesystem_id).with('test_second_storage').and_return(SecureRandom.uuid)
- expect(project_repository_double).to receive(:create_repository)
- .and_return(true)
expect(project_repository_double).to receive(:replicate)
.with(project.repository.raw)
expect(project_repository_double).to receive(:checksum)
.and_return(checksum)
result = subject.execute
+ project.reload
expect(result).to be_success
expect(project.repository_storage).to eq('test_second_storage')
expect(project.reload_pool_repository).to be_nil
end
end
+
+ context 'when the repository move is finished' do
+ let(:repository_storage_move) { create(:project_repository_storage_move, :finished, project: project, destination_storage_name: destination) }
+
+ it 'is idempotent' do
+ expect do
+ result = subject.execute
+
+ expect(result).to be_success
+ end.not_to change(repository_storage_move, :state)
+ end
+ end
+
+ context 'when the repository move is failed' do
+ let(:repository_storage_move) { create(:project_repository_storage_move, :failed, project: project, destination_storage_name: destination) }
+
+ it 'is idempotent' do
+ expect do
+ result = subject.execute
+
+ expect(result).to be_success
+ end.not_to change(repository_storage_move, :state)
+ end
+ end
end
context 'with wiki repository' do
diff --git a/spec/services/projects/update_service_spec.rb b/spec/services/projects/update_service_spec.rb
index 8a17884f641..6620ee6e697 100644
--- a/spec/services/projects/update_service_spec.rb
+++ b/spec/services/projects/update_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::UpdateService do
+RSpec.describe Projects::UpdateService do
include ExternalAuthorizationServiceHelpers
include ProjectForksHelper
diff --git a/spec/services/projects/update_statistics_service_spec.rb b/spec/services/projects/update_statistics_service_spec.rb
index 8534853fbc7..92e97186be3 100644
--- a/spec/services/projects/update_statistics_service_spec.rb
+++ b/spec/services/projects/update_statistics_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::UpdateStatisticsService do
+RSpec.describe Projects::UpdateStatisticsService do
let(:service) { described_class.new(project, nil, statistics: statistics)}
let(:statistics) { %w(repository_size) }
diff --git a/spec/services/prometheus/create_default_alerts_service_spec.rb b/spec/services/prometheus/create_default_alerts_service_spec.rb
index a28c38491de..e149161d881 100644
--- a/spec/services/prometheus/create_default_alerts_service_spec.rb
+++ b/spec/services/prometheus/create_default_alerts_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Prometheus::CreateDefaultAlertsService do
+RSpec.describe Prometheus::CreateDefaultAlertsService do
let_it_be(:project) { create(:project, :repository) }
let(:instance) { described_class.new(project: project) }
let(:expected_alerts) { described_class::DEFAULT_ALERTS }
diff --git a/spec/services/prometheus/proxy_service_spec.rb b/spec/services/prometheus/proxy_service_spec.rb
index bd451ff00a1..f22ea361fde 100644
--- a/spec/services/prometheus/proxy_service_spec.rb
+++ b/spec/services/prometheus/proxy_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Prometheus::ProxyService do
+RSpec.describe Prometheus::ProxyService do
include ReactiveCachingHelpers
let_it_be(:project) { create(:project) }
diff --git a/spec/services/prometheus/proxy_variable_substitution_service_spec.rb b/spec/services/prometheus/proxy_variable_substitution_service_spec.rb
index 2435dda07b4..d8c1fdffb98 100644
--- a/spec/services/prometheus/proxy_variable_substitution_service_spec.rb
+++ b/spec/services/prometheus/proxy_variable_substitution_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Prometheus::ProxyVariableSubstitutionService do
+RSpec.describe Prometheus::ProxyVariableSubstitutionService do
describe '#execute' do
let_it_be(:environment) { create(:environment) }
diff --git a/spec/services/protected_branches/create_service_spec.rb b/spec/services/protected_branches/create_service_spec.rb
index 82d24ec43f6..986322e4d87 100644
--- a/spec/services/protected_branches/create_service_spec.rb
+++ b/spec/services/protected_branches/create_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe ProtectedBranches::CreateService do
+RSpec.describe ProtectedBranches::CreateService do
let(:project) { create(:project) }
let(:user) { project.owner }
let(:params) do
diff --git a/spec/services/protected_branches/destroy_service_spec.rb b/spec/services/protected_branches/destroy_service_spec.rb
index 3287eb9a59b..98d31147754 100644
--- a/spec/services/protected_branches/destroy_service_spec.rb
+++ b/spec/services/protected_branches/destroy_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe ProtectedBranches::DestroyService do
+RSpec.describe ProtectedBranches::DestroyService do
let(:protected_branch) { create(:protected_branch) }
let(:project) { protected_branch.project }
let(:user) { project.owner }
diff --git a/spec/services/protected_branches/update_service_spec.rb b/spec/services/protected_branches/update_service_spec.rb
index 7967ff81075..fdfbdf2e6ae 100644
--- a/spec/services/protected_branches/update_service_spec.rb
+++ b/spec/services/protected_branches/update_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe ProtectedBranches::UpdateService do
+RSpec.describe ProtectedBranches::UpdateService do
let(:protected_branch) { create(:protected_branch) }
let(:project) { protected_branch.project }
let(:user) { project.owner }
diff --git a/spec/services/protected_tags/create_service_spec.rb b/spec/services/protected_tags/create_service_spec.rb
index e58a539eb6f..e85a43eb51c 100644
--- a/spec/services/protected_tags/create_service_spec.rb
+++ b/spec/services/protected_tags/create_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe ProtectedTags::CreateService do
+RSpec.describe ProtectedTags::CreateService do
let(:project) { create(:project) }
let(:user) { project.owner }
let(:params) do
diff --git a/spec/services/protected_tags/destroy_service_spec.rb b/spec/services/protected_tags/destroy_service_spec.rb
index 52d1d1caa34..fbd1452a8d1 100644
--- a/spec/services/protected_tags/destroy_service_spec.rb
+++ b/spec/services/protected_tags/destroy_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe ProtectedTags::DestroyService do
+RSpec.describe ProtectedTags::DestroyService do
let(:protected_tag) { create(:protected_tag) }
let(:project) { protected_tag.project }
let(:user) { project.owner }
diff --git a/spec/services/protected_tags/update_service_spec.rb b/spec/services/protected_tags/update_service_spec.rb
index ca5109aca9c..ed151ca2347 100644
--- a/spec/services/protected_tags/update_service_spec.rb
+++ b/spec/services/protected_tags/update_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe ProtectedTags::UpdateService do
+RSpec.describe ProtectedTags::UpdateService do
let(:protected_tag) { create(:protected_tag) }
let(:project) { protected_tag.project }
let(:user) { project.owner }
diff --git a/spec/services/push_event_payload_service_spec.rb b/spec/services/push_event_payload_service_spec.rb
index 855b10c0259..de2bec21a3c 100644
--- a/spec/services/push_event_payload_service_spec.rb
+++ b/spec/services/push_event_payload_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe PushEventPayloadService do
+RSpec.describe PushEventPayloadService do
let(:event) { create(:push_event) }
describe '#execute' do
diff --git a/spec/services/quick_actions/interpret_service_spec.rb b/spec/services/quick_actions/interpret_service_spec.rb
index 1bd402e38be..57e32b1aea9 100644
--- a/spec/services/quick_actions/interpret_service_spec.rb
+++ b/spec/services/quick_actions/interpret_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe QuickActions::InterpretService do
+RSpec.describe QuickActions::InterpretService do
let(:project) { create(:project, :public) }
let(:developer) { create(:user) }
let(:developer2) { create(:user) }
@@ -792,7 +792,7 @@ describe QuickActions::InterpretService do
let(:issuable) { issue }
end
- it_behaves_like 'assign command', :quarantine do
+ it_behaves_like 'assign command', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/27989' do
let(:content) { "/assign @#{developer.username} @#{developer2.username}" }
let(:issuable) { merge_request }
end
diff --git a/spec/services/quick_actions/target_service_spec.rb b/spec/services/quick_actions/target_service_spec.rb
index 0aeb29cbeec..d960678f809 100644
--- a/spec/services/quick_actions/target_service_spec.rb
+++ b/spec/services/quick_actions/target_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe QuickActions::TargetService do
+RSpec.describe QuickActions::TargetService do
let(:project) { create(:project) }
let(:user) { create(:user) }
let(:service) { described_class.new(project, user) }
diff --git a/spec/services/releases/create_evidence_service_spec.rb b/spec/services/releases/create_evidence_service_spec.rb
index caa36a6b21d..818d20f0468 100644
--- a/spec/services/releases/create_evidence_service_spec.rb
+++ b/spec/services/releases/create_evidence_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Releases::CreateEvidenceService do
+RSpec.describe Releases::CreateEvidenceService do
let_it_be(:project) { create(:project) }
let(:release) { create(:release, project: project) }
let(:service) { described_class.new(release) }
diff --git a/spec/services/releases/create_service_spec.rb b/spec/services/releases/create_service_spec.rb
index 4e3d9d5f108..3c0698aa203 100644
--- a/spec/services/releases/create_service_spec.rb
+++ b/spec/services/releases/create_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Releases::CreateService do
+RSpec.describe Releases::CreateService do
let(:project) { create(:project, :repository) }
let(:user) { create(:user) }
let(:tag_name) { project.repository.tag_names.first }
diff --git a/spec/services/releases/destroy_service_spec.rb b/spec/services/releases/destroy_service_spec.rb
index 9d027767cd2..bc5bff0b31d 100644
--- a/spec/services/releases/destroy_service_spec.rb
+++ b/spec/services/releases/destroy_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Releases::DestroyService do
+RSpec.describe Releases::DestroyService do
let(:project) { create(:project, :repository) }
let(:mainatiner) { create(:user) }
let(:repoter) { create(:user) }
diff --git a/spec/services/releases/update_service_spec.rb b/spec/services/releases/update_service_spec.rb
index 7f1849e39a4..00544b820cb 100644
--- a/spec/services/releases/update_service_spec.rb
+++ b/spec/services/releases/update_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Releases::UpdateService do
+RSpec.describe Releases::UpdateService do
let(:project) { create(:project, :repository) }
let(:user) { create(:user) }
let(:new_name) { 'A new name' }
diff --git a/spec/services/repositories/destroy_rollback_service_spec.rb b/spec/services/repositories/destroy_rollback_service_spec.rb
index c3cdae17de7..9cc41a4c7f8 100644
--- a/spec/services/repositories/destroy_rollback_service_spec.rb
+++ b/spec/services/repositories/destroy_rollback_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Repositories::DestroyRollbackService do
+RSpec.describe Repositories::DestroyRollbackService do
let_it_be(:user) { create(:user) }
let!(:project) { create(:project, :repository, namespace: user.namespace) }
let(:repository) { project.repository }
diff --git a/spec/services/repositories/destroy_service_spec.rb b/spec/services/repositories/destroy_service_spec.rb
index 9c2694483c1..30ec84b44e7 100644
--- a/spec/services/repositories/destroy_service_spec.rb
+++ b/spec/services/repositories/destroy_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Repositories::DestroyService do
+RSpec.describe Repositories::DestroyService do
let_it_be(:user) { create(:user) }
let!(:project) { create(:project, :repository, namespace: user.namespace) }
let(:repository) { project.repository }
@@ -34,6 +34,21 @@ describe Repositories::DestroyService do
project.touch
end
+ context 'on a read-only instance' do
+ before do
+ allow(Gitlab::Database).to receive(:read_only?).and_return(true)
+ end
+
+ it 'schedules the repository deletion' do
+ expect(Repositories::ShellDestroyService).to receive(:new).with(repository).and_call_original
+
+ expect(GitlabShellWorker).to receive(:perform_in)
+ .with(Repositories::ShellDestroyService::REPO_REMOVAL_DELAY, :remove_repository, project.repository_storage, remove_path)
+
+ subject
+ end
+ end
+
it 'removes the repository', :sidekiq_inline do
subject
diff --git a/spec/services/repositories/shell_destroy_service_spec.rb b/spec/services/repositories/shell_destroy_service_spec.rb
index 9419977f6fe..9020ef7b209 100644
--- a/spec/services/repositories/shell_destroy_service_spec.rb
+++ b/spec/services/repositories/shell_destroy_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Repositories::ShellDestroyService do
+RSpec.describe Repositories::ShellDestroyService do
let_it_be(:user) { create(:user) }
let!(:project) { create(:project, :repository, namespace: user.namespace) }
let(:path) { project.repository.disk_path }
diff --git a/spec/services/repository_archive_clean_up_service_spec.rb b/spec/services/repository_archive_clean_up_service_spec.rb
index 80b177a0174..c6d673fb1b5 100644
--- a/spec/services/repository_archive_clean_up_service_spec.rb
+++ b/spec/services/repository_archive_clean_up_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe RepositoryArchiveCleanUpService do
+RSpec.describe RepositoryArchiveCleanUpService do
subject(:service) { described_class.new }
describe '#execute (new archive locations)' do
diff --git a/spec/services/reset_project_cache_service_spec.rb b/spec/services/reset_project_cache_service_spec.rb
index a4db4481c36..3e79270da8d 100644
--- a/spec/services/reset_project_cache_service_spec.rb
+++ b/spec/services/reset_project_cache_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe ResetProjectCacheService do
+RSpec.describe ResetProjectCacheService do
let(:project) { create(:project) }
let(:user) { create(:user) }
diff --git a/spec/services/resource_access_tokens/create_service_spec.rb b/spec/services/resource_access_tokens/create_service_spec.rb
index 57e7e4e66de..f22c379cd30 100644
--- a/spec/services/resource_access_tokens/create_service_spec.rb
+++ b/spec/services/resource_access_tokens/create_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe ResourceAccessTokens::CreateService do
+RSpec.describe ResourceAccessTokens::CreateService do
subject { described_class.new(user, resource, params).execute }
let_it_be(:user) { create(:user) }
@@ -45,6 +45,27 @@ describe ResourceAccessTokens::CreateService do
expect(access_token.user.reload.user_type).to eq("#{resource_type}_bot")
end
+ context 'email confirmation status' do
+ shared_examples_for 'creates a user that has their email confirmed' do
+ it 'creates a user that has their email confirmed' do
+ response = subject
+ access_token = response.payload[:access_token]
+
+ expect(access_token.user.reload.confirmed?).to eq(true)
+ end
+ end
+
+ context 'when created by an admin' do
+ it_behaves_like 'creates a user that has their email confirmed' do
+ let(:user) { create(:admin) }
+ end
+ end
+
+ context 'when created by a non-admin' do
+ it_behaves_like 'creates a user that has their email confirmed'
+ end
+ end
+
context 'bot name' do
context 'when no value is passed' do
it 'uses default value' do
diff --git a/spec/services/resource_access_tokens/revoke_service_spec.rb b/spec/services/resource_access_tokens/revoke_service_spec.rb
index 3ce82745b9e..ffc06d770f8 100644
--- a/spec/services/resource_access_tokens/revoke_service_spec.rb
+++ b/spec/services/resource_access_tokens/revoke_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe ResourceAccessTokens::RevokeService do
+RSpec.describe ResourceAccessTokens::RevokeService do
subject { described_class.new(user, resource, access_token).execute }
let_it_be(:user) { create(:user) }
diff --git a/spec/services/resource_events/change_labels_service_spec.rb b/spec/services/resource_events/change_labels_service_spec.rb
index 2b987b7fec9..efee185669e 100644
--- a/spec/services/resource_events/change_labels_service_spec.rb
+++ b/spec/services/resource_events/change_labels_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe ResourceEvents::ChangeLabelsService do
+RSpec.describe ResourceEvents::ChangeLabelsService do
let_it_be(:project) { create(:project) }
let_it_be(:author) { create(:user) }
let(:resource) { create(:issue, project: project) }
diff --git a/spec/services/resource_events/change_milestone_service_spec.rb b/spec/services/resource_events/change_milestone_service_spec.rb
index dec01d0db8d..9c0f9420f7a 100644
--- a/spec/services/resource_events/change_milestone_service_spec.rb
+++ b/spec/services/resource_events/change_milestone_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe ResourceEvents::ChangeMilestoneService do
+RSpec.describe ResourceEvents::ChangeMilestoneService do
[:issue, :merge_request].each do |issuable|
it_behaves_like 'a milestone events creator' do
let(:resource) { create(issuable) }
diff --git a/spec/services/resource_events/change_state_service_spec.rb b/spec/services/resource_events/change_state_service_spec.rb
index e5d2a4ab11e..5b5379b241b 100644
--- a/spec/services/resource_events/change_state_service_spec.rb
+++ b/spec/services/resource_events/change_state_service_spec.rb
@@ -2,38 +2,95 @@
require 'spec_helper'
-describe ResourceEvents::ChangeStateService do
+RSpec.describe ResourceEvents::ChangeStateService do
let_it_be(:project) { create(:project) }
let_it_be(:user) { create(:user) }
let(:issue) { create(:issue, project: project) }
let(:merge_request) { create(:merge_request, source_project: project) }
+ let(:source_commit) { create(:commit, project: project) }
+ let(:source_merge_request) { create(:merge_request, source_project: project, target_project: project, target_branch: 'foo') }
- describe '#execute' do
- context 'when resource is an issue' do
- %w[opened reopened closed locked].each do |state|
- it "creates the expected event if issue has #{state} state" do
- described_class.new(user: user, resource: issue).execute(state)
+ shared_examples 'a state event' do
+ %w[opened reopened closed locked].each do |state|
+ it "creates the expected event if resource has #{state} state" do
+ described_class.new(user: user, resource: resource).execute(status: state, mentionable_source: source)
+
+ event = resource.resource_state_events.last
- event = issue.resource_state_events.last
- expect(event.issue).to eq(issue)
+ if resource.is_a?(Issue)
+ expect(event.issue).to eq(resource)
expect(event.merge_request).to be_nil
- expect(event.state).to eq(state)
+ elsif resource.is_a?(MergeRequest)
+ expect(event.issue).to be_nil
+ expect(event.merge_request).to eq(resource)
end
+
+ expect(event.state).to eq(state)
+
+ expect_event_source(event, source)
end
end
+ end
- context 'when resource is a merge request' do
- %w[opened reopened closed locked merged].each do |state|
- it "creates the expected event if merge request has #{state} state" do
- described_class.new(user: user, resource: merge_request).execute(state)
+ describe '#execute' do
+ context 'when resource is an Issue' do
+ context 'when no source is given' do
+ it_behaves_like 'a state event' do
+ let(:resource) { issue }
+ let(:source) { nil }
+ end
+ end
- event = merge_request.resource_state_events.last
- expect(event.issue).to be_nil
- expect(event.merge_request).to eq(merge_request)
- expect(event.state).to eq(state)
+ context 'when source commit is given' do
+ it_behaves_like 'a state event' do
+ let(:resource) { issue }
+ let(:source) { source_commit }
+ end
+ end
+
+ context 'when source merge request is given' do
+ it_behaves_like 'a state event' do
+ let(:resource) { issue }
+ let(:source) { source_merge_request }
end
end
end
+
+ context 'when resource is a MergeRequest' do
+ context 'when no source is given' do
+ it_behaves_like 'a state event' do
+ let(:resource) { merge_request }
+ let(:source) { nil }
+ end
+ end
+
+ context 'when source commit is given' do
+ it_behaves_like 'a state event' do
+ let(:resource) { merge_request }
+ let(:source) { source_commit }
+ end
+ end
+
+ context 'when source merge request is given' do
+ it_behaves_like 'a state event' do
+ let(:resource) { merge_request }
+ let(:source) { source_merge_request }
+ end
+ end
+ end
+ end
+
+ def expect_event_source(event, source)
+ if source.is_a?(MergeRequest)
+ expect(event.source_commit).to be_nil
+ expect(event.source_merge_request).to eq(source)
+ elsif source.is_a?(Commit)
+ expect(event.source_commit).to eq(source.id)
+ expect(event.source_merge_request).to be_nil
+ else
+ expect(event.source_merge_request).to be_nil
+ expect(event.source_commit).to be_nil
+ end
end
end
diff --git a/spec/services/resource_events/merge_into_notes_service_spec.rb b/spec/services/resource_events/merge_into_notes_service_spec.rb
index 2664a27244d..6209294f4ce 100644
--- a/spec/services/resource_events/merge_into_notes_service_spec.rb
+++ b/spec/services/resource_events/merge_into_notes_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe ResourceEvents::MergeIntoNotesService do
+RSpec.describe ResourceEvents::MergeIntoNotesService do
def create_event(params)
event_params = { action: :add, label: label, issue: resource,
user: user }
@@ -61,7 +61,7 @@ describe ResourceEvents::MergeIntoNotesService do
event = create_event(created_at: 1.day.ago)
notes = described_class.new(resource, user,
- last_fetched_at: 2.days.ago.to_i).execute
+ last_fetched_at: 2.days.ago).execute
expect(notes.count).to eq 1
expect(notes.first.discussion_id).to eq event.discussion_id
diff --git a/spec/services/resource_events/synthetic_label_notes_builder_service_spec.rb b/spec/services/resource_events/synthetic_label_notes_builder_service_spec.rb
index 41902bc1da1..cb42ad5b617 100644
--- a/spec/services/resource_events/synthetic_label_notes_builder_service_spec.rb
+++ b/spec/services/resource_events/synthetic_label_notes_builder_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe ResourceEvents::SyntheticLabelNotesBuilderService do
+RSpec.describe ResourceEvents::SyntheticLabelNotesBuilderService do
describe '#execute' do
let!(:user) { create(:user) }
diff --git a/spec/services/resource_events/synthetic_milestone_notes_builder_service_spec.rb b/spec/services/resource_events/synthetic_milestone_notes_builder_service_spec.rb
index e98b8bd00dc..5e3afeabee7 100644
--- a/spec/services/resource_events/synthetic_milestone_notes_builder_service_spec.rb
+++ b/spec/services/resource_events/synthetic_milestone_notes_builder_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe ResourceEvents::SyntheticMilestoneNotesBuilderService do
+RSpec.describe ResourceEvents::SyntheticMilestoneNotesBuilderService do
describe '#execute' do
let_it_be(:user) { create(:user) }
let_it_be(:issue) { create(:issue, author: user) }
diff --git a/spec/services/search/global_service_spec.rb b/spec/services/search/global_service_spec.rb
index 0f829df90b3..90ad18e5571 100644
--- a/spec/services/search/global_service_spec.rb
+++ b/spec/services/search/global_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Search::GlobalService do
+RSpec.describe Search::GlobalService do
let(:user) { create(:user) }
let(:internal_user) { create(:user) }
diff --git a/spec/services/search/group_service_spec.rb b/spec/services/search/group_service_spec.rb
index cfb672753b8..d3026d158d4 100644
--- a/spec/services/search/group_service_spec.rb
+++ b/spec/services/search/group_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Search::GroupService do
+RSpec.describe Search::GroupService do
shared_examples_for 'group search' do
context 'finding projects by name' do
let(:user) { create(:user) }
diff --git a/spec/services/search/snippet_service_spec.rb b/spec/services/search/snippet_service_spec.rb
index cb2bb0c43fd..ceaf3d055bf 100644
--- a/spec/services/search/snippet_service_spec.rb
+++ b/spec/services/search/snippet_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Search::SnippetService do
+RSpec.describe Search::SnippetService do
let_it_be(:author) { create(:author) }
let_it_be(:project) { create(:project, :public) }
diff --git a/spec/services/search_service_spec.rb b/spec/services/search_service_spec.rb
index 0333eb85fb6..52aef73ac77 100644
--- a/spec/services/search_service_spec.rb
+++ b/spec/services/search_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe SearchService do
+RSpec.describe SearchService do
let_it_be(:user) { create(:user) }
let_it_be(:accessible_group) { create(:group, :private) }
diff --git a/spec/services/serverless/associate_domain_service_spec.rb b/spec/services/serverless/associate_domain_service_spec.rb
index 3d1a878bcf5..3b5231989bc 100644
--- a/spec/services/serverless/associate_domain_service_spec.rb
+++ b/spec/services/serverless/associate_domain_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Serverless::AssociateDomainService do
+RSpec.describe Serverless::AssociateDomainService do
subject { described_class.new(knative, pages_domain_id: pages_domain_id, creator: creator) }
let(:sdc) { create(:serverless_domain_cluster, pages_domain: create(:pages_domain, :instance_serverless)) }
diff --git a/spec/services/service_desk_settings/update_service_spec.rb b/spec/services/service_desk_settings/update_service_spec.rb
new file mode 100644
index 00000000000..8b920d536b4
--- /dev/null
+++ b/spec/services/service_desk_settings/update_service_spec.rb
@@ -0,0 +1,46 @@
+# frozen_string_literal: true
+require 'spec_helper'
+
+RSpec.describe ServiceDeskSettings::UpdateService do
+ describe '#execute' do
+ let_it_be(:settings) { create(:service_desk_setting, outgoing_name: 'original name') }
+ let_it_be(:user) { create(:user) }
+
+ context 'with valid params' do
+ let(:params) { { outgoing_name: 'some name', project_key: 'foo' } }
+
+ it 'updates service desk settings' do
+ result = described_class.new(settings.project, user, params).execute
+
+ expect(result[:status]).to eq :success
+ expect(settings.reload.outgoing_name).to eq 'some name'
+ expect(settings.reload.project_key).to eq 'foo'
+ end
+
+ context 'when service_desk_custom_address is disabled' do
+ before do
+ stub_feature_flags(service_desk_custom_address: false)
+ end
+
+ it 'ignores project_key parameter' do
+ result = described_class.new(settings.project, user, params).execute
+
+ expect(result[:status]).to eq :success
+ expect(settings.reload.project_key).to be_nil
+ end
+ end
+ end
+
+ context 'with invalid params' do
+ let(:params) { { outgoing_name: 'x' * 256 } }
+
+ it 'does not update service desk settings' do
+ result = described_class.new(settings.project, user, params).execute
+
+ expect(result[:status]).to eq :error
+ expect(result[:message]).to eq 'Outgoing name is too long (maximum is 255 characters)'
+ expect(settings.reload.outgoing_name).to eq 'original name'
+ end
+ end
+ end
+end
diff --git a/spec/services/service_response_spec.rb b/spec/services/service_response_spec.rb
index 2c944a63ebb..986b26e67d7 100644
--- a/spec/services/service_response_spec.rb
+++ b/spec/services/service_response_spec.rb
@@ -4,7 +4,7 @@ require 'fast_spec_helper'
ActiveSupport::Dependencies.autoload_paths << 'app/services'
-describe ServiceResponse do
+RSpec.describe ServiceResponse do
describe '.success' do
it 'creates a successful response without a message' do
expect(described_class.success).to be_success
diff --git a/spec/services/snippets/bulk_destroy_service_spec.rb b/spec/services/snippets/bulk_destroy_service_spec.rb
index 6e5623e575f..8a6250a8b45 100644
--- a/spec/services/snippets/bulk_destroy_service_spec.rb
+++ b/spec/services/snippets/bulk_destroy_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Snippets::BulkDestroyService do
+RSpec.describe Snippets::BulkDestroyService do
let_it_be(:project) { create(:project) }
let(:user) { create(:user) }
let!(:personal_snippet) { create(:personal_snippet, :repository, author: user) }
diff --git a/spec/services/snippets/count_service_spec.rb b/spec/services/snippets/count_service_spec.rb
index 4137e65dcca..5ce637d0bac 100644
--- a/spec/services/snippets/count_service_spec.rb
+++ b/spec/services/snippets/count_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Snippets::CountService do
+RSpec.describe Snippets::CountService do
let_it_be(:user) { create(:user) }
let_it_be(:project) { create(:project, :public) }
diff --git a/spec/services/snippets/create_service_spec.rb b/spec/services/snippets/create_service_spec.rb
index fa8cbc87563..62eef00b67f 100644
--- a/spec/services/snippets/create_service_spec.rb
+++ b/spec/services/snippets/create_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Snippets::CreateService do
+RSpec.describe Snippets::CreateService do
describe '#execute' do
let_it_be(:user) { create(:user) }
let_it_be(:admin) { create(:user, :admin) }
@@ -177,10 +177,8 @@ describe Snippets::CreateService do
end
it 'returns a generic error' do
- response = subject
-
- expect(response).to be_error
- expect(response.payload[:snippet].errors[:repository]).to eq ['Error creating the snippet']
+ expect(subject).to be_error
+ expect(snippet.errors[:repository]).to eq ['Error creating the snippet']
end
end
@@ -230,15 +228,15 @@ describe Snippets::CreateService do
end
end
- shared_examples 'when snippet_files param is present' do
+ shared_examples 'when snippet_actions param is present' do
let(:file_path) { 'snippet_file_path.rb' }
let(:content) { 'snippet_content' }
- let(:snippet_files) { [{ action: 'create', file_path: file_path, content: content }] }
+ let(:snippet_actions) { [{ action: 'create', file_path: file_path, content: content }] }
let(:base_opts) do
{
title: 'Test snippet',
visibility_level: Gitlab::VisibilityLevel::PRIVATE,
- snippet_files: snippet_files
+ snippet_actions: snippet_actions
}
end
@@ -250,7 +248,7 @@ describe Snippets::CreateService do
end
it 'commit the files to the repository' do
- subject
+ expect(subject).to be_success
blob = snippet.repository.blob_at('master', file_path)
@@ -261,28 +259,42 @@ describe Snippets::CreateService do
let(:extra_opts) { { content: 'foo', file_name: 'path' } }
it 'a validation error is raised' do
- response = subject
- snippet = response.payload[:snippet]
-
- expect(response).to be_error
+ expect(subject).to be_error
expect(snippet.errors.full_messages_for(:content)).to eq ['Content and snippet files cannot be used together']
expect(snippet.errors.full_messages_for(:file_name)).to eq ['File name and snippet files cannot be used together']
expect(snippet.repository.exists?).to be_falsey
end
end
- context 'when snippet_files param is invalid' do
- let(:snippet_files) { [{ action: 'invalid_action', file_path: 'snippet_file_path.rb', content: 'snippet_content' }] }
+ context 'when snippet_actions param is invalid' do
+ let(:snippet_actions) { [{ action: 'invalid_action', file_path: 'snippet_file_path.rb', content: 'snippet_content' }] }
it 'a validation error is raised' do
- response = subject
- snippet = response.payload[:snippet]
+ expect(subject).to be_error
+ expect(snippet.errors.full_messages_for(:snippet_actions)).to eq ['Snippet actions have invalid data']
+ expect(snippet.repository.exists?).to be_falsey
+ end
+ end
- expect(response).to be_error
- expect(snippet.errors.full_messages_for(:snippet_files)).to eq ['Snippet files have invalid data']
+ context 'when snippet_actions contain an action different from "create"' do
+ let(:snippet_actions) { [{ action: 'delete', file_path: 'snippet_file_path.rb' }] }
+
+ it 'a validation error is raised' do
+ expect(subject).to be_error
+ expect(snippet.errors.full_messages_for(:snippet_actions)).to eq ['Snippet actions have invalid data']
expect(snippet.repository.exists?).to be_falsey
end
end
+
+ context 'when "create" operation does not have file_path or is empty' do
+ let(:snippet_actions) { [{ action: 'create', content: content }, { action: 'create', content: content, file_path: '' }] }
+
+ it 'generates the file path for the files' do
+ expect(subject).to be_success
+ expect(snippet.repository.blob_at('master', 'snippetfile1.txt').data).to eq content
+ expect(snippet.repository.blob_at('master', 'snippetfile2.txt').data).to eq content
+ end
+ end
end
context 'when ProjectSnippet' do
@@ -299,7 +311,7 @@ describe Snippets::CreateService do
it_behaves_like 'an error service response when save fails'
it_behaves_like 'creates repository and files'
it_behaves_like 'after_save callback to store_mentions', ProjectSnippet
- it_behaves_like 'when snippet_files param is present'
+ it_behaves_like 'when snippet_actions param is present'
context 'when uploaded files are passed to the service' do
let(:extra_opts) { { files: ['foo'] } }
@@ -326,7 +338,7 @@ describe Snippets::CreateService do
it_behaves_like 'an error service response when save fails'
it_behaves_like 'creates repository and files'
it_behaves_like 'after_save callback to store_mentions', PersonalSnippet
- it_behaves_like 'when snippet_files param is present'
+ it_behaves_like 'when snippet_actions param is present'
context 'when the snippet description contains files' do
include FileMoverHelpers
diff --git a/spec/services/snippets/destroy_service_spec.rb b/spec/services/snippets/destroy_service_spec.rb
index 840dc11a740..e53d00b9ca1 100644
--- a/spec/services/snippets/destroy_service_spec.rb
+++ b/spec/services/snippets/destroy_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Snippets::DestroyService do
+RSpec.describe Snippets::DestroyService do
let_it_be(:project) { create(:project) }
let_it_be(:user) { create(:user) }
let_it_be(:other_user) { create(:user) }
@@ -105,6 +105,26 @@ describe Snippets::DestroyService do
it_behaves_like 'a successful destroy'
it_behaves_like 'deletes the snippet repository'
+
+ context 'project statistics' do
+ before do
+ snippet.statistics.refresh!
+ end
+
+ it 'updates stats after deletion' do
+ expect(project.reload.statistics.snippets_size).not_to be_zero
+
+ subject
+
+ expect(project.reload.statistics.snippets_size).to be_zero
+ end
+
+ it 'schedules a namespace statistics update' do
+ expect(Namespaces::ScheduleAggregationWorker).to receive(:perform_async).with(project.namespace_id).once
+
+ subject
+ end
+ end
end
context 'when user is not able to admin_project_snippet' do
@@ -122,6 +142,12 @@ describe Snippets::DestroyService do
it_behaves_like 'a successful destroy'
it_behaves_like 'deletes the snippet repository'
+
+ it 'schedules a namespace statistics update' do
+ expect(Namespaces::ScheduleAggregationWorker).to receive(:perform_async).with(author.namespace_id)
+
+ subject
+ end
end
context 'when user is not able to admin_personal_snippet' do
diff --git a/spec/services/snippets/repository_validation_service_spec.rb b/spec/services/snippets/repository_validation_service_spec.rb
index 1c139d8c223..e2a0d0faa18 100644
--- a/spec/services/snippets/repository_validation_service_spec.rb
+++ b/spec/services/snippets/repository_validation_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Snippets::RepositoryValidationService do
+RSpec.describe Snippets::RepositoryValidationService do
describe '#execute' do
let_it_be(:user) { create(:user) }
let_it_be(:snippet) { create(:personal_snippet, :empty_repo, author: user) }
diff --git a/spec/services/snippets/update_service_spec.rb b/spec/services/snippets/update_service_spec.rb
index 7e6441ad2f9..66dddcc49de 100644
--- a/spec/services/snippets/update_service_spec.rb
+++ b/spec/services/snippets/update_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Snippets::UpdateService do
+RSpec.describe Snippets::UpdateService do
describe '#execute' do
let_it_be(:user) { create(:user) }
let_it_be(:admin) { create :user, admin: true }
@@ -302,22 +302,22 @@ describe Snippets::UpdateService do
end
end
- shared_examples 'when snippet_files param is present' do
+ shared_examples 'when snippet_actions param is present' do
let(:file_path) { 'CHANGELOG' }
let(:content) { 'snippet_content' }
let(:new_title) { 'New title' }
- let(:snippet_files) { [{ action: 'update', previous_path: file_path, file_path: file_path, content: content }] }
+ let(:snippet_actions) { [{ action: 'update', previous_path: file_path, file_path: file_path, content: content }] }
let(:base_opts) do
{
title: new_title,
- snippet_files: snippet_files
+ snippet_actions: snippet_actions
}
end
it 'updates a snippet with the provided attributes' do
file_path = 'foo'
- snippet_files[0][:action] = 'move'
- snippet_files[0][:file_path] = file_path
+ snippet_actions[0][:action] = 'move'
+ snippet_actions[0][:file_path] = file_path
response = subject
snippet = response.payload[:snippet]
@@ -328,7 +328,7 @@ describe Snippets::UpdateService do
expect(snippet.content).to eq(content)
end
- it 'commit the files to the repository' do
+ it 'commits the files to the repository' do
subject
blob = snippet.repository.blob_at('master', file_path)
@@ -349,15 +349,27 @@ describe Snippets::UpdateService do
end
end
- context 'when snippet_files param is invalid' do
- let(:snippet_files) { [{ action: 'invalid_action' }] }
+ context 'when snippet_file content is not present' do
+ let(:snippet_actions) { [{ action: :move, previous_path: file_path, file_path: 'new_file_path' }] }
+
+ it 'does not update snippet content' do
+ content = snippet.content
+
+ expect(subject).to be_success
+
+ expect(snippet.reload.content).to eq content
+ end
+ end
+
+ context 'when snippet_actions param is invalid' do
+ let(:snippet_actions) { [{ action: 'invalid_action' }] }
it 'raises a validation error' do
response = subject
snippet = response.payload[:snippet]
expect(response).to be_error
- expect(snippet.errors.full_messages_for(:snippet_files)).to eq ['Snippet files have invalid data']
+ expect(snippet.errors.full_messages_for(:snippet_actions)).to eq ['Snippet actions have invalid data']
end
end
@@ -376,6 +388,226 @@ describe Snippets::UpdateService do
expect(snippet.content).to eq(content)
end
end
+
+ context 'commit actions' do
+ let(:new_path) { 'created_new_file' }
+ let(:base_opts) { { snippet_actions: snippet_actions } }
+
+ shared_examples 'returns an error' do |error_msg|
+ specify do
+ response = subject
+
+ expect(response).to be_error
+ expect(response.message).to eq error_msg
+ end
+ end
+
+ context 'update action' do
+ let(:snippet_actions) { [{ action: :update, file_path: file_path, content: content }] }
+
+ it 'updates the file content' do
+ expect(subject).to be_success
+
+ blob = blob(file_path)
+
+ expect(blob.data).to eq content
+ end
+
+ context 'when previous_path is present' do
+ let(:snippet_actions) { [{ action: :update, previous_path: file_path, file_path: file_path, content: content }] }
+
+ it 'updates the file content' do
+ expect(subject).to be_success
+
+ blob = blob(file_path)
+
+ expect(blob.data).to eq content
+ end
+ end
+
+ context 'when content is not present' do
+ let(:snippet_actions) { [{ action: :update, file_path: file_path }] }
+
+ it_behaves_like 'returns an error', 'Snippet actions have invalid data'
+ end
+
+ context 'when file_path does not exist' do
+ let(:snippet_actions) { [{ action: :update, file_path: 'makeup_name', content: content }] }
+
+ it_behaves_like 'returns an error', 'Repository Error updating the snippet'
+ end
+ end
+
+ context 'move action' do
+ context 'when file_path and previous_path are the same' do
+ let(:snippet_actions) { [{ action: :move, previous_path: file_path, file_path: file_path }] }
+
+ it_behaves_like 'returns an error', 'Snippet actions have invalid data'
+ end
+
+ context 'when file_path and previous_path are different' do
+ let(:snippet_actions) { [{ action: :move, previous_path: file_path, file_path: new_path }] }
+
+ it 'renames the file' do
+ old_blob = blob(file_path)
+
+ expect(subject).to be_success
+
+ blob = blob(new_path)
+
+ expect(blob).to be_present
+ expect(blob.data).to eq old_blob.data
+ end
+ end
+
+ context 'when previous_path does not exist' do
+ let(:snippet_actions) { [{ action: :move, previous_path: 'makeup_name', file_path: new_path }] }
+
+ it_behaves_like 'returns an error', 'Repository Error updating the snippet'
+ end
+
+ context 'when user wants to rename the file and update content' do
+ let(:snippet_actions) { [{ action: :move, previous_path: file_path, file_path: new_path, content: content }] }
+
+ it 'performs both operations' do
+ expect(subject).to be_success
+
+ blob = blob(new_path)
+
+ expect(blob).to be_present
+ expect(blob.data).to eq content
+ end
+ end
+ end
+
+ context 'delete action' do
+ let(:snippet_actions) { [{ action: :delete, file_path: file_path }] }
+
+ shared_examples 'deletes the file' do
+ specify do
+ old_blob = blob(file_path)
+ expect(old_blob).to be_present
+
+ expect(subject).to be_success
+ expect(blob(file_path)).to be_nil
+ end
+ end
+
+ it_behaves_like 'deletes the file'
+
+ context 'when previous_path is present and same as file_path' do
+ let(:snippet_actions) { [{ action: :delete, previous_path: file_path, file_path: file_path }] }
+
+ it_behaves_like 'deletes the file'
+ end
+
+ context 'when previous_path is present and is different from file_path' do
+ let(:snippet_actions) { [{ action: :delete, previous_path: 'foo', file_path: file_path }] }
+
+ it_behaves_like 'deletes the file'
+ end
+
+ context 'when content is present' do
+ let(:snippet_actions) { [{ action: :delete, file_path: file_path, content: 'foo' }] }
+
+ it_behaves_like 'deletes the file'
+ end
+
+ context 'when file_path does not exist' do
+ let(:snippet_actions) { [{ action: :delete, file_path: 'makeup_name' }] }
+
+ it_behaves_like 'returns an error', 'Repository Error updating the snippet'
+ end
+ end
+
+ context 'create action' do
+ let(:snippet_actions) { [{ action: :create, file_path: new_path, content: content }] }
+
+ it 'creates the file' do
+ expect(subject).to be_success
+
+ blob = blob(new_path)
+ expect(blob).to be_present
+ expect(blob.data).to eq content
+ end
+
+ context 'when content is not present' do
+ let(:snippet_actions) { [{ action: :create, file_path: new_path }] }
+
+ it_behaves_like 'returns an error', 'Snippet actions have invalid data'
+ end
+
+ context 'when file_path is not present or empty' do
+ let(:snippet_actions) { [{ action: :create, content: content }, { action: :create, file_path: '', content: content }] }
+
+ it 'generates the file path for the files' do
+ expect(blob('snippetfile1.txt')).to be_nil
+ expect(blob('snippetfile2.txt')).to be_nil
+
+ expect(subject).to be_success
+
+ expect(blob('snippetfile1.txt').data).to eq content
+ expect(blob('snippetfile2.txt').data).to eq content
+ end
+ end
+
+ context 'when file_path already exists in the repository' do
+ let(:snippet_actions) { [{ action: :create, file_path: file_path, content: content }] }
+
+ it_behaves_like 'returns an error', 'Repository Error updating the snippet'
+ end
+
+ context 'when previous_path is present' do
+ let(:snippet_actions) { [{ action: :create, previous_path: 'foo', file_path: new_path, content: content }] }
+
+ it 'creates the file' do
+ expect(subject).to be_success
+
+ blob = blob(new_path)
+ expect(blob).to be_present
+ expect(blob.data).to eq content
+ end
+ end
+ end
+
+ context 'combination of actions' do
+ let(:delete_file_path) { 'CHANGELOG' }
+ let(:create_file_path) { 'created_new_file' }
+ let(:update_file_path) { 'LICENSE' }
+ let(:move_previous_path) { 'VERSION' }
+ let(:move_file_path) { 'VERSION_new' }
+
+ let(:snippet_actions) do
+ [
+ { action: :create, file_path: create_file_path, content: content },
+ { action: :update, file_path: update_file_path, content: content },
+ { action: :delete, file_path: delete_file_path },
+ { action: :move, previous_path: move_previous_path, file_path: move_file_path, content: content }
+ ]
+ end
+
+ it 'performs all operations' do
+ expect(subject).to be_success
+
+ expect(blob(delete_file_path)).to be_nil
+
+ created_blob = blob(create_file_path)
+ expect(created_blob.data).to eq content
+
+ updated_blob = blob(update_file_path)
+ expect(updated_blob.data).to eq content
+
+ expect(blob(move_previous_path)).to be_nil
+
+ moved_blob = blob(move_file_path)
+ expect(moved_blob.data).to eq content
+ end
+ end
+
+ def blob(path)
+ snippet.repository.blob_at('master', path)
+ end
+ end
end
shared_examples 'only file_name is present' do
@@ -446,7 +678,7 @@ describe Snippets::UpdateService do
it_behaves_like 'updates repository content'
it_behaves_like 'commit operation fails'
it_behaves_like 'committable attributes'
- it_behaves_like 'when snippet_files param is present'
+ it_behaves_like 'when snippet_actions param is present'
it_behaves_like 'only file_name is present'
it_behaves_like 'only content is present'
it_behaves_like 'snippets spam check is performed' do
@@ -473,7 +705,7 @@ describe Snippets::UpdateService do
it_behaves_like 'updates repository content'
it_behaves_like 'commit operation fails'
it_behaves_like 'committable attributes'
- it_behaves_like 'when snippet_files param is present'
+ it_behaves_like 'when snippet_actions param is present'
it_behaves_like 'only file_name is present'
it_behaves_like 'only content is present'
it_behaves_like 'snippets spam check is performed' do
diff --git a/spec/services/snippets/update_statistics_service_spec.rb b/spec/services/snippets/update_statistics_service_spec.rb
new file mode 100644
index 00000000000..27ae054676a
--- /dev/null
+++ b/spec/services/snippets/update_statistics_service_spec.rb
@@ -0,0 +1,86 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Snippets::UpdateStatisticsService do
+ describe '#execute' do
+ subject { described_class.new(snippet).execute }
+
+ shared_examples 'updates statistics' do
+ it 'returns a successful response' do
+ expect(subject).to be_success
+ end
+
+ it 'expires statistics cache' do
+ expect(snippet.repository).to receive(:expire_statistics_caches)
+
+ subject
+ end
+
+ context 'when snippet statistics does not exist' do
+ it 'creates snippet statistics' do
+ snippet.statistics.delete
+ snippet.reload
+
+ expect do
+ subject
+ end.to change(SnippetStatistics, :count).by(1)
+
+ expect(snippet.statistics.commit_count).not_to be_zero
+ expect(snippet.statistics.file_count).not_to be_zero
+ expect(snippet.statistics.repository_size).not_to be_zero
+ end
+ end
+
+ context 'when snippet statistics exists' do
+ it 'updates snippet statistics' do
+ expect(snippet.statistics.commit_count).to be_zero
+ expect(snippet.statistics.file_count).to be_zero
+ expect(snippet.statistics.repository_size).to be_zero
+
+ subject
+
+ expect(snippet.statistics.commit_count).not_to be_zero
+ expect(snippet.statistics.file_count).not_to be_zero
+ expect(snippet.statistics.repository_size).not_to be_zero
+ end
+ end
+
+ context 'when snippet does not have a repository' do
+ it 'returns an error response' do
+ expect(snippet).to receive(:repository_exists?).and_return(false)
+
+ expect(subject).to be_error
+ end
+ end
+
+ it 'schedules a namespace storage statistics update' do
+ expect(Namespaces::ScheduleAggregationWorker)
+ .to receive(:perform_async).once
+
+ subject
+ end
+ end
+
+ context 'with PersonalSnippet' do
+ let!(:snippet) { create(:personal_snippet, :repository) }
+
+ it_behaves_like 'updates statistics'
+ end
+
+ context 'with ProjectSnippet' do
+ let!(:snippet) { create(:project_snippet, :repository) }
+ let(:project_statistics) { snippet.project.statistics }
+
+ it_behaves_like 'updates statistics'
+
+ it 'updates projects statistics "snippets_size"' do
+ expect(project_statistics.snippets_size).to be_zero
+
+ subject
+
+ expect(snippet.reload.statistics.repository_size).to eq project_statistics.reload.snippets_size
+ end
+ end
+ end
+end
diff --git a/spec/services/spam/akismet_service_spec.rb b/spec/services/spam/akismet_service_spec.rb
index 413b43d0156..f75b0216b78 100644
--- a/spec/services/spam/akismet_service_spec.rb
+++ b/spec/services/spam/akismet_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Spam::AkismetService do
+RSpec.describe Spam::AkismetService do
let(:fake_akismet_client) { double(:akismet_client) }
let_it_be(:text) { "Would you like to buy some tinned meat product?" }
diff --git a/spec/services/spam/ham_service_spec.rb b/spec/services/spam/ham_service_spec.rb
index 9848f48def2..c947de6cf92 100644
--- a/spec/services/spam/ham_service_spec.rb
+++ b/spec/services/spam/ham_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Spam::HamService do
+RSpec.describe Spam::HamService do
let_it_be(:user) { create(:user) }
let!(:spam_log) { create(:spam_log, user: user, submitted_as_ham: false) }
let(:fake_akismet_service) { double(:akismet_service) }
diff --git a/spec/services/spam/mark_as_spam_service_spec.rb b/spec/services/spam/mark_as_spam_service_spec.rb
index 9978005279a..308a66c3a48 100644
--- a/spec/services/spam/mark_as_spam_service_spec.rb
+++ b/spec/services/spam/mark_as_spam_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Spam::MarkAsSpamService do
+RSpec.describe Spam::MarkAsSpamService do
let(:user_agent_detail) { build(:user_agent_detail) }
let(:spammable) { build(:issue, user_agent_detail: user_agent_detail) }
let(:fake_akismet_service) { double(:akismet_service, submit_spam: true) }
diff --git a/spec/services/spam/spam_action_service_spec.rb b/spec/services/spam/spam_action_service_spec.rb
index 7b6b65c82b1..abb8e49ec52 100644
--- a/spec/services/spam/spam_action_service_spec.rb
+++ b/spec/services/spam/spam_action_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Spam::SpamActionService do
+RSpec.describe Spam::SpamActionService do
include_context 'includes Spam constants'
let(:fake_ip) { '1.2.3.4' }
diff --git a/spec/services/spam/spam_verdict_service_spec.rb b/spec/services/spam/spam_verdict_service_spec.rb
index f6d9cd96da5..d775e1bdfb5 100644
--- a/spec/services/spam/spam_verdict_service_spec.rb
+++ b/spec/services/spam/spam_verdict_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Spam::SpamVerdictService do
+RSpec.describe Spam::SpamVerdictService do
include_context 'includes Spam constants'
let(:fake_ip) { '1.2.3.4' }
@@ -27,7 +27,7 @@ describe Spam::SpamVerdictService do
before do
allow(service).to receive(:akismet_verdict).and_return(nil)
- allow(service).to receive(:spam_verdict_verdict).and_return(nil)
+ allow(service).to receive(:external_verdict).and_return(nil)
end
context 'if all services return nil' do
@@ -62,7 +62,7 @@ describe Spam::SpamVerdictService do
context 'and they are supported' do
before do
allow(service).to receive(:akismet_verdict).and_return(DISALLOW)
- allow(service).to receive(:spam_verdict).and_return(BLOCK_USER)
+ allow(service).to receive(:external_verdict).and_return(BLOCK_USER)
end
it 'renders the more restrictive verdict' do
@@ -73,18 +73,7 @@ describe Spam::SpamVerdictService do
context 'and one is supported' do
before do
allow(service).to receive(:akismet_verdict).and_return('nonsense')
- allow(service).to receive(:spam_verdict).and_return(BLOCK_USER)
- end
-
- it 'renders the more restrictive verdict' do
- expect(subject).to eq BLOCK_USER
- end
- end
-
- context 'and one is supported' do
- before do
- allow(service).to receive(:akismet_verdict).and_return('nonsense')
- allow(service).to receive(:spam_verdict).and_return(BLOCK_USER)
+ allow(service).to receive(:external_verdict).and_return(BLOCK_USER)
end
it 'renders the more restrictive verdict' do
@@ -95,7 +84,7 @@ describe Spam::SpamVerdictService do
context 'and none are supported' do
before do
allow(service).to receive(:akismet_verdict).and_return('nonsense')
- allow(service).to receive(:spam_verdict).and_return('rubbish')
+ allow(service).to receive(:external_verdict).and_return('rubbish')
end
it 'renders the more restrictive verdict' do
@@ -160,8 +149,8 @@ describe Spam::SpamVerdictService do
end
end
- describe '#spam_verdict' do
- subject { service.send(:spam_verdict) }
+ describe '#external_verdict' do
+ subject { service.send(:external_verdict) }
context 'if a Spam Check endpoint enabled and set to a URL' do
let(:spam_check_body) { {} }
@@ -192,8 +181,8 @@ describe Spam::SpamVerdictService do
context 'the verdict is an unexpected string' do
let(:verdict) { 'this is fine' }
- it 'returns nil' do
- expect(subject).to be_nil
+ it 'returns the string' do
+ expect(subject).to eq verdict
end
end
@@ -209,7 +198,7 @@ describe Spam::SpamVerdictService do
let(:verdict) { '' }
it 'returns nil' do
- expect(subject).to be_nil
+ expect(subject).to eq verdict
end
end
diff --git a/spec/services/submit_usage_ping_service_spec.rb b/spec/services/submit_usage_ping_service_spec.rb
index 981ea0dbec1..4885ef99c13 100644
--- a/spec/services/submit_usage_ping_service_spec.rb
+++ b/spec/services/submit_usage_ping_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe SubmitUsagePingService do
+RSpec.describe SubmitUsagePingService do
include StubRequests
include UsageDataHelpers
diff --git a/spec/services/submodules/update_service_spec.rb b/spec/services/submodules/update_service_spec.rb
index 47b31d4bcbf..e7f92d5ba28 100644
--- a/spec/services/submodules/update_service_spec.rb
+++ b/spec/services/submodules/update_service_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
require 'spec_helper'
-describe Submodules::UpdateService do
+RSpec.describe Submodules::UpdateService do
let(:project) { create(:project, :repository) }
let(:repository) { project.repository }
let(:user) { create(:user, :commit_email) }
diff --git a/spec/services/suggestions/apply_service_spec.rb b/spec/services/suggestions/apply_service_spec.rb
index 678e2129181..aa9caf35987 100644
--- a/spec/services/suggestions/apply_service_spec.rb
+++ b/spec/services/suggestions/apply_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Suggestions::ApplyService do
+RSpec.describe Suggestions::ApplyService do
include ProjectForksHelper
def build_position(**optional_args)
diff --git a/spec/services/suggestions/create_service_spec.rb b/spec/services/suggestions/create_service_spec.rb
index d95f9e3349b..54e7c5cc127 100644
--- a/spec/services/suggestions/create_service_spec.rb
+++ b/spec/services/suggestions/create_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Suggestions::CreateService do
+RSpec.describe Suggestions::CreateService do
let(:project_with_repo) { create(:project, :repository) }
let(:merge_request) do
create(:merge_request, source_project: project_with_repo,
diff --git a/spec/services/suggestions/outdate_service_spec.rb b/spec/services/suggestions/outdate_service_spec.rb
index bcc627013d8..e8891f88548 100644
--- a/spec/services/suggestions/outdate_service_spec.rb
+++ b/spec/services/suggestions/outdate_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Suggestions::OutdateService do
+RSpec.describe Suggestions::OutdateService do
describe '#execute' do
let(:merge_request) { create(:merge_request) }
let(:project) { merge_request.target_project }
diff --git a/spec/services/system_hooks_service_spec.rb b/spec/services/system_hooks_service_spec.rb
index d72e5cc2b16..bdc40a92e91 100644
--- a/spec/services/system_hooks_service_spec.rb
+++ b/spec/services/system_hooks_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe SystemHooksService do
+RSpec.describe SystemHooksService do
let(:user) { create(:user) }
let(:project) { create(:project) }
let(:project_member) { create(:project_member) }
diff --git a/spec/services/system_note_service_spec.rb b/spec/services/system_note_service_spec.rb
index 66f9b5d092f..58fa772fefb 100644
--- a/spec/services/system_note_service_spec.rb
+++ b/spec/services/system_note_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe SystemNoteService do
+RSpec.describe SystemNoteService do
include Gitlab::Routing
include RepoHelpers
include AssetsHelpers
@@ -661,4 +661,48 @@ describe SystemNoteService do
described_class.design_discussion_added(discussion_note)
end
end
+
+ describe '.approve_mr' do
+ it 'calls MergeRequestsService' do
+ expect_next_instance_of(::SystemNotes::MergeRequestsService) do |service|
+ expect(service).to receive(:approve_mr)
+ end
+
+ described_class.approve_mr(noteable, author)
+ end
+ end
+
+ describe '.unapprove_mr' do
+ it 'calls MergeRequestsService' do
+ expect_next_instance_of(::SystemNotes::MergeRequestsService) do |service|
+ expect(service).to receive(:unapprove_mr)
+ end
+
+ described_class.unapprove_mr(noteable, author)
+ end
+ end
+
+ describe '.change_alert_status' do
+ let(:alert) { build(:alert_management_alert) }
+
+ it 'calls AlertManagementService' do
+ expect_next_instance_of(SystemNotes::AlertManagementService) do |service|
+ expect(service).to receive(:change_alert_status).with(alert)
+ end
+
+ described_class.change_alert_status(alert, author)
+ end
+ end
+
+ describe '.new_alert_issue' do
+ let(:alert) { build(:alert_management_alert, :with_issue) }
+
+ it 'calls AlertManagementService' do
+ expect_next_instance_of(SystemNotes::AlertManagementService) do |service|
+ expect(service).to receive(:new_alert_issue).with(alert, alert.issue)
+ end
+
+ described_class.new_alert_issue(alert, alert.issue, author)
+ end
+ end
end
diff --git a/spec/services/system_notes/alert_management_service_spec.rb b/spec/services/system_notes/alert_management_service_spec.rb
new file mode 100644
index 00000000000..403763d5fd9
--- /dev/null
+++ b/spec/services/system_notes/alert_management_service_spec.rb
@@ -0,0 +1,35 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe ::SystemNotes::AlertManagementService do
+ let_it_be(:author) { create(:user) }
+ let_it_be(:project) { create(:project, :repository) }
+ let_it_be(:noteable) { create(:alert_management_alert, :with_issue, :acknowledged, project: project) }
+
+ describe '#change_alert_status' do
+ subject { described_class.new(noteable: noteable, project: project, author: author).change_alert_status(noteable) }
+
+ it_behaves_like 'a system note' do
+ let(:action) { 'status' }
+ end
+
+ it 'has the appropriate message' do
+ expect(subject.note).to eq("changed the status to **Acknowledged**")
+ end
+ end
+
+ describe '#new_alert_issue' do
+ let_it_be(:issue) { noteable.issue }
+
+ subject { described_class.new(noteable: noteable, project: project, author: author).new_alert_issue(noteable, issue) }
+
+ it_behaves_like 'a system note' do
+ let(:action) { 'alert_issue_added' }
+ end
+
+ it 'has the appropriate message' do
+ expect(subject.note).to eq("created issue #{issue.to_reference(project)} for this alert")
+ end
+ end
+end
diff --git a/spec/services/system_notes/base_service_spec.rb b/spec/services/system_notes/base_service_spec.rb
index 96788b05829..efb165f8e4c 100644
--- a/spec/services/system_notes/base_service_spec.rb
+++ b/spec/services/system_notes/base_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe SystemNotes::BaseService do
+RSpec.describe SystemNotes::BaseService do
let(:noteable) { double }
let(:project) { double }
let(:author) { double }
diff --git a/spec/services/system_notes/commit_service_spec.rb b/spec/services/system_notes/commit_service_spec.rb
index 5839a17e4a0..bd6b3ec953a 100644
--- a/spec/services/system_notes/commit_service_spec.rb
+++ b/spec/services/system_notes/commit_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe SystemNotes::CommitService do
+RSpec.describe SystemNotes::CommitService do
let_it_be(:group) { create(:group) }
let_it_be(:project) { create(:project, :repository, group: group) }
let_it_be(:author) { create(:user) }
diff --git a/spec/services/system_notes/design_management_service_spec.rb b/spec/services/system_notes/design_management_service_spec.rb
index 08511e62341..6267ad2aaad 100644
--- a/spec/services/system_notes/design_management_service_spec.rb
+++ b/spec/services/system_notes/design_management_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe SystemNotes::DesignManagementService do
+RSpec.describe SystemNotes::DesignManagementService do
let(:project) { create(:project) }
let(:issue) { create(:issue, project: project) }
diff --git a/spec/services/system_notes/issuables_service_spec.rb b/spec/services/system_notes/issuables_service_spec.rb
index c3b3c877583..1b5b26d90da 100644
--- a/spec/services/system_notes/issuables_service_spec.rb
+++ b/spec/services/system_notes/issuables_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe ::SystemNotes::IssuablesService do
+RSpec.describe ::SystemNotes::IssuablesService do
include ProjectForksHelper
let_it_be(:group) { create(:group) }
@@ -161,7 +161,9 @@ describe ::SystemNotes::IssuablesService do
let(:status) { 'reopened' }
let(:source) { nil }
- it { is_expected.to be_nil }
+ it 'does not change note count' do
+ expect { subject }.not_to change { Note.count }
+ end
end
context 'with status reopened' do
@@ -660,25 +662,67 @@ describe ::SystemNotes::IssuablesService do
describe '#close_after_error_tracking_resolve' do
subject { service.close_after_error_tracking_resolve }
- it_behaves_like 'a system note' do
- let(:action) { 'closed' }
+ context 'when state tracking is enabled' do
+ before do
+ stub_feature_flags(track_resource_state_change_events: true)
+ end
+
+ it 'creates the expected state event' do
+ subject
+
+ event = ResourceStateEvent.last
+
+ expect(event.close_after_error_tracking_resolve).to eq(true)
+ expect(event.state).to eq('closed')
+ end
end
- it 'creates the expected system note' do
- expect(subject.note)
+ context 'when state tracking is disabled' do
+ before do
+ stub_feature_flags(track_resource_state_change_events: false)
+ end
+
+ it_behaves_like 'a system note' do
+ let(:action) { 'closed' }
+ end
+
+ it 'creates the expected system note' do
+ expect(subject.note)
.to eq('resolved the corresponding error and closed the issue.')
+ end
end
end
describe '#auto_resolve_prometheus_alert' do
subject { service.auto_resolve_prometheus_alert }
- it_behaves_like 'a system note' do
- let(:action) { 'closed' }
+ context 'when state tracking is enabled' do
+ before do
+ stub_feature_flags(track_resource_state_change_events: true)
+ end
+
+ it 'creates the expected state event' do
+ subject
+
+ event = ResourceStateEvent.last
+
+ expect(event.close_auto_resolve_prometheus_alert).to eq(true)
+ expect(event.state).to eq('closed')
+ end
end
- it 'creates the expected system note' do
- expect(subject.note).to eq('automatically closed this issue because the alert resolved.')
+ context 'when state tracking is disabled' do
+ before do
+ stub_feature_flags(track_resource_state_change_events: false)
+ end
+
+ it_behaves_like 'a system note' do
+ let(:action) { 'closed' }
+ end
+
+ it 'creates the expected system note' do
+ expect(subject.note).to eq('automatically closed this issue because the alert resolved.')
+ end
end
end
end
diff --git a/spec/services/system_notes/merge_requests_service_spec.rb b/spec/services/system_notes/merge_requests_service_spec.rb
index 13d6367a585..067e1cef64d 100644
--- a/spec/services/system_notes/merge_requests_service_spec.rb
+++ b/spec/services/system_notes/merge_requests_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe ::SystemNotes::MergeRequestsService do
+RSpec.describe ::SystemNotes::MergeRequestsService do
include Gitlab::Routing
let_it_be(:group) { create(:group) }
@@ -52,8 +52,8 @@ describe ::SystemNotes::MergeRequestsService do
end
describe '.handle_merge_request_wip' do
- context 'adding wip note' do
- let(:noteable) { create(:merge_request, source_project: project, title: 'WIP Lorem ipsum') }
+ context 'adding draft note' do
+ let(:noteable) { create(:merge_request, source_project: project, title: 'Draft: Lorem ipsum') }
subject { service.handle_merge_request_wip }
@@ -261,4 +261,18 @@ describe ::SystemNotes::MergeRequestsService do
expect(subject.commit_id).to eq(commit_sha)
end
end
+
+ describe '#approve_mr' do
+ subject { described_class.new(noteable: noteable, project: project, author: author).approve_mr }
+
+ it_behaves_like 'a system note' do
+ let(:action) { 'approved' }
+ end
+
+ context 'when merge request approved' do
+ it 'sets the note text' do
+ expect(subject.note).to eq "approved this merge request"
+ end
+ end
+ end
end
diff --git a/spec/services/system_notes/time_tracking_service_spec.rb b/spec/services/system_notes/time_tracking_service_spec.rb
index 7e3e6a75cdf..f671e66cdcd 100644
--- a/spec/services/system_notes/time_tracking_service_spec.rb
+++ b/spec/services/system_notes/time_tracking_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe ::SystemNotes::TimeTrackingService do
+RSpec.describe ::SystemNotes::TimeTrackingService do
let_it_be(:author) { create(:user) }
let_it_be(:project) { create(:project, :repository) }
diff --git a/spec/services/system_notes/zoom_service_spec.rb b/spec/services/system_notes/zoom_service_spec.rb
index 435cdb5748e..986324c9664 100644
--- a/spec/services/system_notes/zoom_service_spec.rb
+++ b/spec/services/system_notes/zoom_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe ::SystemNotes::ZoomService do
+RSpec.describe ::SystemNotes::ZoomService do
let_it_be(:project) { create(:project, :repository) }
let_it_be(:author) { create(:user) }
diff --git a/spec/services/tags/create_service_spec.rb b/spec/services/tags/create_service_spec.rb
index e505960d3c7..b1c6623308e 100644
--- a/spec/services/tags/create_service_spec.rb
+++ b/spec/services/tags/create_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Tags::CreateService do
+RSpec.describe Tags::CreateService do
let(:project) { create(:project, :repository) }
let(:repository) { project.repository }
let(:user) { create(:user) }
diff --git a/spec/services/tags/destroy_service_spec.rb b/spec/services/tags/destroy_service_spec.rb
index b46bd77eafe..6160f337552 100644
--- a/spec/services/tags/destroy_service_spec.rb
+++ b/spec/services/tags/destroy_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Tags::DestroyService do
+RSpec.describe Tags::DestroyService do
let(:project) { create(:project, :repository) }
let(:repository) { project.repository }
let(:user) { create(:user) }
@@ -11,6 +11,10 @@ describe Tags::DestroyService do
describe '#execute' do
subject { service.execute(tag_name) }
+ before do
+ allow(Ci::RefDeleteUnlockArtifactsWorker).to receive(:perform_async)
+ end
+
it 'removes the tag' do
expect(repository).to receive(:before_remove_tag)
expect(service).to receive(:success)
@@ -18,6 +22,12 @@ describe Tags::DestroyService do
service.execute('v1.1.0')
end
+ it 'calls the RefDeleteUnlockArtifactsWorker' do
+ expect(Ci::RefDeleteUnlockArtifactsWorker).to receive(:perform_async).with(project.id, user.id, 'refs/tags/v1.1.0')
+
+ service.execute('v1.1.0')
+ end
+
context 'when there is an associated release on the tag' do
let(:tag) { repository.tags.first }
let(:tag_name) { tag.name }
diff --git a/spec/services/task_list_toggle_service_spec.rb b/spec/services/task_list_toggle_service_spec.rb
index 82a5446dcb8..276f2ae435e 100644
--- a/spec/services/task_list_toggle_service_spec.rb
+++ b/spec/services/task_list_toggle_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe TaskListToggleService do
+RSpec.describe TaskListToggleService do
let(:markdown) do
<<-EOT.strip_heredoc
* [ ] Task 1
diff --git a/spec/services/terraform/remote_state_handler_spec.rb b/spec/services/terraform/remote_state_handler_spec.rb
index f4e1831b2e8..c47367feb14 100644
--- a/spec/services/terraform/remote_state_handler_spec.rb
+++ b/spec/services/terraform/remote_state_handler_spec.rb
@@ -2,9 +2,12 @@
require 'spec_helper'
-describe Terraform::RemoteStateHandler do
+RSpec.describe Terraform::RemoteStateHandler do
let_it_be(:project) { create(:project) }
- let_it_be(:user) { create(:user) }
+ let_it_be(:developer) { create(:user, developer_projects: [project]) }
+ let_it_be(:maintainer) { create(:user, maintainer_projects: [project]) }
+
+ let_it_be(:user) { maintainer }
describe '#find_with_lock' do
context 'without a state name' do
@@ -34,33 +37,6 @@ describe Terraform::RemoteStateHandler do
end
end
- describe '#create_or_find!' do
- it 'requires passing a state name' do
- handler = described_class.new(project, user)
-
- expect { handler.create_or_find! }.to raise_error(ArgumentError)
- end
-
- it 'allows to create states with same name in different projects' do
- project_b = create(:project)
-
- state_a = described_class.new(project, user, name: 'my-state').create_or_find!
- state_b = described_class.new(project_b, user, name: 'my-state').create_or_find!
-
- expect(state_a).to be_persisted
- expect(state_b).to be_persisted
- expect(state_a.id).not_to eq state_b.id
- end
-
- it 'loads the same state upon subsequent call in the project scope' do
- state_a = described_class.new(project, user, name: 'my-state').create_or_find!
- state_b = described_class.new(project, user, name: 'my-state').create_or_find!
-
- expect(state_a).to be_persisted
- expect(state_a.id).to eq state_b.id
- end
- end
-
context 'when state locking is not being used' do
subject { described_class.new(project, user, name: 'my-state') }
@@ -74,7 +50,7 @@ describe Terraform::RemoteStateHandler do
end
it 'returns the state object itself' do
- state = subject.create_or_find!
+ state = subject.handle_with_lock
expect(state.name).to eq 'my-state'
end
@@ -89,10 +65,9 @@ describe Terraform::RemoteStateHandler do
context 'when using locking' do
describe '#handle_with_lock' do
- it 'handles a locked state using exclusive read lock' do
- handler = described_class
- .new(project, user, name: 'new-state', lock_id: 'abc-abc')
+ subject(:handler) { described_class.new(project, user, name: 'new-state', lock_id: 'abc-abc') }
+ it 'handles a locked state using exclusive read lock' do
handler.lock!
state = handler.handle_with_lock do |state|
@@ -101,20 +76,35 @@ describe Terraform::RemoteStateHandler do
expect(state.name).to eq 'new-name'
end
- end
- it 'raises exception if lock has not been acquired before' do
- handler = described_class
- .new(project, user, name: 'new-state', lock_id: 'abc-abc')
+ it 'raises exception if lock has not been acquired before' do
+ expect { handler.handle_with_lock }
+ .to raise_error(described_class::StateLockedError)
+ end
+
+ context 'user does not have permission to modify state' do
+ let(:user) { developer }
- expect { handler.handle_with_lock }
- .to raise_error(described_class::StateLockedError)
+ it 'raises an exception' do
+ expect { handler.handle_with_lock }
+ .to raise_error(described_class::UnauthorizedError)
+ end
+ end
end
describe '#lock!' do
- it 'allows to lock state if it does not exist yet' do
- handler = described_class.new(project, user, name: 'new-state', lock_id: 'abc-abc')
+ let(:lock_id) { 'abc-abc' }
+
+ subject(:handler) do
+ described_class.new(
+ project,
+ user,
+ name: 'new-state',
+ lock_id: lock_id
+ )
+ end
+ it 'allows to lock state if it does not exist yet' do
state = handler.lock!
expect(state).to be_persisted
@@ -122,22 +112,61 @@ describe Terraform::RemoteStateHandler do
end
it 'allows to lock state if it exists and is not locked' do
- state = described_class.new(project, user, name: 'new-state').create_or_find!
- handler = described_class.new(project, user, name: 'new-state', lock_id: 'abc-abc')
+ state = create(:terraform_state, project: project, name: 'new-state')
handler.lock!
- expect(state.reload.lock_xid).to eq 'abc-abc'
+ expect(state.reload.lock_xid).to eq lock_id
expect(state).to be_locked
end
it 'raises an exception when trying to unlocked state locked by someone else' do
- described_class.new(project, user, name: 'new-state', lock_id: 'abc-abc').lock!
-
- handler = described_class.new(project, user, name: 'new-state', lock_id: '12a-23f')
+ described_class.new(project, user, name: 'new-state', lock_id: '12a-23f').lock!
expect { handler.lock! }.to raise_error(described_class::StateLockedError)
end
end
+
+ describe '#unlock!' do
+ let(:lock_id) { 'abc-abc' }
+
+ subject(:handler) do
+ described_class.new(
+ project,
+ user,
+ name: 'new-state',
+ lock_id: lock_id
+ )
+ end
+
+ before do
+ create(:terraform_state, :locked, project: project, name: 'new-state', lock_xid: 'abc-abc')
+ end
+
+ it 'unlocks the state' do
+ state = handler.unlock!
+
+ expect(state.lock_xid).to be_nil
+ end
+
+ context 'with no lock ID (force-unlock)' do
+ let(:lock_id) { }
+
+ it 'unlocks the state' do
+ state = handler.unlock!
+
+ expect(state.lock_xid).to be_nil
+ end
+ end
+
+ context 'with different lock ID' do
+ let(:lock_id) { 'other' }
+
+ it 'raises an exception' do
+ expect { handler.unlock! }
+ .to raise_error(described_class::StateLockedError)
+ end
+ end
+ end
end
end
diff --git a/spec/services/test_hooks/project_service_spec.rb b/spec/services/test_hooks/project_service_spec.rb
index 3c5bc0d85f2..e4cc3a2d652 100644
--- a/spec/services/test_hooks/project_service_spec.rb
+++ b/spec/services/test_hooks/project_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe TestHooks::ProjectService do
+RSpec.describe TestHooks::ProjectService do
let(:current_user) { create(:user) }
describe '#execute' do
diff --git a/spec/services/test_hooks/system_service_spec.rb b/spec/services/test_hooks/system_service_spec.rb
index 8a86b14a2a1..34dd2173b09 100644
--- a/spec/services/test_hooks/system_service_spec.rb
+++ b/spec/services/test_hooks/system_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe TestHooks::SystemService do
+RSpec.describe TestHooks::SystemService do
let(:current_user) { create(:user) }
describe '#execute' do
diff --git a/spec/services/todo_service_spec.rb b/spec/services/todo_service_spec.rb
index f6e1608acbe..b187025eb11 100644
--- a/spec/services/todo_service_spec.rb
+++ b/spec/services/todo_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe TodoService do
+RSpec.describe TodoService do
let(:author) { create(:user) }
let(:assignee) { create(:user) }
let(:non_member) { create(:user) }
diff --git a/spec/services/todos/destroy/confidential_issue_service_spec.rb b/spec/services/todos/destroy/confidential_issue_service_spec.rb
index 9f7e656f7d3..ddce45e7968 100644
--- a/spec/services/todos/destroy/confidential_issue_service_spec.rb
+++ b/spec/services/todos/destroy/confidential_issue_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Todos::Destroy::ConfidentialIssueService do
+RSpec.describe Todos::Destroy::ConfidentialIssueService do
let(:project) { create(:project, :public) }
let(:user) { create(:user) }
let(:author) { create(:user) }
diff --git a/spec/services/todos/destroy/entity_leave_service_spec.rb b/spec/services/todos/destroy/entity_leave_service_spec.rb
index 45e3bf381fb..ccafe3bb7a8 100644
--- a/spec/services/todos/destroy/entity_leave_service_spec.rb
+++ b/spec/services/todos/destroy/entity_leave_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Todos::Destroy::EntityLeaveService do
+RSpec.describe Todos::Destroy::EntityLeaveService do
let(:group) { create(:group, :private) }
let(:project) { create(:project, group: group) }
let(:user) { create(:user) }
diff --git a/spec/services/todos/destroy/group_private_service_spec.rb b/spec/services/todos/destroy/group_private_service_spec.rb
index 7dd495847b3..30d02cb7400 100644
--- a/spec/services/todos/destroy/group_private_service_spec.rb
+++ b/spec/services/todos/destroy/group_private_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Todos::Destroy::GroupPrivateService do
+RSpec.describe Todos::Destroy::GroupPrivateService do
let(:group) { create(:group, :public) }
let(:project) { create(:project, group: group) }
let(:user) { create(:user) }
diff --git a/spec/services/todos/destroy/private_features_service_spec.rb b/spec/services/todos/destroy/private_features_service_spec.rb
index dfe9f42e8b1..6dbd7574b80 100644
--- a/spec/services/todos/destroy/private_features_service_spec.rb
+++ b/spec/services/todos/destroy/private_features_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Todos::Destroy::PrivateFeaturesService do
+RSpec.describe Todos::Destroy::PrivateFeaturesService do
let(:project) { create(:project, :public) }
let(:user) { create(:user) }
let(:another_user) { create(:user) }
diff --git a/spec/services/todos/destroy/project_private_service_spec.rb b/spec/services/todos/destroy/project_private_service_spec.rb
index 7c0c76b6c29..1d1c010535d 100644
--- a/spec/services/todos/destroy/project_private_service_spec.rb
+++ b/spec/services/todos/destroy/project_private_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Todos::Destroy::ProjectPrivateService do
+RSpec.describe Todos::Destroy::ProjectPrivateService do
let(:group) { create(:group, :public) }
let(:project) { create(:project, :public, group: group) }
let(:user) { create(:user) }
diff --git a/spec/services/update_container_registry_info_service_spec.rb b/spec/services/update_container_registry_info_service_spec.rb
new file mode 100644
index 00000000000..740e53b0472
--- /dev/null
+++ b/spec/services/update_container_registry_info_service_spec.rb
@@ -0,0 +1,115 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe UpdateContainerRegistryInfoService do
+ let_it_be(:application_settings) { Gitlab::CurrentSettings }
+ let_it_be(:api_url) { 'http://registry.gitlab' }
+
+ describe '#execute' do
+ before do
+ stub_access_token
+ stub_container_registry_config(enabled: true, api_url: api_url)
+ end
+
+ subject { described_class.new.execute }
+
+ shared_examples 'invalid config' do
+ it 'does not update the application settings' do
+ expect(application_settings).not_to receive(:update!)
+
+ subject
+ end
+
+ it 'does not raise an error' do
+ expect { subject }.not_to raise_error
+ end
+ end
+
+ context 'when container registry is disabled' do
+ before do
+ stub_container_registry_config(enabled: false)
+ end
+
+ it_behaves_like 'invalid config'
+ end
+
+ context 'when container registry api_url is blank' do
+ before do
+ stub_container_registry_config(api_url: '')
+ end
+
+ it_behaves_like 'invalid config'
+ end
+
+ context 'when creating a registry client instance' do
+ let(:token) { 'foo' }
+ let(:client) { ContainerRegistry::Client.new(api_url, token: token) }
+
+ before do
+ stub_registry_info({})
+ end
+
+ it 'uses a token with no access permissions' do
+ expect(Auth::ContainerRegistryAuthenticationService)
+ .to receive(:access_token).with([], []).and_return(token)
+ expect(ContainerRegistry::Client)
+ .to receive(:new).with(api_url, token: token).and_return(client)
+
+ subject
+ end
+ end
+
+ context 'when unabled to detect the container registry type' do
+ it 'sets the application settings to their defaults' do
+ stub_registry_info({})
+
+ subject
+
+ application_settings.reload
+ expect(application_settings.container_registry_vendor).to be_blank
+ expect(application_settings.container_registry_version).to be_blank
+ expect(application_settings.container_registry_features).to eq([])
+ end
+ end
+
+ context 'when able to detect the container registry type' do
+ context 'when using the GitLab container registry' do
+ it 'updates application settings accordingly' do
+ stub_registry_info(vendor: 'gitlab', version: '2.9.1-gitlab', features: %w[a,b,c])
+
+ subject
+
+ application_settings.reload
+ expect(application_settings.container_registry_vendor).to eq('gitlab')
+ expect(application_settings.container_registry_version).to eq('2.9.1-gitlab')
+ expect(application_settings.container_registry_features).to eq(%w[a,b,c])
+ end
+ end
+
+ context 'when using a third-party container registry' do
+ it 'updates application settings accordingly' do
+ stub_registry_info(vendor: 'other', version: nil, features: nil)
+
+ subject
+
+ application_settings.reload
+ expect(application_settings.container_registry_vendor).to eq('other')
+ expect(application_settings.container_registry_version).to be_blank
+ expect(application_settings.container_registry_features).to eq([])
+ end
+ end
+ end
+ end
+
+ def stub_access_token
+ allow(Auth::ContainerRegistryAuthenticationService)
+ .to receive(:access_token).with([], []).and_return('foo')
+ end
+
+ def stub_registry_info(output)
+ allow_next_instance_of(ContainerRegistry::Client) do |client|
+ allow(client).to receive(:registry_info).and_return(output)
+ end
+ end
+end
diff --git a/spec/services/update_merge_request_metrics_service_spec.rb b/spec/services/update_merge_request_metrics_service_spec.rb
index 1aaf5e712f9..a07fcee91e4 100644
--- a/spec/services/update_merge_request_metrics_service_spec.rb
+++ b/spec/services/update_merge_request_metrics_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe MergeRequestMetricsService do
+RSpec.describe MergeRequestMetricsService do
let(:metrics) { create(:merge_request).metrics }
describe '#merge' do
diff --git a/spec/services/upload_service_spec.rb b/spec/services/upload_service_spec.rb
index 504e61f9903..89a28e6a098 100644
--- a/spec/services/upload_service_spec.rb
+++ b/spec/services/upload_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe UploadService do
+RSpec.describe UploadService do
describe 'File service' do
before do
@user = create(:user)
diff --git a/spec/services/user_project_access_changed_service_spec.rb b/spec/services/user_project_access_changed_service_spec.rb
index e5ecdd123f7..070782992e7 100644
--- a/spec/services/user_project_access_changed_service_spec.rb
+++ b/spec/services/user_project_access_changed_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe UserProjectAccessChangedService do
+RSpec.describe UserProjectAccessChangedService do
describe '#execute' do
it 'schedules the user IDs' do
expect(AuthorizedProjectsWorker).to receive(:bulk_perform_and_wait)
diff --git a/spec/services/users/activity_service_spec.rb b/spec/services/users/activity_service_spec.rb
index 5f068a2033c..4bbf6a2bcb8 100644
--- a/spec/services/users/activity_service_spec.rb
+++ b/spec/services/users/activity_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Users::ActivityService do
+RSpec.describe Users::ActivityService do
include ExclusiveLeaseHelpers
let(:user) { create(:user, last_activity_on: last_activity_on) }
diff --git a/spec/services/users/block_service_spec.rb b/spec/services/users/block_service_spec.rb
index c3a65a08c0d..e170a5494aa 100644
--- a/spec/services/users/block_service_spec.rb
+++ b/spec/services/users/block_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Users::BlockService do
+RSpec.describe Users::BlockService do
let(:current_user) { create(:admin) }
subject(:service) { described_class.new(current_user) }
diff --git a/spec/services/users/build_service_spec.rb b/spec/services/users/build_service_spec.rb
index 7588be833ae..c14fdb35bfa 100644
--- a/spec/services/users/build_service_spec.rb
+++ b/spec/services/users/build_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Users::BuildService do
+RSpec.describe Users::BuildService do
describe '#execute' do
let(:params) do
{ name: 'John Doe', username: 'jduser', email: 'jd@example.com', password: 'mydummypass' }
diff --git a/spec/services/users/create_service_spec.rb b/spec/services/users/create_service_spec.rb
index c783a1403df..69d2d6ca9ff 100644
--- a/spec/services/users/create_service_spec.rb
+++ b/spec/services/users/create_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Users::CreateService do
+RSpec.describe Users::CreateService do
describe '#execute' do
let(:admin_user) { create(:admin) }
diff --git a/spec/services/users/destroy_service_spec.rb b/spec/services/users/destroy_service_spec.rb
index 3db5e66fe05..ff919257b3c 100644
--- a/spec/services/users/destroy_service_spec.rb
+++ b/spec/services/users/destroy_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Users::DestroyService do
+RSpec.describe Users::DestroyService do
describe "Deletes a user and all their personal projects" do
let!(:user) { create(:user) }
let!(:admin) { create(:admin) }
diff --git a/spec/services/users/keys_count_service_spec.rb b/spec/services/users/keys_count_service_spec.rb
index 83af051e728..aff267cce5e 100644
--- a/spec/services/users/keys_count_service_spec.rb
+++ b/spec/services/users/keys_count_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Users::KeysCountService, :use_clean_rails_memory_store_caching do
+RSpec.describe Users::KeysCountService, :use_clean_rails_memory_store_caching do
let(:user) { create(:user) }
subject { described_class.new(user) }
diff --git a/spec/services/users/last_push_event_service_spec.rb b/spec/services/users/last_push_event_service_spec.rb
index 424e9e2f8ef..5b755db407f 100644
--- a/spec/services/users/last_push_event_service_spec.rb
+++ b/spec/services/users/last_push_event_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Users::LastPushEventService do
+RSpec.describe Users::LastPushEventService do
let(:user) { build(:user, id: 1) }
let(:project) { build(:project, id: 2) }
let(:event) { build(:push_event, id: 3, author: user, project: project) }
diff --git a/spec/services/users/migrate_to_ghost_user_service_spec.rb b/spec/services/users/migrate_to_ghost_user_service_spec.rb
index c2a793b2368..c9c8f9a74d3 100644
--- a/spec/services/users/migrate_to_ghost_user_service_spec.rb
+++ b/spec/services/users/migrate_to_ghost_user_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Users::MigrateToGhostUserService do
+RSpec.describe Users::MigrateToGhostUserService do
let!(:user) { create(:user) }
let!(:project) { create(:project, :repository) }
let(:service) { described_class.new(user) }
diff --git a/spec/services/users/refresh_authorized_projects_service_spec.rb b/spec/services/users/refresh_authorized_projects_service_spec.rb
index d7ba7f5f69e..e45cb05a6c5 100644
--- a/spec/services/users/refresh_authorized_projects_service_spec.rb
+++ b/spec/services/users/refresh_authorized_projects_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Users::RefreshAuthorizedProjectsService do
+RSpec.describe Users::RefreshAuthorizedProjectsService do
include ExclusiveLeaseHelpers
# We're using let! here so that any expectations for the service class are not
diff --git a/spec/services/users/repair_ldap_blocked_service_spec.rb b/spec/services/users/repair_ldap_blocked_service_spec.rb
index bf80cc79d62..b33dcb92f45 100644
--- a/spec/services/users/repair_ldap_blocked_service_spec.rb
+++ b/spec/services/users/repair_ldap_blocked_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Users::RepairLdapBlockedService do
+RSpec.describe Users::RepairLdapBlockedService do
let(:user) { create(:omniauth_user, provider: 'ldapmain', state: 'ldap_blocked') }
let(:identity) { user.ldap_identity }
diff --git a/spec/services/users/respond_to_terms_service_spec.rb b/spec/services/users/respond_to_terms_service_spec.rb
index d840706e8a5..1997dcd0e04 100644
--- a/spec/services/users/respond_to_terms_service_spec.rb
+++ b/spec/services/users/respond_to_terms_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Users::RespondToTermsService do
+RSpec.describe Users::RespondToTermsService do
let(:user) { create(:user) }
let(:term) { create(:term) }
diff --git a/spec/services/users/set_status_service_spec.rb b/spec/services/users/set_status_service_spec.rb
index 554f5e9dc5e..54489adceb0 100644
--- a/spec/services/users/set_status_service_spec.rb
+++ b/spec/services/users/set_status_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Users::SetStatusService do
+RSpec.describe Users::SetStatusService do
let(:current_user) { create(:user) }
subject(:service) { described_class.new(current_user, params) }
diff --git a/spec/services/users/signup_service_spec.rb b/spec/services/users/signup_service_spec.rb
index 7d3cd614142..cc234309817 100644
--- a/spec/services/users/signup_service_spec.rb
+++ b/spec/services/users/signup_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Users::SignupService do
+RSpec.describe Users::SignupService do
let(:user) { create(:user, setup_for_company: true) }
describe '#execute' do
diff --git a/spec/services/users/update_canonical_email_service_spec.rb b/spec/services/users/update_canonical_email_service_spec.rb
index 68ba1b75b6c..1dead13d338 100644
--- a/spec/services/users/update_canonical_email_service_spec.rb
+++ b/spec/services/users/update_canonical_email_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Users::UpdateCanonicalEmailService do
+RSpec.describe Users::UpdateCanonicalEmailService do
let(:other_email) { "differentaddress@includeddomain.com" }
before do
diff --git a/spec/services/users/update_highest_member_role_service_spec.rb b/spec/services/users/update_highest_member_role_service_spec.rb
index 8063abffc2a..89ddd635bb6 100644
--- a/spec/services/users/update_highest_member_role_service_spec.rb
+++ b/spec/services/users/update_highest_member_role_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Users::UpdateHighestMemberRoleService do
+RSpec.describe Users::UpdateHighestMemberRoleService do
let(:user) { create(:user) }
let(:execute_service) { described_class.new(user).execute }
diff --git a/spec/services/users/update_service_spec.rb b/spec/services/users/update_service_spec.rb
index 8e13e7d9c0c..274c44394f3 100644
--- a/spec/services/users/update_service_spec.rb
+++ b/spec/services/users/update_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Users::UpdateService do
+RSpec.describe Users::UpdateService do
let(:user) { create(:user) }
describe '#execute' do
diff --git a/spec/services/verify_pages_domain_service_spec.rb b/spec/services/verify_pages_domain_service_spec.rb
index 3f08ae84c14..29ad85a16ce 100644
--- a/spec/services/verify_pages_domain_service_spec.rb
+++ b/spec/services/verify_pages_domain_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe VerifyPagesDomainService do
+RSpec.describe VerifyPagesDomainService do
using RSpec::Parameterized::TableSyntax
include EmailHelpers
diff --git a/spec/services/web_hook_service_spec.rb b/spec/services/web_hook_service_spec.rb
index 4a917ecdbb5..2be481c5b62 100644
--- a/spec/services/web_hook_service_spec.rb
+++ b/spec/services/web_hook_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe WebHookService do
+RSpec.describe WebHookService do
include StubRequests
let(:project) { create(:project) }
diff --git a/spec/services/wiki_pages/base_service_spec.rb b/spec/services/wiki_pages/base_service_spec.rb
index fede86a5192..6ccc796014c 100644
--- a/spec/services/wiki_pages/base_service_spec.rb
+++ b/spec/services/wiki_pages/base_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe WikiPages::BaseService do
+RSpec.describe WikiPages::BaseService do
let(:project) { double('project') }
let(:user) { double('user') }
diff --git a/spec/services/wiki_pages/create_service_spec.rb b/spec/services/wiki_pages/create_service_spec.rb
index 2a17805110e..44b57088319 100644
--- a/spec/services/wiki_pages/create_service_spec.rb
+++ b/spec/services/wiki_pages/create_service_spec.rb
@@ -2,6 +2,6 @@
require 'spec_helper'
-describe WikiPages::CreateService do
+RSpec.describe WikiPages::CreateService do
it_behaves_like 'WikiPages::CreateService#execute', :project
end
diff --git a/spec/services/wiki_pages/destroy_service_spec.rb b/spec/services/wiki_pages/destroy_service_spec.rb
index b6fee1fd896..9384ea1cd43 100644
--- a/spec/services/wiki_pages/destroy_service_spec.rb
+++ b/spec/services/wiki_pages/destroy_service_spec.rb
@@ -2,6 +2,6 @@
require 'spec_helper'
-describe WikiPages::DestroyService do
+RSpec.describe WikiPages::DestroyService do
it_behaves_like 'WikiPages::DestroyService#execute', :project
end
diff --git a/spec/services/wiki_pages/event_create_service_spec.rb b/spec/services/wiki_pages/event_create_service_spec.rb
index c725c67d7a7..abf3bcb4c4d 100644
--- a/spec/services/wiki_pages/event_create_service_spec.rb
+++ b/spec/services/wiki_pages/event_create_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe WikiPages::EventCreateService do
+RSpec.describe WikiPages::EventCreateService do
let_it_be(:project) { create(:project) }
let_it_be(:user) { create(:user) }
@@ -14,21 +14,6 @@ describe WikiPages::EventCreateService do
let(:action) { :created }
let(:response) { subject.execute(slug, page, action) }
- context 'feature flag is not enabled' do
- before do
- stub_feature_flags(wiki_events: false)
- end
-
- it 'does not error' do
- expect(response).to be_success
- .and have_attributes(message: /No event created/)
- end
-
- it 'does not create an event' do
- expect { response }.not_to change(Event, :count)
- end
- end
-
context 'the user is nil' do
subject { described_class.new(nil) }
diff --git a/spec/services/wiki_pages/update_service_spec.rb b/spec/services/wiki_pages/update_service_spec.rb
index ac629a96f9a..33ac98e764d 100644
--- a/spec/services/wiki_pages/update_service_spec.rb
+++ b/spec/services/wiki_pages/update_service_spec.rb
@@ -2,6 +2,6 @@
require 'spec_helper'
-describe WikiPages::UpdateService do
+RSpec.describe WikiPages::UpdateService do
it_behaves_like 'WikiPages::UpdateService#execute', :project
end
diff --git a/spec/services/wikis/create_attachment_service_spec.rb b/spec/services/wikis/create_attachment_service_spec.rb
index 4adfaa24874..50cb9ac111c 100644
--- a/spec/services/wikis/create_attachment_service_spec.rb
+++ b/spec/services/wikis/create_attachment_service_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
require 'spec_helper'
-describe Wikis::CreateAttachmentService do
+RSpec.describe Wikis::CreateAttachmentService do
let(:container) { create(:project, :wiki_repo) }
let(:user) { create(:user) }
let(:file_name) { 'filename.txt' }
diff --git a/spec/services/x509_certificate_revoke_service_spec.rb b/spec/services/x509_certificate_revoke_service_spec.rb
index c2b2576904c..adad3281c13 100644
--- a/spec/services/x509_certificate_revoke_service_spec.rb
+++ b/spec/services/x509_certificate_revoke_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe X509CertificateRevokeService do
+RSpec.describe X509CertificateRevokeService do
describe '#execute' do
let(:service) { described_class.new }
let!(:x509_signature_1) { create(:x509_commit_signature, x509_certificate: x509_certificate, verification_status: :verified ) }