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

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'spec/requests/api/graphql')
-rw-r--r--spec/requests/api/graphql/boards/board_list_issues_query_spec.rb2
-rw-r--r--spec/requests/api/graphql/boards/board_list_query_spec.rb2
-rw-r--r--spec/requests/api/graphql/boards/board_lists_query_spec.rb2
-rw-r--r--spec/requests/api/graphql/boards/boards_query_spec.rb2
-rw-r--r--spec/requests/api/graphql/ci/application_setting_spec.rb2
-rw-r--r--spec/requests/api/graphql/ci/ci_cd_setting_spec.rb2
-rw-r--r--spec/requests/api/graphql/ci/config_spec.rb2
-rw-r--r--spec/requests/api/graphql/ci/config_variables_spec.rb2
-rw-r--r--spec/requests/api/graphql/ci/group_variables_spec.rb2
-rw-r--r--spec/requests/api/graphql/ci/groups_spec.rb2
-rw-r--r--spec/requests/api/graphql/ci/instance_variables_spec.rb2
-rw-r--r--spec/requests/api/graphql/ci/job_artifacts_spec.rb2
-rw-r--r--spec/requests/api/graphql/ci/job_spec.rb2
-rw-r--r--spec/requests/api/graphql/ci/jobs_spec.rb63
-rw-r--r--spec/requests/api/graphql/ci/manual_variables_spec.rb2
-rw-r--r--spec/requests/api/graphql/ci/pipeline_schedules_spec.rb58
-rw-r--r--spec/requests/api/graphql/ci/pipelines_spec.rb2
-rw-r--r--spec/requests/api/graphql/ci/project_variables_spec.rb2
-rw-r--r--spec/requests/api/graphql/ci/runner_spec.rb264
-rw-r--r--spec/requests/api/graphql/ci/runner_web_url_edge_spec.rb2
-rw-r--r--spec/requests/api/graphql/ci/runners_spec.rb4
-rw-r--r--spec/requests/api/graphql/ci/stages_spec.rb2
-rw-r--r--spec/requests/api/graphql/ci/template_spec.rb2
-rw-r--r--spec/requests/api/graphql/container_repository/container_repository_details_spec.rb2
-rw-r--r--spec/requests/api/graphql/crm/contacts_spec.rb2
-rw-r--r--spec/requests/api/graphql/current_user/groups_query_spec.rb2
-rw-r--r--spec/requests/api/graphql/current_user/todos_query_spec.rb4
-rw-r--r--spec/requests/api/graphql/current_user_query_spec.rb2
-rw-r--r--spec/requests/api/graphql/current_user_todos_spec.rb3
-rw-r--r--spec/requests/api/graphql/custom_emoji_query_spec.rb2
-rw-r--r--spec/requests/api/graphql/environments/deployments_spec.rb (renamed from spec/requests/api/graphql/environments/deployments_query_spec.rb)39
-rw-r--r--spec/requests/api/graphql/gitlab_schema_spec.rb2
-rw-r--r--spec/requests/api/graphql/group/container_repositories_spec.rb2
-rw-r--r--spec/requests/api/graphql/group/dependency_proxy_blobs_spec.rb2
-rw-r--r--spec/requests/api/graphql/group/dependency_proxy_group_setting_spec.rb2
-rw-r--r--spec/requests/api/graphql/group/dependency_proxy_image_ttl_policy_spec.rb2
-rw-r--r--spec/requests/api/graphql/group/dependency_proxy_manifests_spec.rb2
-rw-r--r--spec/requests/api/graphql/group/group_members_spec.rb2
-rw-r--r--spec/requests/api/graphql/group/issues_spec.rb2
-rw-r--r--spec/requests/api/graphql/group/labels_query_spec.rb2
-rw-r--r--spec/requests/api/graphql/group/merge_requests_spec.rb2
-rw-r--r--spec/requests/api/graphql/group/milestones_spec.rb2
-rw-r--r--spec/requests/api/graphql/group/packages_spec.rb2
-rw-r--r--spec/requests/api/graphql/group/recent_issue_boards_query_spec.rb2
-rw-r--r--spec/requests/api/graphql/group/timelogs_spec.rb2
-rw-r--r--spec/requests/api/graphql/group/work_item_types_spec.rb2
-rw-r--r--spec/requests/api/graphql/group_query_spec.rb2
-rw-r--r--spec/requests/api/graphql/issue/issue_spec.rb2
-rw-r--r--spec/requests/api/graphql/issue_status_counts_spec.rb2
-rw-r--r--spec/requests/api/graphql/issues_spec.rb128
-rw-r--r--spec/requests/api/graphql/jobs_query_spec.rb2
-rw-r--r--spec/requests/api/graphql/merge_request/merge_request_spec.rb2
-rw-r--r--spec/requests/api/graphql/metadata_query_spec.rb2
-rw-r--r--spec/requests/api/graphql/metrics/dashboard/annotations_spec.rb2
-rw-r--r--spec/requests/api/graphql/metrics/dashboard_query_spec.rb155
-rw-r--r--spec/requests/api/graphql/milestone_spec.rb2
-rw-r--r--spec/requests/api/graphql/multiplexed_queries_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/admin/sidekiq_queues/delete_jobs_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/alert_management/alerts/create_alert_issue_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/alert_management/alerts/set_assignees_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/alert_management/alerts/todo/create_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/alert_management/alerts/update_alert_status_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/alert_management/http_integration/create_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/alert_management/http_integration/destroy_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/alert_management/http_integration/reset_token_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/alert_management/http_integration/update_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/alert_management/prometheus_integration/create_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/alert_management/prometheus_integration/reset_token_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/alert_management/prometheus_integration/update_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/award_emojis/add_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/award_emojis/remove_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/award_emojis/toggle_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/boards/create_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/boards/destroy_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/boards/issues/issue_move_list_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/boards/lists/create_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/boards/lists/destroy_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/boards/lists/update_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/branches/create_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/ci/job/artifacts_destroy_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/ci/job/destroy_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/ci/job_artifact/destroy_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/ci/job_cancel_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/ci/job_play_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/ci/job_retry_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/ci/job_token_scope/add_project_spec.rb4
-rw-r--r--spec/requests/api/graphql/mutations/ci/job_token_scope/remove_project_spec.rb4
-rw-r--r--spec/requests/api/graphql/mutations/ci/job_unschedule_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/ci/pipeline_cancel_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/ci/pipeline_destroy_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/ci/pipeline_retry_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/ci/pipeline_schedule_create_spec.rb151
-rw-r--r--spec/requests/api/graphql/mutations/ci/pipeline_schedule_delete_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/ci/pipeline_schedule_play_spec.rb80
-rw-r--r--spec/requests/api/graphql/mutations/ci/pipeline_schedule_take_ownership_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/ci/project_ci_cd_settings_update_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/ci/runners_registration_token/reset_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/clusters/agent_tokens/agent_tokens/create_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/clusters/agents/create_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/clusters/agents/delete_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/commits/create_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/container_expiration_policy/update_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/container_repository/destroy_spec.rb21
-rw-r--r--spec/requests/api/graphql/mutations/container_repository/destroy_tags_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/custom_emoji/create_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/custom_emoji/destroy_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/dependency_proxy/group_settings/update_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/dependency_proxy/image_ttl_group_policy/update_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/design_management/delete_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/design_management/move_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/design_management/upload_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/discussions/toggle_resolve_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/environments/canary_ingress/update_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/groups/update_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/incident_management/timeline_event/create_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/incident_management/timeline_event/destroy_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/incident_management/timeline_event/promote_from_note_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/incident_management/timeline_event/update_spec.rb43
-rw-r--r--spec/requests/api/graphql/mutations/incident_management/timeline_event_tag/create_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/issues/create_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/issues/link_alerts_spec.rb65
-rw-r--r--spec/requests/api/graphql/mutations/issues/move_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/issues/set_confidential_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/issues/set_crm_contacts_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/issues/set_due_date_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/issues/set_escalation_status_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/issues/set_locked_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/issues/set_severity_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/issues/set_subscription_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/issues/unlink_alerts_spec.rb89
-rw-r--r--spec/requests/api/graphql/mutations/issues/update_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/jira_import/import_users_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/jira_import/start_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/labels/create_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/merge_requests/create_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/merge_requests/reviewer_rereview_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/merge_requests/set_assignees_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/merge_requests/set_draft_spec.rb4
-rw-r--r--spec/requests/api/graphql/mutations/merge_requests/set_locked_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/merge_requests/set_milestone_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/merge_requests/set_reviewers_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/merge_requests/set_subscription_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/metrics/dashboard/annotations/create_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/metrics/dashboard/annotations/delete_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/namespace/package_settings/update_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/notes/create/diff_note_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/notes/create/image_diff_note_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/notes/create/note_spec.rb31
-rw-r--r--spec/requests/api/graphql/mutations/notes/destroy_spec.rb41
-rw-r--r--spec/requests/api/graphql/mutations/notes/reposition_image_diff_note_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/notes/update/image_diff_note_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/notes/update/note_spec.rb59
-rw-r--r--spec/requests/api/graphql/mutations/packages/bulk_destroy_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/packages/cleanup/policy/update_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/packages/destroy_file_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/packages/destroy_files_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/packages/destroy_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/release_asset_links/create_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/release_asset_links/delete_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/release_asset_links/update_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/releases/create_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/releases/delete_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/releases/update_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/security/ci_configuration/configure_sast_iac_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/security/ci_configuration/configure_secret_detection_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/snippets/create_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/snippets/destroy_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/snippets/mark_as_spam_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/snippets/update_spec.rb15
-rw-r--r--spec/requests/api/graphql/mutations/timelogs/create_spec.rb10
-rw-r--r--spec/requests/api/graphql/mutations/timelogs/delete_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/todos/create_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/todos/mark_all_done_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/todos/mark_done_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/todos/restore_many_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/todos/restore_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/uploads/delete_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/user_callouts/create_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/user_preferences/update_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/work_items/create_from_task_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/work_items/create_spec.rb4
-rw-r--r--spec/requests/api/graphql/mutations/work_items/delete_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/work_items/delete_task_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/work_items/update_spec.rb10
-rw-r--r--spec/requests/api/graphql/mutations/work_items/update_task_spec.rb2
-rw-r--r--spec/requests/api/graphql/namespace/package_settings_spec.rb2
-rw-r--r--spec/requests/api/graphql/namespace/projects_spec.rb2
-rw-r--r--spec/requests/api/graphql/namespace/root_storage_statistics_spec.rb2
-rw-r--r--spec/requests/api/graphql/namespace_query_spec.rb2
-rw-r--r--spec/requests/api/graphql/packages/composer_spec.rb2
-rw-r--r--spec/requests/api/graphql/packages/conan_spec.rb2
-rw-r--r--spec/requests/api/graphql/packages/helm_spec.rb2
-rw-r--r--spec/requests/api/graphql/packages/maven_spec.rb2
-rw-r--r--spec/requests/api/graphql/packages/nuget_spec.rb2
-rw-r--r--spec/requests/api/graphql/packages/package_spec.rb13
-rw-r--r--spec/requests/api/graphql/packages/pypi_spec.rb2
-rw-r--r--spec/requests/api/graphql/project/alert_management/alert/assignees_spec.rb2
-rw-r--r--spec/requests/api/graphql/project/alert_management/alert/issue_spec.rb2
-rw-r--r--spec/requests/api/graphql/project/alert_management/alert/metrics_dashboard_url_spec.rb2
-rw-r--r--spec/requests/api/graphql/project/alert_management/alert/notes_spec.rb2
-rw-r--r--spec/requests/api/graphql/project/alert_management/alert/todos_spec.rb2
-rw-r--r--spec/requests/api/graphql/project/alert_management/alert_status_counts_spec.rb2
-rw-r--r--spec/requests/api/graphql/project/alert_management/alerts_spec.rb4
-rw-r--r--spec/requests/api/graphql/project/alert_management/integrations_spec.rb2
-rw-r--r--spec/requests/api/graphql/project/base_service_spec.rb2
-rw-r--r--spec/requests/api/graphql/project/branch_protections/merge_access_levels_spec.rb4
-rw-r--r--spec/requests/api/graphql/project/branch_protections/push_access_levels_spec.rb4
-rw-r--r--spec/requests/api/graphql/project/branch_rules/branch_protection_spec.rb2
-rw-r--r--spec/requests/api/graphql/project/branch_rules_spec.rb81
-rw-r--r--spec/requests/api/graphql/project/cluster_agents_spec.rb2
-rw-r--r--spec/requests/api/graphql/project/container_expiration_policy_spec.rb2
-rw-r--r--spec/requests/api/graphql/project/container_repositories_spec.rb2
-rw-r--r--spec/requests/api/graphql/project/deployment_spec.rb2
-rw-r--r--spec/requests/api/graphql/project/environments_spec.rb133
-rw-r--r--spec/requests/api/graphql/project/error_tracking/sentry_detailed_error_request_spec.rb2
-rw-r--r--spec/requests/api/graphql/project/error_tracking/sentry_errors_request_spec.rb2
-rw-r--r--spec/requests/api/graphql/project/fork_details_spec.rb60
-rw-r--r--spec/requests/api/graphql/project/fork_targets_spec.rb2
-rw-r--r--spec/requests/api/graphql/project/grafana_integration_spec.rb2
-rw-r--r--spec/requests/api/graphql/project/incident_management/timeline_events_spec.rb2
-rw-r--r--spec/requests/api/graphql/project/issue/design_collection/version_spec.rb11
-rw-r--r--spec/requests/api/graphql/project/issue/design_collection/versions_spec.rb2
-rw-r--r--spec/requests/api/graphql/project/issue/designs/designs_spec.rb2
-rw-r--r--spec/requests/api/graphql/project/issue/designs/notes_spec.rb2
-rw-r--r--spec/requests/api/graphql/project/issue/notes_spec.rb2
-rw-r--r--spec/requests/api/graphql/project/issue_spec.rb2
-rw-r--r--spec/requests/api/graphql/project/issues_spec.rb698
-rw-r--r--spec/requests/api/graphql/project/jira_import_spec.rb2
-rw-r--r--spec/requests/api/graphql/project/jira_projects_spec.rb2
-rw-r--r--spec/requests/api/graphql/project/jira_service_spec.rb2
-rw-r--r--spec/requests/api/graphql/project/job_spec.rb2
-rw-r--r--spec/requests/api/graphql/project/jobs_spec.rb2
-rw-r--r--spec/requests/api/graphql/project/labels_query_spec.rb2
-rw-r--r--spec/requests/api/graphql/project/languages_spec.rb2
-rw-r--r--spec/requests/api/graphql/project/merge_request/diff_notes_spec.rb2
-rw-r--r--spec/requests/api/graphql/project/merge_request/pipelines_spec.rb2
-rw-r--r--spec/requests/api/graphql/project/merge_request_spec.rb2
-rw-r--r--spec/requests/api/graphql/project/merge_requests_spec.rb2
-rw-r--r--spec/requests/api/graphql/project/milestones_spec.rb2
-rw-r--r--spec/requests/api/graphql/project/packages_cleanup_policy_spec.rb2
-rw-r--r--spec/requests/api/graphql/project/packages_spec.rb2
-rw-r--r--spec/requests/api/graphql/project/pipeline_spec.rb2
-rw-r--r--spec/requests/api/graphql/project/project_members_spec.rb2
-rw-r--r--spec/requests/api/graphql/project/project_pipeline_statistics_spec.rb2
-rw-r--r--spec/requests/api/graphql/project/project_statistics_spec.rb2
-rw-r--r--spec/requests/api/graphql/project/recent_issue_boards_query_spec.rb2
-rw-r--r--spec/requests/api/graphql/project/release_spec.rb2
-rw-r--r--spec/requests/api/graphql/project/releases_spec.rb2
-rw-r--r--spec/requests/api/graphql/project/repository/blobs_spec.rb2
-rw-r--r--spec/requests/api/graphql/project/repository_spec.rb2
-rw-r--r--spec/requests/api/graphql/project/runners_spec.rb68
-rw-r--r--spec/requests/api/graphql/project/terraform/state_spec.rb2
-rw-r--r--spec/requests/api/graphql/project/terraform/states_spec.rb2
-rw-r--r--spec/requests/api/graphql/project/tree/tree_spec.rb50
-rw-r--r--spec/requests/api/graphql/project/work_item_types_spec.rb2
-rw-r--r--spec/requests/api/graphql/project/work_items_spec.rb134
-rw-r--r--spec/requests/api/graphql/project_query_spec.rb2
-rw-r--r--spec/requests/api/graphql/query_spec.rb2
-rw-r--r--spec/requests/api/graphql/read_only_spec.rb2
-rw-r--r--spec/requests/api/graphql/snippets_spec.rb2
-rw-r--r--spec/requests/api/graphql/tasks/task_completion_status_spec.rb2
-rw-r--r--spec/requests/api/graphql/terraform/state/delete_spec.rb2
-rw-r--r--spec/requests/api/graphql/terraform/state/lock_spec.rb2
-rw-r--r--spec/requests/api/graphql/terraform/state/unlock_spec.rb2
-rw-r--r--spec/requests/api/graphql/todo_query_spec.rb2
-rw-r--r--spec/requests/api/graphql/usage_trends_measurements_spec.rb2
-rw-r--r--spec/requests/api/graphql/user/group_member_query_spec.rb2
-rw-r--r--spec/requests/api/graphql/user/project_member_query_spec.rb2
-rw-r--r--spec/requests/api/graphql/user/starred_projects_query_spec.rb2
-rw-r--r--spec/requests/api/graphql/user_query_spec.rb2
-rw-r--r--spec/requests/api/graphql/user_spec.rb2
-rw-r--r--spec/requests/api/graphql/users_spec.rb2
-rw-r--r--spec/requests/api/graphql/work_item_spec.rb12
273 files changed, 1862 insertions, 1229 deletions
diff --git a/spec/requests/api/graphql/boards/board_list_issues_query_spec.rb b/spec/requests/api/graphql/boards/board_list_issues_query_spec.rb
index 9bed720c815..2775c3d4c5a 100644
--- a/spec/requests/api/graphql/boards/board_list_issues_query_spec.rb
+++ b/spec/requests/api/graphql/boards/board_list_issues_query_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'get board lists' do
+RSpec.describe 'get board lists', feature_category: :team_planning do
include GraphqlHelpers
let_it_be(:user) { create(:user) }
diff --git a/spec/requests/api/graphql/boards/board_list_query_spec.rb b/spec/requests/api/graphql/boards/board_list_query_spec.rb
index f01f7e87f10..b5ed0fe35d5 100644
--- a/spec/requests/api/graphql/boards/board_list_query_spec.rb
+++ b/spec/requests/api/graphql/boards/board_list_query_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Querying a Board list' do
+RSpec.describe 'Querying a Board list', feature_category: :team_planning do
include GraphqlHelpers
let_it_be(:current_user) { create(:user) }
diff --git a/spec/requests/api/graphql/boards/board_lists_query_spec.rb b/spec/requests/api/graphql/boards/board_lists_query_spec.rb
index ad7df5c9344..2f23e93e2c6 100644
--- a/spec/requests/api/graphql/boards/board_lists_query_spec.rb
+++ b/spec/requests/api/graphql/boards/board_lists_query_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'get board lists' do
+RSpec.describe 'get board lists', feature_category: :team_planning do
include GraphqlHelpers
let_it_be(:user) { create(:user) }
diff --git a/spec/requests/api/graphql/boards/boards_query_spec.rb b/spec/requests/api/graphql/boards/boards_query_spec.rb
index 50004e5a8a1..1407034fa5f 100644
--- a/spec/requests/api/graphql/boards/boards_query_spec.rb
+++ b/spec/requests/api/graphql/boards/boards_query_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'get list of boards' do
+RSpec.describe 'get list of boards', feature_category: :team_planning do
include GraphqlHelpers
include_context 'group and project boards query context'
diff --git a/spec/requests/api/graphql/ci/application_setting_spec.rb b/spec/requests/api/graphql/ci/application_setting_spec.rb
index 156ee550f16..42ab1786fee 100644
--- a/spec/requests/api/graphql/ci/application_setting_spec.rb
+++ b/spec/requests/api/graphql/ci/application_setting_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'getting Application Settings' do
+RSpec.describe 'getting Application Settings', feature_category: :continuous_integration do
include GraphqlHelpers
let(:fields) do
diff --git a/spec/requests/api/graphql/ci/ci_cd_setting_spec.rb b/spec/requests/api/graphql/ci/ci_cd_setting_spec.rb
index 2dc7b9764fe..0437a30eccd 100644
--- a/spec/requests/api/graphql/ci/ci_cd_setting_spec.rb
+++ b/spec/requests/api/graphql/ci/ci_cd_setting_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
require 'spec_helper'
-RSpec.describe 'Getting Ci Cd Setting' do
+RSpec.describe 'Getting Ci Cd Setting', feature_category: :continuous_integration do
include GraphqlHelpers
let_it_be_with_reload(:project) { create(:project, :repository) }
diff --git a/spec/requests/api/graphql/ci/config_spec.rb b/spec/requests/api/graphql/ci/config_spec.rb
index 784019ee926..8154f132430 100644
--- a/spec/requests/api/graphql/ci/config_spec.rb
+++ b/spec/requests/api/graphql/ci/config_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Query.ciConfig' do
+RSpec.describe 'Query.ciConfig', feature_category: :continuous_integration do
include GraphqlHelpers
include StubRequests
diff --git a/spec/requests/api/graphql/ci/config_variables_spec.rb b/spec/requests/api/graphql/ci/config_variables_spec.rb
index 17133d7ea66..e6d73701b8f 100644
--- a/spec/requests/api/graphql/ci/config_variables_spec.rb
+++ b/spec/requests/api/graphql/ci/config_variables_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Query.project(fullPath).ciConfigVariables(sha)' do
+RSpec.describe 'Query.project(fullPath).ciConfigVariables(sha)', feature_category: :pipeline_authoring do
include GraphqlHelpers
include ReactiveCachingHelpers
diff --git a/spec/requests/api/graphql/ci/group_variables_spec.rb b/spec/requests/api/graphql/ci/group_variables_spec.rb
index 7baf26c7648..51cbb4719f7 100644
--- a/spec/requests/api/graphql/ci/group_variables_spec.rb
+++ b/spec/requests/api/graphql/ci/group_variables_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Query.group(fullPath).ciVariables' do
+RSpec.describe 'Query.group(fullPath).ciVariables', feature_category: :pipeline_authoring do
include GraphqlHelpers
let_it_be(:group) { create(:group) }
diff --git a/spec/requests/api/graphql/ci/groups_spec.rb b/spec/requests/api/graphql/ci/groups_spec.rb
index d1a4395d2c9..d1588833d8f 100644
--- a/spec/requests/api/graphql/ci/groups_spec.rb
+++ b/spec/requests/api/graphql/ci/groups_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
require 'spec_helper'
-RSpec.describe 'Query.project.pipeline.stages.groups' do
+RSpec.describe 'Query.project.pipeline.stages.groups', feature_category: :continuous_integration do
include GraphqlHelpers
let_it_be(:project) { create(:project, :repository, :public) }
diff --git a/spec/requests/api/graphql/ci/instance_variables_spec.rb b/spec/requests/api/graphql/ci/instance_variables_spec.rb
index cd6b2de98a1..e0397e17923 100644
--- a/spec/requests/api/graphql/ci/instance_variables_spec.rb
+++ b/spec/requests/api/graphql/ci/instance_variables_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Query.ciVariables' do
+RSpec.describe 'Query.ciVariables', feature_category: :pipeline_authoring do
include GraphqlHelpers
let(:query) do
diff --git a/spec/requests/api/graphql/ci/job_artifacts_spec.rb b/spec/requests/api/graphql/ci/job_artifacts_spec.rb
index df6e398fbe5..5fcb363d479 100644
--- a/spec/requests/api/graphql/ci/job_artifacts_spec.rb
+++ b/spec/requests/api/graphql/ci/job_artifacts_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Query.project(fullPath).pipelines.jobs.artifacts' do
+RSpec.describe 'Query.project(fullPath).pipelines.jobs.artifacts', feature_category: :build do
include GraphqlHelpers
let_it_be(:project) { create(:project, :repository, :public) }
diff --git a/spec/requests/api/graphql/ci/job_spec.rb b/spec/requests/api/graphql/ci/job_spec.rb
index 3721155c71b..8121c5e5c85 100644
--- a/spec/requests/api/graphql/ci/job_spec.rb
+++ b/spec/requests/api/graphql/ci/job_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Query.project(fullPath).pipelines.job(id)' do
+RSpec.describe 'Query.project(fullPath).pipelines.job(id)', feature_category: :continuous_integration do
include GraphqlHelpers
around do |example|
diff --git a/spec/requests/api/graphql/ci/jobs_spec.rb b/spec/requests/api/graphql/ci/jobs_spec.rb
index a161c5c98ed..7a1dc614dcf 100644
--- a/spec/requests/api/graphql/ci/jobs_spec.rb
+++ b/spec/requests/api/graphql/ci/jobs_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
require 'spec_helper'
-RSpec.describe 'Query.project.pipeline' do
+RSpec.describe 'Query.project.pipeline', feature_category: :continuous_integration do
include GraphqlHelpers
let_it_be(:project) { create(:project, :repository, :public) }
@@ -367,4 +367,65 @@ RSpec.describe 'Query.project.pipeline' do
expect_graphql_errors_to_include [/"jobs" field can be requested only for 1 Project\(s\) at a time./]
end
end
+
+ context 'when batched querying jobs for multiple projects' do
+ let(:batched) do
+ [
+ { query: query_1 },
+ { query: query_2 }
+ ]
+ end
+
+ let(:query_1) do
+ %(
+ query Page1 {
+ projects {
+ nodes {
+ jobs {
+ nodes {
+ name
+ }
+ }
+ }
+ }
+ }
+ )
+ end
+
+ let(:query_2) do
+ %(
+ query Page2 {
+ projects {
+ nodes {
+ jobs {
+ nodes {
+ name
+ }
+ }
+ }
+ }
+ }
+ )
+ end
+
+ before do
+ create_list(:project, 2).each do |project|
+ project.add_developer(user)
+ create(:ci_build, project: project)
+ end
+ end
+
+ it 'limits the specific field evaluation per query' do
+ get_multiplex(batched, current_user: user)
+
+ resp = json_response
+
+ expect(resp.first.dig('data', 'projects', 'nodes').first.dig('jobs', 'nodes').first['name']).to eq('test')
+ expect(resp.first['errors'].first['message'])
+ .to match(/"jobs" field can be requested only for 1 Project\(s\) at a time./)
+ expect(resp.second.dig('data', 'projects', 'nodes').first.dig('jobs', 'nodes').first['name']).to eq('test')
+ expect(resp.second['errors'].first['message'])
+ .to match(/"jobs" field can be requested only for 1 Project\(s\) at a time./)
+ end
+ end
end
diff --git a/spec/requests/api/graphql/ci/manual_variables_spec.rb b/spec/requests/api/graphql/ci/manual_variables_spec.rb
index a15bac2b8bd..921c69e535d 100644
--- a/spec/requests/api/graphql/ci/manual_variables_spec.rb
+++ b/spec/requests/api/graphql/ci/manual_variables_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Query.project(fullPath).pipelines.jobs.manualVariables' do
+RSpec.describe 'Query.project(fullPath).pipelines.jobs.manualVariables', feature_category: :pipeline_authoring do
include GraphqlHelpers
let_it_be(:project) { create(:project) }
diff --git a/spec/requests/api/graphql/ci/pipeline_schedules_spec.rb b/spec/requests/api/graphql/ci/pipeline_schedules_spec.rb
index 8b8ba09a95c..76adce6ff1b 100644
--- a/spec/requests/api/graphql/ci/pipeline_schedules_spec.rb
+++ b/spec/requests/api/graphql/ci/pipeline_schedules_spec.rb
@@ -2,11 +2,11 @@
require 'spec_helper'
-RSpec.describe 'Query.project.pipelineSchedules' do
+RSpec.describe 'Query.project.pipelineSchedules', feature_category: :continuous_integration do
include GraphqlHelpers
- let_it_be(:project) { create(:project, :repository, :public) }
let_it_be(:user) { create(:user) }
+ let_it_be(:project) { create(:project, :repository, :public, creator: user, namespace: user.namespace) }
let_it_be(:pipeline_schedule) { create(:ci_pipeline_schedule, project: project, owner: user) }
let(:pipeline_schedule_graphql_data) { graphql_data_at(:project, :pipeline_schedules, :nodes, 0) }
@@ -29,6 +29,8 @@ RSpec.describe 'Query.project.pipelineSchedules' do
forTag
cron
cronTimezone
+ editPath
+ variables { nodes { #{all_graphql_fields_for('PipelineScheduleVariable')} } }
}
QUERY
end
@@ -61,6 +63,58 @@ RSpec.describe 'Query.project.pipelineSchedules' do
expect(pipeline_schedule_graphql_data['refPath']).to eq("/#{project.full_path}/-/commits/#{ref_for_display}")
expect(pipeline_schedule_graphql_data['forTag']).to be(false)
end
+
+ it 'returns the edit_path for a pipeline schedule' do
+ edit_path = pipeline_schedule_graphql_data['editPath']
+
+ expect(edit_path).to eq("/#{project.full_path}/-/pipeline_schedules/#{pipeline_schedule.id}/edit")
+ end
+ end
+
+ describe 'variables' do
+ let!(:env_vars) { create_list(:ci_pipeline_schedule_variable, 5, pipeline_schedule: pipeline_schedule) }
+
+ it 'returns all variables' do
+ post_graphql(query, current_user: user)
+
+ variables = pipeline_schedule_graphql_data['variables']['nodes']
+ expected = env_vars.map do |var|
+ a_graphql_entity_for(var, :key, :value, variable_type: var.variable_type.upcase)
+ end
+
+ expect(variables).to match_array(expected)
+ end
+
+ it 'is N+1 safe on the variables level' do
+ baseline = ActiveRecord::QueryRecorder.new { post_graphql(query, current_user: user) }
+
+ create_list(:ci_pipeline_schedule_variable, 2, pipeline_schedule: pipeline_schedule)
+
+ expect { post_graphql(query, current_user: user) }.not_to exceed_query_limit(baseline)
+ end
+
+ it 'is N+1 safe on the schedules level' do
+ baseline = ActiveRecord::QueryRecorder.new { post_graphql(query, current_user: user) }
+
+ pipeline_schedule_2 = create(:ci_pipeline_schedule, project: project, owner: user)
+ create_list(:ci_pipeline_schedule_variable, 2, pipeline_schedule: pipeline_schedule_2)
+
+ expect { post_graphql(query, current_user: user) }.not_to exceed_query_limit(baseline)
+ end
+ end
+
+ describe 'permissions' do
+ let_it_be(:another_user) { create(:user) }
+
+ before do
+ post_graphql(query, current_user: another_user)
+ end
+
+ it 'does not return the edit_path for a pipeline schedule for a user that does not have permissions' do
+ edit_path = pipeline_schedule_graphql_data['editPath']
+
+ expect(edit_path).to be nil
+ end
end
it 'avoids N+1 queries' do
diff --git a/spec/requests/api/graphql/ci/pipelines_spec.rb b/spec/requests/api/graphql/ci/pipelines_spec.rb
index 948704e8770..9fe71533b5e 100644
--- a/spec/requests/api/graphql/ci/pipelines_spec.rb
+++ b/spec/requests/api/graphql/ci/pipelines_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Query.project(fullPath).pipelines' do
+RSpec.describe 'Query.project(fullPath).pipelines', feature_category: :continuous_integration do
include GraphqlHelpers
let_it_be(:project) { create(:project, :repository, :public) }
diff --git a/spec/requests/api/graphql/ci/project_variables_spec.rb b/spec/requests/api/graphql/ci/project_variables_spec.rb
index d49a4a7e768..0338b58a0ea 100644
--- a/spec/requests/api/graphql/ci/project_variables_spec.rb
+++ b/spec/requests/api/graphql/ci/project_variables_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Query.project(fullPath).ciVariables' do
+RSpec.describe 'Query.project(fullPath).ciVariables', feature_category: :pipeline_authoring do
include GraphqlHelpers
let_it_be(:project) { create(:project) }
diff --git a/spec/requests/api/graphql/ci/runner_spec.rb b/spec/requests/api/graphql/ci/runner_spec.rb
index 94c0a3c41bd..ca08e780758 100644
--- a/spec/requests/api/graphql/ci/runner_spec.rb
+++ b/spec/requests/api/graphql/ci/runner_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Query.runner(id)' do
+RSpec.describe 'Query.runner(id)', feature_category: :runner_fleet do
include GraphqlHelpers
let_it_be(:user) { create(:user, :admin) }
@@ -74,34 +74,39 @@ RSpec.describe 'Query.runner(id)' do
runner_data = graphql_data_at(:runner)
expect(runner_data).not_to be_nil
- expect(runner_data).to match a_hash_including(
- 'id' => runner.to_global_id.to_s,
- 'description' => runner.description,
- 'createdAt' => runner.created_at&.iso8601,
- 'contactedAt' => runner.contacted_at&.iso8601,
- 'version' => runner.version,
- 'shortSha' => runner.short_sha,
- 'revision' => runner.revision,
- 'locked' => false,
- 'active' => runner.active,
- 'paused' => !runner.active,
- 'status' => runner.status('14.5').to_s.upcase,
- 'maximumTimeout' => runner.maximum_timeout,
- 'accessLevel' => runner.access_level.to_s.upcase,
- 'runUntagged' => runner.run_untagged,
- 'ipAddress' => runner.ip_address,
- 'runnerType' => runner.instance_type? ? 'INSTANCE_TYPE' : 'PROJECT_TYPE',
- 'executorName' => runner.executor_type&.dasherize,
- 'architectureName' => runner.architecture,
- 'platformName' => runner.platform,
- 'maintenanceNote' => runner.maintenance_note,
- 'maintenanceNoteHtml' =>
+ expect(runner_data).to match a_graphql_entity_for(
+ runner,
+ description: runner.description,
+ created_at: runner.created_at&.iso8601,
+ contacted_at: runner.contacted_at&.iso8601,
+ version: runner.version,
+ short_sha: runner.short_sha,
+ revision: runner.revision,
+ locked: false,
+ active: runner.active,
+ paused: !runner.active,
+ status: runner.status('14.5').to_s.upcase,
+ job_execution_status: runner.builds.running.any? ? 'RUNNING' : 'IDLE',
+ maximum_timeout: runner.maximum_timeout,
+ access_level: runner.access_level.to_s.upcase,
+ run_untagged: runner.run_untagged,
+ ip_address: runner.ip_address,
+ runner_type: runner.instance_type? ? 'INSTANCE_TYPE' : 'PROJECT_TYPE',
+ executor_name: runner.executor_type&.dasherize,
+ architecture_name: runner.architecture,
+ platform_name: runner.platform,
+ maintenance_note: runner.maintenance_note,
+ maintenance_note_html:
runner.maintainer_note.present? ? a_string_including('<strong>Test maintenance note</strong>') : '',
- 'jobCount' => 0,
- 'jobs' => a_hash_including("count" => 0, "nodes" => [], "pageInfo" => anything),
- 'projectCount' => nil,
- 'adminUrl' => "http://localhost/admin/runners/#{runner.id}",
- 'userPermissions' => {
+ job_count: runner.builds.count,
+ jobs: a_hash_including(
+ "count" => runner.builds.count,
+ "nodes" => an_instance_of(Array),
+ "pageInfo" => anything
+ ),
+ project_count: nil,
+ admin_url: "http://localhost/admin/runners/#{runner.id}",
+ user_permissions: {
'readRunner' => true,
'updateRunner' => true,
'deleteRunner' => true,
@@ -129,10 +134,7 @@ RSpec.describe 'Query.runner(id)' do
runner_data = graphql_data_at(:runner)
expect(runner_data).not_to be_nil
- expect(runner_data).to match a_hash_including(
- 'id' => runner.to_global_id.to_s,
- 'adminUrl' => nil
- )
+ expect(runner_data).to match a_graphql_entity_for(runner, admin_url: nil)
expect(runner_data['tagList']).to match_array runner.tag_list
end
end
@@ -179,6 +181,16 @@ RSpec.describe 'Query.runner(id)' do
expect(runner_data).not_to include('tagList')
end
end
+
+ context 'with build running' do
+ before do
+ project = create(:project, :repository)
+ pipeline = create(:ci_pipeline, project: project)
+ create(:ci_build, :running, runner: runner, pipeline: pipeline)
+ end
+
+ it_behaves_like 'runner details fetch'
+ end
end
describe 'for project runner' do
@@ -216,9 +228,47 @@ RSpec.describe 'Query.runner(id)' do
runner_data = graphql_data_at(:runner)
- expect(runner_data).to match a_hash_including(
- 'id' => project_runner.to_global_id.to_s,
- 'locked' => is_locked
+ expect(runner_data).to match a_graphql_entity_for(project_runner, locked: is_locked)
+ end
+ end
+ end
+
+ describe 'jobCount' do
+ let_it_be(:pipeline1) { create(:ci_pipeline, project: project1) }
+ let_it_be(:pipeline2) { create(:ci_pipeline, project: project1) }
+ let_it_be(:build1) { create(:ci_build, :running, runner: active_project_runner, pipeline: pipeline1) }
+ let_it_be(:build2) { create(:ci_build, :running, runner: active_project_runner, pipeline: pipeline2) }
+
+ let(:runner_query_fragment) { 'id jobCount' }
+ let(:query) do
+ %(
+ query {
+ runner1: runner(id: "#{active_project_runner.to_global_id}") { #{runner_query_fragment} }
+ runner2: runner(id: "#{inactive_instance_runner.to_global_id}") { #{runner_query_fragment} }
+ }
+ )
+ end
+
+ it 'retrieves correct jobCount values' do
+ post_graphql(query, current_user: user)
+
+ expect(graphql_data).to match a_hash_including(
+ 'runner1' => a_graphql_entity_for(active_project_runner, job_count: 2),
+ 'runner2' => a_graphql_entity_for(inactive_instance_runner, job_count: 0)
+ )
+ end
+
+ context 'when JOB_COUNT_LIMIT is in effect' do
+ before do
+ stub_const('Types::Ci::RunnerType::JOB_COUNT_LIMIT', 0)
+ end
+
+ it 'retrieves correct capped jobCount values' do
+ post_graphql(query, current_user: user)
+
+ expect(graphql_data).to match a_hash_including(
+ 'runner1' => a_graphql_entity_for(active_project_runner, job_count: 1),
+ 'runner2' => a_graphql_entity_for(inactive_instance_runner, job_count: 0)
)
end
end
@@ -243,18 +293,8 @@ RSpec.describe 'Query.runner(id)' do
post_graphql(query, current_user: user)
expect(graphql_data).to match a_hash_including(
- 'runner1' => {
- 'id' => runner1.to_global_id.to_s,
- 'ownerProject' => {
- 'id' => project2.to_global_id.to_s
- }
- },
- 'runner2' => {
- 'id' => runner2.to_global_id.to_s,
- 'ownerProject' => {
- 'id' => project1.to_global_id.to_s
- }
- }
+ 'runner1' => a_graphql_entity_for(runner1, owner_project: a_graphql_entity_for(project2)),
+ 'runner2' => a_graphql_entity_for(runner2, owner_project: a_graphql_entity_for(project1))
)
end
end
@@ -284,8 +324,8 @@ RSpec.describe 'Query.runner(id)' do
it 'retrieves groups field with expected value' do
post_graphql(query, current_user: user)
- runner_data = graphql_data_at(:runner, :groups)
- expect(runner_data).to eq 'nodes' => [{ 'id' => group.to_global_id.to_s }]
+ runner_data = graphql_data_at(:runner, :groups, :nodes)
+ expect(runner_data).to contain_exactly(a_graphql_entity_for(group))
end
end
@@ -409,13 +449,13 @@ RSpec.describe 'Query.runner(id)' do
'jobCount' => 1,
'jobs' => a_hash_including(
"count" => 1,
- "nodes" => [{ "id" => job.to_global_id.to_s, "status" => job.status.upcase }]
+ "nodes" => [a_graphql_entity_for(job, status: job.status.upcase)]
),
'projectCount' => 2,
'projects' => {
'nodes' => [
- { 'id' => project1.to_global_id.to_s },
- { 'id' => project2.to_global_id.to_s }
+ a_graphql_entity_for(project1),
+ a_graphql_entity_for(project2)
]
})
expect(runner2_data).to match a_hash_including(
@@ -486,15 +526,24 @@ RSpec.describe 'Query.runner(id)' do
groups {
nodes {
id
+ path
+ fullPath
+ webUrl
}
}
projects {
nodes {
id
+ path
+ fullPath
+ webUrl
}
}
ownerProject {
id
+ path
+ fullPath
+ webUrl
}
}
SINGLE
@@ -503,8 +552,8 @@ RSpec.describe 'Query.runner(id)' do
let(:active_project_runner2) { create(:ci_runner, :project) }
let(:active_group_runner2) { create(:ci_runner, :group) }
- # Currently excluding known N+1 issues, see https://gitlab.com/gitlab-org/gitlab/-/issues/334759
- let(:excluded_fields) { %w[jobCount groups projects ownerProject] }
+ # Exclude fields that are already hardcoded above
+ let(:excluded_fields) { %w[jobs groups projects ownerProject] }
let(:single_query) do
<<~QUERY
@@ -542,27 +591,98 @@ RSpec.describe 'Query.runner(id)' do
expect(graphql_data.count).to eq 6
expect(graphql_data).to match(
a_hash_including(
- 'instance_runner1' => a_hash_including('id' => active_instance_runner.to_global_id.to_s),
- 'instance_runner2' => a_hash_including('id' => inactive_instance_runner.to_global_id.to_s),
- 'group_runner1' => a_hash_including(
- 'id' => active_group_runner.to_global_id.to_s,
- 'groups' => { 'nodes' => [a_hash_including('id' => group.to_global_id.to_s)] }
+ 'instance_runner1' => a_graphql_entity_for(active_instance_runner),
+ 'instance_runner2' => a_graphql_entity_for(inactive_instance_runner),
+ 'group_runner1' => a_graphql_entity_for(
+ active_group_runner,
+ groups: { 'nodes' => contain_exactly(a_graphql_entity_for(group)) }
),
- 'group_runner2' => a_hash_including(
- 'id' => active_group_runner2.to_global_id.to_s,
- 'groups' => { 'nodes' => [a_hash_including('id' => active_group_runner2.groups[0].to_global_id.to_s)] }
+ 'group_runner2' => a_graphql_entity_for(
+ active_group_runner2,
+ groups: { 'nodes' => active_group_runner2.groups.map { |g| a_graphql_entity_for(g) } }
),
- 'project_runner1' => a_hash_including(
- 'id' => active_project_runner.to_global_id.to_s,
- 'projects' => { 'nodes' => [a_hash_including('id' => active_project_runner.projects[0].to_global_id.to_s)] },
- 'ownerProject' => a_hash_including('id' => active_project_runner.projects[0].to_global_id.to_s)
+ 'project_runner1' => a_graphql_entity_for(
+ active_project_runner,
+ projects: { 'nodes' => active_project_runner.projects.map { |p| a_graphql_entity_for(p) } },
+ owner_project: a_graphql_entity_for(active_project_runner.projects[0])
),
- 'project_runner2' => a_hash_including(
- 'id' => active_project_runner2.to_global_id.to_s,
- 'projects' => {
- 'nodes' => [a_hash_including('id' => active_project_runner2.projects[0].to_global_id.to_s)]
- },
- 'ownerProject' => a_hash_including('id' => active_project_runner2.projects[0].to_global_id.to_s)
+ 'project_runner2' => a_graphql_entity_for(
+ active_project_runner2,
+ projects: { 'nodes' => active_project_runner2.projects.map { |p| a_graphql_entity_for(p) } },
+ owner_project: a_graphql_entity_for(active_project_runner2.projects[0])
+ )
+ ))
+ end
+ end
+
+ describe 'Query limits with jobs' do
+ let!(:group1) { create(:group) }
+ let!(:group2) { create(:group) }
+ let!(:project1) { create(:project, :repository, group: group1) }
+ let!(:project2) { create(:project, :repository, group: group1) }
+ let!(:project3) { create(:project, :repository, group: group2) }
+
+ let!(:merge_request1) { create(:merge_request, source_project: project1) }
+ let!(:merge_request2) { create(:merge_request, source_project: project3) }
+
+ let(:project_runner2) { create(:ci_runner, :project, projects: [project1, project2]) }
+ let!(:build1) { create(:ci_build, :success, name: 'Build One', runner: project_runner2, pipeline: pipeline1) }
+ let!(:pipeline1) do
+ create(:ci_pipeline, project: project1, source: :merge_request_event, merge_request: merge_request1, ref: 'main',
+ target_sha: 'xxx')
+ end
+
+ let(:query) do
+ <<~QUERY
+ {
+ runner(id: "#{project_runner2.to_global_id}") {
+ id
+ jobs {
+ nodes {
+ id
+ detailedStatus {
+ id
+ detailsPath
+ group
+ icon
+ text
+ }
+ shortSha
+ commitPath
+ finishedAt
+ duration
+ queuedDuration
+ tags
+ }
+ }
+ }
+ }
+ QUERY
+ end
+
+ it 'does not execute more queries per job', :aggregate_failures do
+ # warm-up license cache and so on:
+ personal_access_token = create(:personal_access_token, user: user)
+ args = { current_user: user, token: { personal_access_token: personal_access_token } }
+ post_graphql(query, **args)
+
+ control = ActiveRecord::QueryRecorder.new(query_recorder_debug: true) { post_graphql(query, **args) }
+
+ # Add a new build to project_runner2
+ project_runner2.runner_projects << build(:ci_runner_project, runner: project_runner2, project: project3)
+ pipeline2 = create(:ci_pipeline, project: project3, source: :merge_request_event, merge_request: merge_request2,
+ ref: 'main', target_sha: 'xxx')
+ build2 = create(:ci_build, :success, name: 'Build Two', runner: project_runner2, pipeline: pipeline2)
+
+ args[:current_user] = create(:user, :admin) # do not reuse same user
+ expect { post_graphql(query, **args) }.not_to exceed_all_query_limit(control)
+
+ expect(graphql_data.count).to eq 1
+ expect(graphql_data).to match(
+ a_hash_including(
+ 'runner' => a_graphql_entity_for(
+ project_runner2,
+ jobs: { 'nodes' => containing_exactly(a_graphql_entity_for(build1), a_graphql_entity_for(build2)) }
)
))
end
diff --git a/spec/requests/api/graphql/ci/runner_web_url_edge_spec.rb b/spec/requests/api/graphql/ci/runner_web_url_edge_spec.rb
index 767e958ea82..e84a1ca4cc4 100644
--- a/spec/requests/api/graphql/ci/runner_web_url_edge_spec.rb
+++ b/spec/requests/api/graphql/ci/runner_web_url_edge_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
require 'spec_helper'
-RSpec.describe 'RunnerWebUrlEdge' do
+RSpec.describe 'RunnerWebUrlEdge', feature_category: :runner_fleet do
include GraphqlHelpers
describe 'inside a Query.group' do
diff --git a/spec/requests/api/graphql/ci/runners_spec.rb b/spec/requests/api/graphql/ci/runners_spec.rb
index 3054b866812..75d8609dc38 100644
--- a/spec/requests/api/graphql/ci/runners_spec.rb
+++ b/spec/requests/api/graphql/ci/runners_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
require 'spec_helper'
-RSpec.describe 'Query.runners' do
+RSpec.describe 'Query.runners', feature_category: :runner_fleet do
include GraphqlHelpers
let_it_be(:current_user) { create_default(:user, :admin) }
@@ -48,7 +48,7 @@ RSpec.describe 'Query.runners' do
it_behaves_like 'a working graphql query'
it 'returns expected runner' do
- expect(runners_graphql_data['nodes'].map { |n| n['id'] }).to contain_exactly(expected_runner.to_global_id.to_s)
+ expect(runners_graphql_data['nodes']).to contain_exactly(a_graphql_entity_for(expected_runner))
end
end
diff --git a/spec/requests/api/graphql/ci/stages_spec.rb b/spec/requests/api/graphql/ci/stages_spec.rb
index 1edd6e58486..f4e1a69d455 100644
--- a/spec/requests/api/graphql/ci/stages_spec.rb
+++ b/spec/requests/api/graphql/ci/stages_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
require 'spec_helper'
-RSpec.describe 'Query.project.pipeline.stages' do
+RSpec.describe 'Query.project.pipeline.stages', feature_category: :continuous_integration do
include GraphqlHelpers
subject(:post_query) { post_graphql(query, current_user: user) }
diff --git a/spec/requests/api/graphql/ci/template_spec.rb b/spec/requests/api/graphql/ci/template_spec.rb
index 1bbef7d7f30..aaec219f734 100644
--- a/spec/requests/api/graphql/ci/template_spec.rb
+++ b/spec/requests/api/graphql/ci/template_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
require 'spec_helper'
-RSpec.describe 'Querying CI template' do
+RSpec.describe 'Querying CI template', feature_category: :continuous_integration do
include GraphqlHelpers
let_it_be(:project) { create(:project, :public) }
diff --git a/spec/requests/api/graphql/container_repository/container_repository_details_spec.rb b/spec/requests/api/graphql/container_repository/container_repository_details_spec.rb
index 14c55e61a65..88f63fd59d7 100644
--- a/spec/requests/api/graphql/container_repository/container_repository_details_spec.rb
+++ b/spec/requests/api/graphql/container_repository/container_repository_details_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
require 'spec_helper'
-RSpec.describe 'container repository details' do
+RSpec.describe 'container repository details', feature_category: :container_registry do
include_context 'container registry tags'
include_context 'container registry client stubs'
diff --git a/spec/requests/api/graphql/crm/contacts_spec.rb b/spec/requests/api/graphql/crm/contacts_spec.rb
index a676e92dc3b..3ae19de63ed 100644
--- a/spec/requests/api/graphql/crm/contacts_spec.rb
+++ b/spec/requests/api/graphql/crm/contacts_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'getting CRM contacts' do
+RSpec.describe 'getting CRM contacts', feature_category: :service_desk do
include GraphqlHelpers
let_it_be(:current_user) { create(:user) }
diff --git a/spec/requests/api/graphql/current_user/groups_query_spec.rb b/spec/requests/api/graphql/current_user/groups_query_spec.rb
index 6e36beb2afc..151d07ff0a7 100644
--- a/spec/requests/api/graphql/current_user/groups_query_spec.rb
+++ b/spec/requests/api/graphql/current_user/groups_query_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Query current user groups' do
+RSpec.describe 'Query current user groups', feature_category: :subgroups do
include GraphqlHelpers
let_it_be(:user) { create(:user) }
diff --git a/spec/requests/api/graphql/current_user/todos_query_spec.rb b/spec/requests/api/graphql/current_user/todos_query_spec.rb
index 5a45f0db518..f7e23aeb241 100644
--- a/spec/requests/api/graphql/current_user/todos_query_spec.rb
+++ b/spec/requests/api/graphql/current_user/todos_query_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Query current user todos' do
+RSpec.describe 'Query current user todos', feature_category: :source_code_management do
include GraphqlHelpers
include DesignManagementTestHelpers
@@ -19,7 +19,7 @@ RSpec.describe 'Query current user todos' do
let(:fields) do
<<~QUERY
nodes {
- #{all_graphql_fields_for('todos'.classify)}
+ #{all_graphql_fields_for('todos'.classify, max_depth: 2)}
}
QUERY
end
diff --git a/spec/requests/api/graphql/current_user_query_spec.rb b/spec/requests/api/graphql/current_user_query_spec.rb
index 086a57094ca..53d2580caee 100644
--- a/spec/requests/api/graphql/current_user_query_spec.rb
+++ b/spec/requests/api/graphql/current_user_query_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'getting project information' do
+RSpec.describe 'getting project information', feature_category: :authentication_and_authorization do
include GraphqlHelpers
let(:fields) do
diff --git a/spec/requests/api/graphql/current_user_todos_spec.rb b/spec/requests/api/graphql/current_user_todos_spec.rb
index da1c893ec2b..eaed51982e1 100644
--- a/spec/requests/api/graphql/current_user_todos_spec.rb
+++ b/spec/requests/api/graphql/current_user_todos_spec.rb
@@ -2,7 +2,8 @@
require 'spec_helper'
-RSpec.describe 'A Todoable that implements the CurrentUserTodos interface' do
+RSpec.describe 'A Todoable that implements the CurrentUserTodos interface',
+feature_category: :team_planning do
include GraphqlHelpers
let_it_be(:current_user) { create(:user) }
diff --git a/spec/requests/api/graphql/custom_emoji_query_spec.rb b/spec/requests/api/graphql/custom_emoji_query_spec.rb
index 5dd5ad117b0..7b804623e01 100644
--- a/spec/requests/api/graphql/custom_emoji_query_spec.rb
+++ b/spec/requests/api/graphql/custom_emoji_query_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'getting custom emoji within namespace' do
+RSpec.describe 'getting custom emoji within namespace', feature_category: :not_owned do
include GraphqlHelpers
let_it_be(:current_user) { create(:user) }
diff --git a/spec/requests/api/graphql/environments/deployments_query_spec.rb b/spec/requests/api/graphql/environments/deployments_spec.rb
index 6da00057449..0022a38d2d3 100644
--- a/spec/requests/api/graphql/environments/deployments_query_spec.rb
+++ b/spec/requests/api/graphql/environments/deployments_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Environments Deployments query' do
+RSpec.describe 'Environments Deployments query', feature_category: :continuous_delivery do
include GraphqlHelpers
let_it_be(:project) { create(:project, :private, :repository) }
@@ -437,6 +437,43 @@ RSpec.describe 'Environments Deployments query' do
end
end
+ context 'when requesting user permissions' do
+ let(:query) do
+ %(
+ query {
+ project(fullPath: "#{project.full_path}") {
+ environment(name: "#{environment.name}") {
+ deployments {
+ nodes {
+ iid
+ userPermissions {
+ updateDeployment
+ destroyDeployment
+ }
+ }
+ }
+ }
+ }
+ }
+ )
+ end
+
+ it_behaves_like 'avoids N+1 database queries'
+
+ it 'returns user permissions of the deployments', :aggregate_failures do
+ deployments = subject.dig('data', 'project', 'environment', 'deployments', 'nodes')
+
+ deployments.each do |deployment|
+ deployment_in_record = project.deployments.find_by_iid(deployment['iid'])
+
+ expect(deployment['userPermissions']['updateDeployment'])
+ .to eq(Ability.allowed?(user, :update_deployment, deployment_in_record))
+ expect(deployment['userPermissions']['destroyDeployment'])
+ .to eq(Ability.allowed?(user, :destroy_deployment, deployment_in_record))
+ end
+ end
+ end
+
describe 'sorting and pagination' do
let(:data_path) { [:project, :environment, :deployments] }
let(:current_user) { user }
diff --git a/spec/requests/api/graphql/gitlab_schema_spec.rb b/spec/requests/api/graphql/gitlab_schema_spec.rb
index c1beadb6c45..7937091ea7c 100644
--- a/spec/requests/api/graphql/gitlab_schema_spec.rb
+++ b/spec/requests/api/graphql/gitlab_schema_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'GitlabSchema configurations' do
+RSpec.describe 'GitlabSchema configurations', feature_category: :not_owned do
include GraphqlHelpers
let_it_be(:project) { create(:project) }
diff --git a/spec/requests/api/graphql/group/container_repositories_spec.rb b/spec/requests/api/graphql/group/container_repositories_spec.rb
index 8ec321c8d7c..51d12261247 100644
--- a/spec/requests/api/graphql/group/container_repositories_spec.rb
+++ b/spec/requests/api/graphql/group/container_repositories_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
require 'spec_helper'
-RSpec.describe 'getting container repositories in a group' do
+RSpec.describe 'getting container repositories in a group', feature_category: :source_code_management do
using RSpec::Parameterized::TableSyntax
include GraphqlHelpers
diff --git a/spec/requests/api/graphql/group/dependency_proxy_blobs_spec.rb b/spec/requests/api/graphql/group/dependency_proxy_blobs_spec.rb
index daa1483e956..2c4770a31a7 100644
--- a/spec/requests/api/graphql/group/dependency_proxy_blobs_spec.rb
+++ b/spec/requests/api/graphql/group/dependency_proxy_blobs_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
require 'spec_helper'
-RSpec.describe 'getting dependency proxy blobs in a group' do
+RSpec.describe 'getting dependency proxy blobs in a group', feature_category: :dependency_proxy do
using RSpec::Parameterized::TableSyntax
include GraphqlHelpers
diff --git a/spec/requests/api/graphql/group/dependency_proxy_group_setting_spec.rb b/spec/requests/api/graphql/group/dependency_proxy_group_setting_spec.rb
index cc706c3051f..aca8527ba0a 100644
--- a/spec/requests/api/graphql/group/dependency_proxy_group_setting_spec.rb
+++ b/spec/requests/api/graphql/group/dependency_proxy_group_setting_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
require 'spec_helper'
-RSpec.describe 'getting dependency proxy settings for a group' do
+RSpec.describe 'getting dependency proxy settings for a group', feature_category: :dependency_proxy do
using RSpec::Parameterized::TableSyntax
include GraphqlHelpers
diff --git a/spec/requests/api/graphql/group/dependency_proxy_image_ttl_policy_spec.rb b/spec/requests/api/graphql/group/dependency_proxy_image_ttl_policy_spec.rb
index 3b2b04b1322..edff4dc1dae 100644
--- a/spec/requests/api/graphql/group/dependency_proxy_image_ttl_policy_spec.rb
+++ b/spec/requests/api/graphql/group/dependency_proxy_image_ttl_policy_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
require 'spec_helper'
-RSpec.describe 'getting dependency proxy image ttl policy for a group' do
+RSpec.describe 'getting dependency proxy image ttl policy for a group', feature_category: :dependency_proxy do
using RSpec::Parameterized::TableSyntax
include GraphqlHelpers
diff --git a/spec/requests/api/graphql/group/dependency_proxy_manifests_spec.rb b/spec/requests/api/graphql/group/dependency_proxy_manifests_spec.rb
index 37ef7089c2f..d2d686104ad 100644
--- a/spec/requests/api/graphql/group/dependency_proxy_manifests_spec.rb
+++ b/spec/requests/api/graphql/group/dependency_proxy_manifests_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
require 'spec_helper'
-RSpec.describe 'getting dependency proxy manifests in a group' do
+RSpec.describe 'getting dependency proxy manifests in a group', feature_category: :dependency_proxy do
using RSpec::Parameterized::TableSyntax
include GraphqlHelpers
diff --git a/spec/requests/api/graphql/group/group_members_spec.rb b/spec/requests/api/graphql/group/group_members_spec.rb
index 5f8becc0726..26d1fb48408 100644
--- a/spec/requests/api/graphql/group/group_members_spec.rb
+++ b/spec/requests/api/graphql/group/group_members_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'getting group members information' do
+RSpec.describe 'getting group members information', feature_category: :subgroups do
include GraphqlHelpers
let_it_be(:parent_group) { create(:group, :public) }
diff --git a/spec/requests/api/graphql/group/issues_spec.rb b/spec/requests/api/graphql/group/issues_spec.rb
index 26338f46611..95aeed32558 100644
--- a/spec/requests/api/graphql/group/issues_spec.rb
+++ b/spec/requests/api/graphql/group/issues_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'getting an issue list for a group' do
+RSpec.describe 'getting an issue list for a group', feature_category: :team_planning do
include GraphqlHelpers
let_it_be(:current_user) { create(:user) }
diff --git a/spec/requests/api/graphql/group/labels_query_spec.rb b/spec/requests/api/graphql/group/labels_query_spec.rb
index 31556ffca30..28886f8d80b 100644
--- a/spec/requests/api/graphql/group/labels_query_spec.rb
+++ b/spec/requests/api/graphql/group/labels_query_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'getting group label information' do
+RSpec.describe 'getting group label information', feature_category: :team_planning do
include GraphqlHelpers
let_it_be(:group) { create(:group, :public) }
diff --git a/spec/requests/api/graphql/group/merge_requests_spec.rb b/spec/requests/api/graphql/group/merge_requests_spec.rb
index 434b0d16569..6976685ecc0 100644
--- a/spec/requests/api/graphql/group/merge_requests_spec.rb
+++ b/spec/requests/api/graphql/group/merge_requests_spec.rb
@@ -4,7 +4,7 @@ require 'spec_helper'
# Based on ee/spec/requests/api/epics_spec.rb
# Should follow closely in order to ensure all situations are covered
-RSpec.describe 'Query.group.mergeRequests' do
+RSpec.describe 'Query.group.mergeRequests', feature_category: :code_review do
include GraphqlHelpers
let_it_be(:group) { create(:group) }
diff --git a/spec/requests/api/graphql/group/milestones_spec.rb b/spec/requests/api/graphql/group/milestones_spec.rb
index 7c51409f907..28cd68493c0 100644
--- a/spec/requests/api/graphql/group/milestones_spec.rb
+++ b/spec/requests/api/graphql/group/milestones_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Milestones through GroupQuery' do
+RSpec.describe 'Milestones through GroupQuery', feature_category: :team_planning do
include GraphqlHelpers
let_it_be(:user) { create(:user) }
diff --git a/spec/requests/api/graphql/group/packages_spec.rb b/spec/requests/api/graphql/group/packages_spec.rb
index cf8736db5af..0b4057c87f8 100644
--- a/spec/requests/api/graphql/group/packages_spec.rb
+++ b/spec/requests/api/graphql/group/packages_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'getting a package list for a group' do
+RSpec.describe 'getting a package list for a group', feature_category: :package_registry do
include GraphqlHelpers
let_it_be(:resource) { create(:group, :private) }
diff --git a/spec/requests/api/graphql/group/recent_issue_boards_query_spec.rb b/spec/requests/api/graphql/group/recent_issue_boards_query_spec.rb
index 4914beec870..2dfbc95bac9 100644
--- a/spec/requests/api/graphql/group/recent_issue_boards_query_spec.rb
+++ b/spec/requests/api/graphql/group/recent_issue_boards_query_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'getting group recent issue boards' do
+RSpec.describe 'getting group recent issue boards', feature_category: :team_planning do
include GraphqlHelpers
it_behaves_like 'querying a GraphQL type recent boards' do
diff --git a/spec/requests/api/graphql/group/timelogs_spec.rb b/spec/requests/api/graphql/group/timelogs_spec.rb
index 05b6ee3ff89..b67b39edff2 100644
--- a/spec/requests/api/graphql/group/timelogs_spec.rb
+++ b/spec/requests/api/graphql/group/timelogs_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Timelogs through GroupQuery' do
+RSpec.describe 'Timelogs through GroupQuery', feature_category: :team_planning do
include GraphqlHelpers
describe 'Get list of timelogs from a group issues' do
diff --git a/spec/requests/api/graphql/group/work_item_types_spec.rb b/spec/requests/api/graphql/group/work_item_types_spec.rb
index 35090e2a89f..791c0fb9524 100644
--- a/spec/requests/api/graphql/group/work_item_types_spec.rb
+++ b/spec/requests/api/graphql/group/work_item_types_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'getting a list of work item types for a group' do
+RSpec.describe 'getting a list of work item types for a group', feature_category: :team_planning do
include GraphqlHelpers
let_it_be(:developer) { create(:user) }
diff --git a/spec/requests/api/graphql/group_query_spec.rb b/spec/requests/api/graphql/group_query_spec.rb
index 8ee5c3c5d73..bc288c0a98b 100644
--- a/spec/requests/api/graphql/group_query_spec.rb
+++ b/spec/requests/api/graphql/group_query_spec.rb
@@ -4,7 +4,7 @@ require 'spec_helper'
# Based on spec/requests/api/groups_spec.rb
# Should follow closely in order to ensure all situations are covered
-RSpec.describe 'getting group information' do
+RSpec.describe 'getting group information', feature_category: :subgroups do
include GraphqlHelpers
include UploadHelpers
diff --git a/spec/requests/api/graphql/issue/issue_spec.rb b/spec/requests/api/graphql/issue/issue_spec.rb
index 6e2d736f244..101de692aa5 100644
--- a/spec/requests/api/graphql/issue/issue_spec.rb
+++ b/spec/requests/api/graphql/issue/issue_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Query.issue(id)' do
+RSpec.describe 'Query.issue(id)', feature_category: :team_planning do
include GraphqlHelpers
let_it_be(:project) { create(:project) }
diff --git a/spec/requests/api/graphql/issue_status_counts_spec.rb b/spec/requests/api/graphql/issue_status_counts_spec.rb
index 89ecbf44b10..72a1968cb27 100644
--- a/spec/requests/api/graphql/issue_status_counts_spec.rb
+++ b/spec/requests/api/graphql/issue_status_counts_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
require 'spec_helper'
-RSpec.describe 'getting Issue counts by status' do
+RSpec.describe 'getting Issue counts by status', feature_category: :team_planning do
include GraphqlHelpers
let_it_be(:project) { create(:project, :repository) }
diff --git a/spec/requests/api/graphql/issues_spec.rb b/spec/requests/api/graphql/issues_spec.rb
index 8838ad78f72..ba6f8ec2cab 100644
--- a/spec/requests/api/graphql/issues_spec.rb
+++ b/spec/requests/api/graphql/issues_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'getting an issue list at root level' do
+RSpec.describe 'getting an issue list at root level', feature_category: :team_planning do
include GraphqlHelpers
let_it_be(:developer) { create(:user) }
@@ -13,34 +13,81 @@ RSpec.describe 'getting an issue list at root level' do
let_it_be(:project_b) { create(:project, :repository, :private, group: group1) }
let_it_be(:project_c) { create(:project, :repository, :public, group: group2) }
let_it_be(:project_d) { create(:project, :repository, :private, group: group2) }
- let_it_be(:early_milestone) { create(:milestone, project: project_d, due_date: 10.days.from_now) }
- let_it_be(:late_milestone) { create(:milestone, project: project_c, due_date: 30.days.from_now) }
+ let_it_be(:milestone1) { create(:milestone, project: project_c, due_date: 10.days.from_now) }
+ let_it_be(:milestone2) { create(:milestone, project: project_d, due_date: 20.days.from_now) }
+ let_it_be(:milestone3) { create(:milestone, project: project_d, due_date: 30.days.from_now) }
+ let_it_be(:milestone4) { create(:milestone, project: project_a, due_date: 40.days.from_now) }
let_it_be(:priority1) { create(:label, project: project_c, priority: 1) }
let_it_be(:priority2) { create(:label, project: project_d, priority: 5) }
let_it_be(:priority3) { create(:label, project: project_a, priority: 10) }
+ let_it_be(:priority4) { create(:label, project: project_d, priority: 15) }
+
+ let_it_be(:issue_a) do
+ create(
+ :issue,
+ project: project_a,
+ labels: [priority3],
+ due_date: 1.day.ago,
+ milestone: milestone4,
+ relative_position: 1000
+ )
+ end
+
+ let_it_be(:issue_b) do
+ create(
+ :issue,
+ :with_alert,
+ project: project_b,
+ discussion_locked: true,
+ due_date: 1.day.from_now,
+ relative_position: 3000
+ )
+ end
- let_it_be(:issue_a) { create(:issue, project: project_a, labels: [priority3]) }
- let_it_be(:issue_b) { create(:issue, :with_alert, project: project_b, discussion_locked: true) }
let_it_be(:issue_c) do
create(
:issue,
+ :confidential,
project: project_c,
title: 'title matching issue plus',
labels: [priority1],
- milestone: late_milestone
+ milestone: milestone1,
+ due_date: 3.days.from_now,
+ relative_position: nil
)
end
- let_it_be(:issue_d) { create(:issue, :with_alert, project: project_d, discussion_locked: true, labels: [priority2]) }
- let_it_be(:issue_e) { create(:issue, project: project_d, milestone: early_milestone) }
+ let_it_be(:issue_d) do
+ create(
+ :issue,
+ :with_alert,
+ project: project_d,
+ discussion_locked: true,
+ labels: [priority2],
+ milestone: milestone3,
+ relative_position: 5000
+ )
+ end
- let(:issue_filter_params) { {} }
+ let_it_be(:issue_e) do
+ create(
+ :issue,
+ :confidential,
+ project: project_d,
+ milestone: milestone2,
+ due_date: 3.days.ago,
+ relative_position: nil,
+ labels: [priority2, priority4]
+ )
+ end
+ let_it_be(:issues, reload: true) { [issue_a, issue_b, issue_c, issue_d, issue_e] }
+
+ let(:issue_filter_params) { {} }
+ let(:current_user) { developer }
let(:fields) do
<<~QUERY
- nodes {
- #{all_graphql_fields_for('issues'.classify)}
- }
+ nodes { id }
QUERY
end
@@ -60,13 +107,16 @@ RSpec.describe 'getting an issue list at root level' do
end
end
+ # All new specs should be added to the shared example if the change also
+ # affects the `issues` query at the root level of the API.
+ # Shared example also used in spec/requests/api/graphql/project/issues_spec.rb
it_behaves_like 'graphql issue list request spec' do
- subject(:post_query) { post_graphql(query, current_user: current_user) }
+ let_it_be(:external_user) { create(:user) }
+
+ let(:public_projects) { [project_a, project_c] }
- let(:current_user) { developer }
let(:another_user) { reporter }
- let(:issues_data) { graphql_data['issues']['nodes'] }
- let(:issue_ids) { graphql_dig_at(issues_data, :id) }
+ let(:issue_nodes_path) { %w[issues nodes] }
# filters
let(:expected_negated_assignee_issues) { [issue_b, issue_c, issue_d, issue_e] }
@@ -77,12 +127,25 @@ RSpec.describe 'getting an issue list at root level' do
let(:unlocked_discussion_issues) { [issue_a, issue_c, issue_e] }
let(:search_title_term) { 'matching issue' }
let(:title_search_issue) { issue_c }
+ let(:confidential_issues) { [issue_c, issue_e] }
+ let(:non_confidential_issues) { [issue_a, issue_b, issue_d] }
+ let(:public_non_confidential_issues) { [issue_a] }
# sorting
let(:data_path) { [:issues] }
- let(:expected_severity_sorted_asc) { [issue_c, issue_a, issue_b, issue_e, issue_d] }
- let(:expected_priority_sorted_asc) { [issue_e, issue_c, issue_d, issue_a, issue_b] }
- let(:expected_priority_sorted_desc) { [issue_c, issue_e, issue_a, issue_d, issue_b] }
+ let(:expected_priority_sorted_asc) { [issue_c, issue_e, issue_d, issue_a, issue_b] }
+ let(:expected_priority_sorted_desc) { [issue_a, issue_d, issue_e, issue_c, issue_b] }
+ let(:expected_due_date_sorted_desc) { [issue_c, issue_b, issue_a, issue_e, issue_d] }
+ let(:expected_due_date_sorted_asc) { [issue_e, issue_a, issue_b, issue_c, issue_d] }
+ let(:expected_relative_position_sorted_asc) { [issue_a, issue_b, issue_d, issue_c, issue_e] }
+ let(:expected_label_priority_sorted_asc) { [issue_c, issue_e, issue_d, issue_a, issue_b] }
+ let(:expected_label_priority_sorted_desc) { [issue_a, issue_e, issue_d, issue_c, issue_b] }
+ let(:expected_milestone_sorted_asc) { [issue_c, issue_e, issue_d, issue_a, issue_b] }
+ let(:expected_milestone_sorted_desc) { [issue_a, issue_d, issue_e, issue_c, issue_b] }
+
+ # N+1 queries
+ let(:same_project_issue1) { issue_d }
+ let(:same_project_issue2) { issue_e }
before_all do
issue_a.assignee_ids = developer.id
@@ -90,12 +153,6 @@ RSpec.describe 'getting an issue list at root level' do
create(:award_emoji, :upvote, user: developer, awardable: issue_a)
create(:award_emoji, :upvote, user: developer, awardable: issue_c)
-
- # severity sorting
- create(:issuable_severity, issue: issue_a, severity: :unknown)
- create(:issuable_severity, issue: issue_b, severity: :low)
- create(:issuable_severity, issue: issue_d, severity: :critical)
- create(:issuable_severity, issue: issue_e, severity: :high)
end
def pagination_query(params)
@@ -107,6 +164,27 @@ RSpec.describe 'getting an issue list at root level' do
end
end
+ context 'when fetching issues from multiple projects' do
+ it 'avoids N+1 queries' do
+ post_query # warm-up
+
+ control = ActiveRecord::QueryRecorder.new { post_query }
+
+ new_private_project = create(:project, :private).tap { |project| project.add_developer(current_user) }
+ create(:issue, project: new_private_project)
+
+ expect { post_query }.not_to exceed_query_limit(control)
+ end
+ end
+
+ def execute_query
+ post_query
+ end
+
+ def post_query(request_user = current_user)
+ post_graphql(query, current_user: request_user)
+ end
+
def query(params = issue_filter_params)
graphql_query_for(
:issues,
diff --git a/spec/requests/api/graphql/jobs_query_spec.rb b/spec/requests/api/graphql/jobs_query_spec.rb
index 5907566be7f..0aea8e4c253 100644
--- a/spec/requests/api/graphql/jobs_query_spec.rb
+++ b/spec/requests/api/graphql/jobs_query_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'getting job information' do
+RSpec.describe 'getting job information', feature_category: :continuous_integration do
include GraphqlHelpers
let_it_be(:job) { create(:ci_build, :success, name: 'job1') }
diff --git a/spec/requests/api/graphql/merge_request/merge_request_spec.rb b/spec/requests/api/graphql/merge_request/merge_request_spec.rb
index d89f381753e..213697bacc1 100644
--- a/spec/requests/api/graphql/merge_request/merge_request_spec.rb
+++ b/spec/requests/api/graphql/merge_request/merge_request_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Query.merge_request(id)' do
+RSpec.describe 'Query.merge_request(id)', feature_category: :code_review do
include GraphqlHelpers
let_it_be(:project) { create(:project, :empty_repo) }
diff --git a/spec/requests/api/graphql/metadata_query_spec.rb b/spec/requests/api/graphql/metadata_query_spec.rb
index 435e1b5b596..7d1850b1b93 100644
--- a/spec/requests/api/graphql/metadata_query_spec.rb
+++ b/spec/requests/api/graphql/metadata_query_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'getting project information' do
+RSpec.describe 'getting project information', feature_category: :projects do
include GraphqlHelpers
let(:query) { graphql_query_for('metadata', {}, all_graphql_fields_for('Metadata')) }
diff --git a/spec/requests/api/graphql/metrics/dashboard/annotations_spec.rb b/spec/requests/api/graphql/metrics/dashboard/annotations_spec.rb
index 72ec2b8e070..4dd47142c40 100644
--- a/spec/requests/api/graphql/metrics/dashboard/annotations_spec.rb
+++ b/spec/requests/api/graphql/metrics/dashboard/annotations_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Getting Metrics Dashboard Annotations' do
+RSpec.describe 'Getting Metrics Dashboard Annotations', feature_category: :metrics do
include GraphqlHelpers
let_it_be(:project) { create(:project) }
diff --git a/spec/requests/api/graphql/metrics/dashboard_query_spec.rb b/spec/requests/api/graphql/metrics/dashboard_query_spec.rb
index 1b84acff0e2..8db0844c6d7 100644
--- a/spec/requests/api/graphql/metrics/dashboard_query_spec.rb
+++ b/spec/requests/api/graphql/metrics/dashboard_query_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Getting Metrics Dashboard' do
+RSpec.describe 'Getting Metrics Dashboard', feature_category: :metrics do
include GraphqlHelpers
let_it_be(:current_user) { create(:user) }
@@ -26,156 +26,73 @@ RSpec.describe 'Getting Metrics Dashboard' do
)
end
- context 'with metrics_dashboard_exhaustive_validations feature flag off' do
+ context 'for anonymous user' do
before do
- stub_feature_flags(metrics_dashboard_exhaustive_validations: false)
+ post_graphql(query, current_user: current_user)
end
- context 'for anonymous user' do
- before do
- post_graphql(query, current_user: current_user)
- end
-
- context 'requested dashboard is available' do
- let(:path) { 'config/prometheus/common_metrics.yml' }
-
- it_behaves_like 'a working graphql query'
-
- it 'returns nil' do
- dashboard = graphql_data.dig('project', 'environments', 'nodes')
-
- expect(dashboard).to be_nil
- end
- end
- end
-
- context 'for user with developer access' do
- before do
- project.add_developer(current_user)
- post_graphql(query, current_user: current_user)
- end
-
- context 'requested dashboard is available' do
- let(:path) { 'config/prometheus/common_metrics.yml' }
-
- it_behaves_like 'a working graphql query'
-
- it 'returns metrics dashboard' do
- dashboard = graphql_data.dig('project', 'environments', 'nodes', 0, 'metricsDashboard')
-
- expect(dashboard).to eql("path" => path, "schemaValidationWarnings" => nil)
- end
-
- context 'invalid dashboard' do
- let(:path) { '.gitlab/dashboards/metrics.yml' }
- let(:project) { create(:project, :repository, :custom_repo, namespace: current_user.namespace, files: { path => "---\ndashboard: 'test'" }) }
-
- it 'returns metrics dashboard' do
- dashboard = graphql_data.dig('project', 'environments', 'nodes', 0, 'metricsDashboard')
-
- expect(dashboard).to eql("path" => path, "schemaValidationWarnings" => ["panel_groups: should be an array of panel_groups objects"])
- end
- end
-
- context 'empty dashboard' do
- let(:path) { '.gitlab/dashboards/metrics.yml' }
- let(:project) { create(:project, :repository, :custom_repo, namespace: current_user.namespace, files: { path => "" }) }
-
- it 'returns metrics dashboard' do
- dashboard = graphql_data.dig('project', 'environments', 'nodes', 0, 'metricsDashboard')
+ context 'requested dashboard is available' do
+ let(:path) { 'config/prometheus/common_metrics.yml' }
- expect(dashboard).to eql("path" => path, "schemaValidationWarnings" => ["dashboard: can't be blank", "panel_groups: should be an array of panel_groups objects"])
- end
- end
- end
-
- context 'requested dashboard can not be found' do
- let(:path) { 'config/prometheus/i_am_not_here.yml' }
+ it_behaves_like 'a working graphql query'
- it_behaves_like 'a working graphql query'
+ it 'returns nil' do
+ dashboard = graphql_data.dig('project', 'environments', 'nodes')
- it 'returns nil' do
- dashboard = graphql_data.dig('project', 'environments', 'nodes', 0, 'metricsDashboard')
-
- expect(dashboard).to be_nil
- end
+ expect(dashboard).to be_nil
end
end
end
- context 'with metrics_dashboard_exhaustive_validations feature flag on' do
+ context 'for user with developer access' do
before do
- stub_feature_flags(metrics_dashboard_exhaustive_validations: true)
+ project.add_developer(current_user)
+ post_graphql(query, current_user: current_user)
end
- context 'for anonymous user' do
- before do
- post_graphql(query, current_user: current_user)
- end
-
- context 'requested dashboard is available' do
- let(:path) { 'config/prometheus/common_metrics.yml' }
-
- it_behaves_like 'a working graphql query'
+ context 'requested dashboard is available' do
+ let(:path) { 'config/prometheus/common_metrics.yml' }
- it 'returns nil' do
- dashboard = graphql_data.dig('project', 'environments', 'nodes')
+ it_behaves_like 'a working graphql query'
- expect(dashboard).to be_nil
- end
- end
- end
+ it 'returns metrics dashboard' do
+ dashboard = graphql_data.dig('project', 'environments', 'nodes', 0, 'metricsDashboard')
- context 'for user with developer access' do
- before do
- project.add_developer(current_user)
- post_graphql(query, current_user: current_user)
+ expect(dashboard).to eql("path" => path, "schemaValidationWarnings" => nil)
end
- context 'requested dashboard is available' do
- let(:path) { 'config/prometheus/common_metrics.yml' }
-
- it_behaves_like 'a working graphql query'
+ context 'invalid dashboard' do
+ let(:path) { '.gitlab/dashboards/metrics.yml' }
+ let(:project) { create(:project, :repository, :custom_repo, namespace: current_user.namespace, files: { path => "---\ndashboard: 'test'" }) }
it 'returns metrics dashboard' do
dashboard = graphql_data.dig('project', 'environments', 'nodes', 0, 'metricsDashboard')
- expect(dashboard).to eql("path" => path, "schemaValidationWarnings" => nil)
- end
-
- context 'invalid dashboard' do
- let(:path) { '.gitlab/dashboards/metrics.yml' }
- let(:project) { create(:project, :repository, :custom_repo, namespace: current_user.namespace, files: { path => "---\ndashboard: 'test'" }) }
-
- it 'returns metrics dashboard' do
- dashboard = graphql_data.dig('project', 'environments', 'nodes', 0, 'metricsDashboard')
-
- expect(dashboard).to eql("path" => path, "schemaValidationWarnings" => ["root is missing required keys: panel_groups"])
- end
+ expect(dashboard).to eql("path" => path, "schemaValidationWarnings" => ["panel_groups: should be an array of panel_groups objects"])
end
+ end
- context 'empty dashboard' do
- let(:path) { '.gitlab/dashboards/metrics.yml' }
- let(:project) { create(:project, :repository, :custom_repo, namespace: current_user.namespace, files: { path => "" }) }
+ context 'empty dashboard' do
+ let(:path) { '.gitlab/dashboards/metrics.yml' }
+ let(:project) { create(:project, :repository, :custom_repo, namespace: current_user.namespace, files: { path => "" }) }
- it 'returns metrics dashboard' do
- dashboard = graphql_data.dig('project', 'environments', 'nodes', 0, 'metricsDashboard')
+ it 'returns metrics dashboard' do
+ dashboard = graphql_data.dig('project', 'environments', 'nodes', 0, 'metricsDashboard')
- expect(dashboard).to eql("path" => path, "schemaValidationWarnings" => ["root is missing required keys: dashboard, panel_groups"])
- end
+ expect(dashboard).to eql("path" => path, "schemaValidationWarnings" => ["dashboard: can't be blank", "panel_groups: should be an array of panel_groups objects"])
end
end
+ end
- context 'requested dashboard can not be found' do
- let(:path) { 'config/prometheus/i_am_not_here.yml' }
+ context 'requested dashboard can not be found' do
+ let(:path) { 'config/prometheus/i_am_not_here.yml' }
- it_behaves_like 'a working graphql query'
+ it_behaves_like 'a working graphql query'
- it 'returns nil' do
- dashboard = graphql_data.dig('project', 'environments', 'nodes', 0, 'metricsDashboard')
+ it 'returns nil' do
+ dashboard = graphql_data.dig('project', 'environments', 'nodes', 0, 'metricsDashboard')
- expect(dashboard).to be_nil
- end
+ expect(dashboard).to be_nil
end
end
end
diff --git a/spec/requests/api/graphql/milestone_spec.rb b/spec/requests/api/graphql/milestone_spec.rb
index 78e7ec39ee3..2cea9fd0408 100644
--- a/spec/requests/api/graphql/milestone_spec.rb
+++ b/spec/requests/api/graphql/milestone_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Querying a Milestone' do
+RSpec.describe 'Querying a Milestone', feature_category: :team_planning do
include GraphqlHelpers
let_it_be(:group) { create(:group, :public) }
diff --git a/spec/requests/api/graphql/multiplexed_queries_spec.rb b/spec/requests/api/graphql/multiplexed_queries_spec.rb
index f79bac6ae3b..4d615d3eaa4 100644
--- a/spec/requests/api/graphql/multiplexed_queries_spec.rb
+++ b/spec/requests/api/graphql/multiplexed_queries_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
require 'spec_helper'
-RSpec.describe 'Multiplexed queries' do
+RSpec.describe 'Multiplexed queries', feature_category: :not_owned do
include GraphqlHelpers
it 'returns responses for multiple queries' do
diff --git a/spec/requests/api/graphql/mutations/admin/sidekiq_queues/delete_jobs_spec.rb b/spec/requests/api/graphql/mutations/admin/sidekiq_queues/delete_jobs_spec.rb
index f992e46879f..64ea6d32f5f 100644
--- a/spec/requests/api/graphql/mutations/admin/sidekiq_queues/delete_jobs_spec.rb
+++ b/spec/requests/api/graphql/mutations/admin/sidekiq_queues/delete_jobs_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Deleting Sidekiq jobs', :clean_gitlab_redis_queues do
+RSpec.describe 'Deleting Sidekiq jobs', :clean_gitlab_redis_queues, feature_category: :not_owned do
include GraphqlHelpers
let_it_be(:admin) { create(:admin) }
diff --git a/spec/requests/api/graphql/mutations/alert_management/alerts/create_alert_issue_spec.rb b/spec/requests/api/graphql/mutations/alert_management/alerts/create_alert_issue_spec.rb
index f637ca98353..fbe6d95dfff 100644
--- a/spec/requests/api/graphql/mutations/alert_management/alerts/create_alert_issue_spec.rb
+++ b/spec/requests/api/graphql/mutations/alert_management/alerts/create_alert_issue_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Create an alert issue from an alert' do
+RSpec.describe 'Create an alert issue from an alert', feature_category: :incident_management do
include GraphqlHelpers
let_it_be(:user) { create(:user) }
diff --git a/spec/requests/api/graphql/mutations/alert_management/alerts/set_assignees_spec.rb b/spec/requests/api/graphql/mutations/alert_management/alerts/set_assignees_spec.rb
index fcef7b4e3ec..935856814c4 100644
--- a/spec/requests/api/graphql/mutations/alert_management/alerts/set_assignees_spec.rb
+++ b/spec/requests/api/graphql/mutations/alert_management/alerts/set_assignees_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Setting assignees of an alert' do
+RSpec.describe 'Setting assignees of an alert', feature_category: :incident_management do
include GraphqlHelpers
let_it_be(:project) { create(:project) }
diff --git a/spec/requests/api/graphql/mutations/alert_management/alerts/todo/create_spec.rb b/spec/requests/api/graphql/mutations/alert_management/alerts/todo/create_spec.rb
index 48307964345..570324a3126 100644
--- a/spec/requests/api/graphql/mutations/alert_management/alerts/todo/create_spec.rb
+++ b/spec/requests/api/graphql/mutations/alert_management/alerts/todo/create_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Creating a todo for the alert' do
+RSpec.describe 'Creating a todo for the alert', feature_category: :incident_management do
include GraphqlHelpers
let_it_be(:user) { create(:user) }
diff --git a/spec/requests/api/graphql/mutations/alert_management/alerts/update_alert_status_spec.rb b/spec/requests/api/graphql/mutations/alert_management/alerts/update_alert_status_spec.rb
index 802d8d6c5a1..6537747850c 100644
--- a/spec/requests/api/graphql/mutations/alert_management/alerts/update_alert_status_spec.rb
+++ b/spec/requests/api/graphql/mutations/alert_management/alerts/update_alert_status_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Setting the status of an alert' do
+RSpec.describe 'Setting the status of an alert', feature_category: :incident_management do
include GraphqlHelpers
let_it_be(:user) { create(:user) }
diff --git a/spec/requests/api/graphql/mutations/alert_management/http_integration/create_spec.rb b/spec/requests/api/graphql/mutations/alert_management/http_integration/create_spec.rb
index ff93da2153f..187c88363c6 100644
--- a/spec/requests/api/graphql/mutations/alert_management/http_integration/create_spec.rb
+++ b/spec/requests/api/graphql/mutations/alert_management/http_integration/create_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Creating a new HTTP Integration' do
+RSpec.describe 'Creating a new HTTP Integration', feature_category: :integrations do
include GraphqlHelpers
let_it_be(:current_user) { create(:user) }
diff --git a/spec/requests/api/graphql/mutations/alert_management/http_integration/destroy_spec.rb b/spec/requests/api/graphql/mutations/alert_management/http_integration/destroy_spec.rb
index 1ecb5c76b57..1c77c71daba 100644
--- a/spec/requests/api/graphql/mutations/alert_management/http_integration/destroy_spec.rb
+++ b/spec/requests/api/graphql/mutations/alert_management/http_integration/destroy_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Removing an HTTP Integration' do
+RSpec.describe 'Removing an HTTP Integration', feature_category: :integrations do
include GraphqlHelpers
let_it_be(:user) { create(:user) }
diff --git a/spec/requests/api/graphql/mutations/alert_management/http_integration/reset_token_spec.rb b/spec/requests/api/graphql/mutations/alert_management/http_integration/reset_token_spec.rb
index badd9412589..427277dd540 100644
--- a/spec/requests/api/graphql/mutations/alert_management/http_integration/reset_token_spec.rb
+++ b/spec/requests/api/graphql/mutations/alert_management/http_integration/reset_token_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Resetting a token on an existing HTTP Integration' do
+RSpec.describe 'Resetting a token on an existing HTTP Integration', feature_category: :integrations do
include GraphqlHelpers
let_it_be(:user) { create(:user) }
diff --git a/spec/requests/api/graphql/mutations/alert_management/http_integration/update_spec.rb b/spec/requests/api/graphql/mutations/alert_management/http_integration/update_spec.rb
index 18cbb7d8b00..a9d189d564d 100644
--- a/spec/requests/api/graphql/mutations/alert_management/http_integration/update_spec.rb
+++ b/spec/requests/api/graphql/mutations/alert_management/http_integration/update_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Updating an existing HTTP Integration' do
+RSpec.describe 'Updating an existing HTTP Integration', feature_category: :integrations do
include GraphqlHelpers
let_it_be(:current_user) { create(:user) }
diff --git a/spec/requests/api/graphql/mutations/alert_management/prometheus_integration/create_spec.rb b/spec/requests/api/graphql/mutations/alert_management/prometheus_integration/create_spec.rb
index 4c359d9b357..3dee7f50af3 100644
--- a/spec/requests/api/graphql/mutations/alert_management/prometheus_integration/create_spec.rb
+++ b/spec/requests/api/graphql/mutations/alert_management/prometheus_integration/create_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Creating a new Prometheus Integration' do
+RSpec.describe 'Creating a new Prometheus Integration', feature_category: :incident_management do
include GraphqlHelpers
let_it_be(:current_user) { create(:user) }
diff --git a/spec/requests/api/graphql/mutations/alert_management/prometheus_integration/reset_token_spec.rb b/spec/requests/api/graphql/mutations/alert_management/prometheus_integration/reset_token_spec.rb
index 31053c50cac..15127843b95 100644
--- a/spec/requests/api/graphql/mutations/alert_management/prometheus_integration/reset_token_spec.rb
+++ b/spec/requests/api/graphql/mutations/alert_management/prometheus_integration/reset_token_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Resetting a token on an existing Prometheus Integration' do
+RSpec.describe 'Resetting a token on an existing Prometheus Integration', feature_category: :incident_management do
include GraphqlHelpers
let_it_be(:user) { create(:user) }
diff --git a/spec/requests/api/graphql/mutations/alert_management/prometheus_integration/update_spec.rb b/spec/requests/api/graphql/mutations/alert_management/prometheus_integration/update_spec.rb
index ad26ec118d7..63e95f4513b 100644
--- a/spec/requests/api/graphql/mutations/alert_management/prometheus_integration/update_spec.rb
+++ b/spec/requests/api/graphql/mutations/alert_management/prometheus_integration/update_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Updating an existing Prometheus Integration' do
+RSpec.describe 'Updating an existing Prometheus Integration', feature_category: :incident_management do
include GraphqlHelpers
let_it_be(:user) { create(:user) }
diff --git a/spec/requests/api/graphql/mutations/award_emojis/add_spec.rb b/spec/requests/api/graphql/mutations/award_emojis/add_spec.rb
index 3879e58cecf..fdbff0f93cd 100644
--- a/spec/requests/api/graphql/mutations/award_emojis/add_spec.rb
+++ b/spec/requests/api/graphql/mutations/award_emojis/add_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Adding an AwardEmoji' do
+RSpec.describe 'Adding an AwardEmoji', feature_category: :not_owned do
include GraphqlHelpers
let_it_be(:current_user) { create(:user) }
diff --git a/spec/requests/api/graphql/mutations/award_emojis/remove_spec.rb b/spec/requests/api/graphql/mutations/award_emojis/remove_spec.rb
index e81621209fb..e200bfc2d18 100644
--- a/spec/requests/api/graphql/mutations/award_emojis/remove_spec.rb
+++ b/spec/requests/api/graphql/mutations/award_emojis/remove_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Removing an AwardEmoji' do
+RSpec.describe 'Removing an AwardEmoji', feature_category: :not_owned do
include GraphqlHelpers
let(:current_user) { create(:user) }
diff --git a/spec/requests/api/graphql/mutations/award_emojis/toggle_spec.rb b/spec/requests/api/graphql/mutations/award_emojis/toggle_spec.rb
index b151da72b55..6dba2b58357 100644
--- a/spec/requests/api/graphql/mutations/award_emojis/toggle_spec.rb
+++ b/spec/requests/api/graphql/mutations/award_emojis/toggle_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Toggling an AwardEmoji' do
+RSpec.describe 'Toggling an AwardEmoji', feature_category: :not_owned do
include GraphqlHelpers
let_it_be(:current_user) { create(:user) }
diff --git a/spec/requests/api/graphql/mutations/boards/create_spec.rb b/spec/requests/api/graphql/mutations/boards/create_spec.rb
index ca848c0c92f..10eb12f277f 100644
--- a/spec/requests/api/graphql/mutations/boards/create_spec.rb
+++ b/spec/requests/api/graphql/mutations/boards/create_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Mutations::Boards::Create do
+RSpec.describe Mutations::Boards::Create, feature_category: :team_planning do
let_it_be(:parent) { create(:project) }
let_it_be(:current_user, reload: true) { create(:user) }
diff --git a/spec/requests/api/graphql/mutations/boards/destroy_spec.rb b/spec/requests/api/graphql/mutations/boards/destroy_spec.rb
index 7620da3e7e0..44924159137 100644
--- a/spec/requests/api/graphql/mutations/boards/destroy_spec.rb
+++ b/spec/requests/api/graphql/mutations/boards/destroy_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Mutations::Boards::Destroy do
+RSpec.describe Mutations::Boards::Destroy, feature_category: :team_planning do
include GraphqlHelpers
let_it_be(:current_user, reload: true) { create(:user) }
diff --git a/spec/requests/api/graphql/mutations/boards/issues/issue_move_list_spec.rb b/spec/requests/api/graphql/mutations/boards/issues/issue_move_list_spec.rb
index 06093e9f7c2..df64caa1cfb 100644
--- a/spec/requests/api/graphql/mutations/boards/issues/issue_move_list_spec.rb
+++ b/spec/requests/api/graphql/mutations/boards/issues/issue_move_list_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Reposition and move issue within board lists' do
+RSpec.describe 'Reposition and move issue within board lists', feature_category: :team_planning do
include GraphqlHelpers
let_it_be(:group) { create(:group, :private) }
diff --git a/spec/requests/api/graphql/mutations/boards/lists/create_spec.rb b/spec/requests/api/graphql/mutations/boards/lists/create_spec.rb
index fec9a8c6307..f5381be2741 100644
--- a/spec/requests/api/graphql/mutations/boards/lists/create_spec.rb
+++ b/spec/requests/api/graphql/mutations/boards/lists/create_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Create a label or backlog board list' do
+RSpec.describe 'Create a label or backlog board list', feature_category: :team_planning do
let_it_be(:group) { create(:group, :private) }
let_it_be(:board) { create(:board, group: group) }
diff --git a/spec/requests/api/graphql/mutations/boards/lists/destroy_spec.rb b/spec/requests/api/graphql/mutations/boards/lists/destroy_spec.rb
index 83309ead352..b37b1a7b935 100644
--- a/spec/requests/api/graphql/mutations/boards/lists/destroy_spec.rb
+++ b/spec/requests/api/graphql/mutations/boards/lists/destroy_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Mutations::Boards::Lists::Destroy do
+RSpec.describe Mutations::Boards::Lists::Destroy, feature_category: :team_planning do
include GraphqlHelpers
let_it_be(:current_user, reload: true) { create(:user) }
diff --git a/spec/requests/api/graphql/mutations/boards/lists/update_spec.rb b/spec/requests/api/graphql/mutations/boards/lists/update_spec.rb
index c7885879a9d..6a7edcd7349 100644
--- a/spec/requests/api/graphql/mutations/boards/lists/update_spec.rb
+++ b/spec/requests/api/graphql/mutations/boards/lists/update_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Update of an existing board list' do
+RSpec.describe 'Update of an existing board list', feature_category: :team_planning do
include GraphqlHelpers
let_it_be(:current_user) { create(:user) }
diff --git a/spec/requests/api/graphql/mutations/branches/create_spec.rb b/spec/requests/api/graphql/mutations/branches/create_spec.rb
index 9ee2f41e8fc..32512e2ee1b 100644
--- a/spec/requests/api/graphql/mutations/branches/create_spec.rb
+++ b/spec/requests/api/graphql/mutations/branches/create_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Creation of a new branch' do
+RSpec.describe 'Creation of a new branch', feature_category: :source_code_management do
include GraphqlHelpers
let_it_be(:group) { create(:group, :public) }
diff --git a/spec/requests/api/graphql/mutations/ci/job/artifacts_destroy_spec.rb b/spec/requests/api/graphql/mutations/ci/job/artifacts_destroy_spec.rb
index bdad80995ea..6cdf8788957 100644
--- a/spec/requests/api/graphql/mutations/ci/job/artifacts_destroy_spec.rb
+++ b/spec/requests/api/graphql/mutations/ci/job/artifacts_destroy_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'JobArtifactsDestroy' do
+RSpec.describe 'JobArtifactsDestroy', feature_category: :build_artifacts do
include GraphqlHelpers
let_it_be(:user) { create(:user) }
diff --git a/spec/requests/api/graphql/mutations/ci/job/destroy_spec.rb b/spec/requests/api/graphql/mutations/ci/job/destroy_spec.rb
index 5855eb6bb51..88dfec41d36 100644
--- a/spec/requests/api/graphql/mutations/ci/job/destroy_spec.rb
+++ b/spec/requests/api/graphql/mutations/ci/job/destroy_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'JobArtifactsDestroy' do
+RSpec.describe 'JobArtifactsDestroy', feature_category: :build_artifacts do
include GraphqlHelpers
let_it_be(:user) { create(:user) }
diff --git a/spec/requests/api/graphql/mutations/ci/job_artifact/destroy_spec.rb b/spec/requests/api/graphql/mutations/ci/job_artifact/destroy_spec.rb
index a5ec9ea343d..ac3592130b8 100644
--- a/spec/requests/api/graphql/mutations/ci/job_artifact/destroy_spec.rb
+++ b/spec/requests/api/graphql/mutations/ci/job_artifact/destroy_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'ArtifactDestroy' do
+RSpec.describe 'ArtifactDestroy', feature_category: :build_artifacts do
include GraphqlHelpers
let(:user) { create(:user) }
diff --git a/spec/requests/api/graphql/mutations/ci/job_cancel_spec.rb b/spec/requests/api/graphql/mutations/ci/job_cancel_spec.rb
index ee0f0a9bccb..468a9e57f56 100644
--- a/spec/requests/api/graphql/mutations/ci/job_cancel_spec.rb
+++ b/spec/requests/api/graphql/mutations/ci/job_cancel_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe "JobCancel" do
+RSpec.describe "JobCancel", feature_category: :continuous_integration do
include GraphqlHelpers
let_it_be(:user) { create(:user) }
diff --git a/spec/requests/api/graphql/mutations/ci/job_play_spec.rb b/spec/requests/api/graphql/mutations/ci/job_play_spec.rb
index 0874e225259..014a5e0f1c7 100644
--- a/spec/requests/api/graphql/mutations/ci/job_play_spec.rb
+++ b/spec/requests/api/graphql/mutations/ci/job_play_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'JobPlay' do
+RSpec.describe 'JobPlay', feature_category: :continuous_integration do
include GraphqlHelpers
let_it_be(:user) { create(:user) }
diff --git a/spec/requests/api/graphql/mutations/ci/job_retry_spec.rb b/spec/requests/api/graphql/mutations/ci/job_retry_spec.rb
index 8cf559a372a..e49ee6f3163 100644
--- a/spec/requests/api/graphql/mutations/ci/job_retry_spec.rb
+++ b/spec/requests/api/graphql/mutations/ci/job_retry_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'JobRetry' do
+RSpec.describe 'JobRetry', feature_category: :continuous_integration do
include GraphqlHelpers
let_it_be(:user) { create(:user) }
diff --git a/spec/requests/api/graphql/mutations/ci/job_token_scope/add_project_spec.rb b/spec/requests/api/graphql/mutations/ci/job_token_scope/add_project_spec.rb
index b2f84ab2869..490716ddbe2 100644
--- a/spec/requests/api/graphql/mutations/ci/job_token_scope/add_project_spec.rb
+++ b/spec/requests/api/graphql/mutations/ci/job_token_scope/add_project_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'CiJobTokenScopeAddProject' do
+RSpec.describe 'CiJobTokenScopeAddProject', feature_category: :continuous_integration do
include GraphqlHelpers
let_it_be(:project) { create(:project, ci_outbound_job_token_scope_enabled: true).tap(&:save!) }
@@ -60,7 +60,7 @@ RSpec.describe 'CiJobTokenScopeAddProject' do
post_graphql_mutation(mutation, current_user: current_user)
expect(response).to have_gitlab_http_status(:success)
expect(mutation_response.dig('ciJobTokenScope', 'projects', 'nodes')).not_to be_empty
- end.to change { Ci::JobToken::Scope.new(project).includes?(target_project) }.from(false).to(true)
+ end.to change { Ci::JobToken::Scope.new(project).allows?(target_project) }.from(false).to(true)
end
context 'when invalid target project is provided' do
diff --git a/spec/requests/api/graphql/mutations/ci/job_token_scope/remove_project_spec.rb b/spec/requests/api/graphql/mutations/ci/job_token_scope/remove_project_spec.rb
index 2b0adf89f40..607c6bd85c2 100644
--- a/spec/requests/api/graphql/mutations/ci/job_token_scope/remove_project_spec.rb
+++ b/spec/requests/api/graphql/mutations/ci/job_token_scope/remove_project_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'CiJobTokenScopeRemoveProject' do
+RSpec.describe 'CiJobTokenScopeRemoveProject', feature_category: :continuous_integration do
include GraphqlHelpers
let_it_be(:project) { create(:project, ci_outbound_job_token_scope_enabled: true).tap(&:save!) }
@@ -66,7 +66,7 @@ RSpec.describe 'CiJobTokenScopeRemoveProject' do
post_graphql_mutation(mutation, current_user: current_user)
expect(response).to have_gitlab_http_status(:success)
expect(mutation_response.dig('ciJobTokenScope', 'projects', 'nodes')).not_to be_empty
- end.to change { Ci::JobToken::Scope.new(project).includes?(target_project) }.from(true).to(false)
+ end.to change { Ci::JobToken::Scope.new(project).allows?(target_project) }.from(true).to(false)
end
context 'when invalid target project is provided' do
diff --git a/spec/requests/api/graphql/mutations/ci/job_unschedule_spec.rb b/spec/requests/api/graphql/mutations/ci/job_unschedule_spec.rb
index 4ddc019a2b5..6868b0ea279 100644
--- a/spec/requests/api/graphql/mutations/ci/job_unschedule_spec.rb
+++ b/spec/requests/api/graphql/mutations/ci/job_unschedule_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'JobUnschedule' do
+RSpec.describe 'JobUnschedule', feature_category: :continuous_integration do
include GraphqlHelpers
let_it_be(:user) { create(:user) }
diff --git a/spec/requests/api/graphql/mutations/ci/pipeline_cancel_spec.rb b/spec/requests/api/graphql/mutations/ci/pipeline_cancel_spec.rb
index 6ec1b7ce9b6..8c1359384ed 100644
--- a/spec/requests/api/graphql/mutations/ci/pipeline_cancel_spec.rb
+++ b/spec/requests/api/graphql/mutations/ci/pipeline_cancel_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'PipelineCancel' do
+RSpec.describe 'PipelineCancel', feature_category: :continuous_integration do
include GraphqlHelpers
let_it_be(:user) { create(:user) }
diff --git a/spec/requests/api/graphql/mutations/ci/pipeline_destroy_spec.rb b/spec/requests/api/graphql/mutations/ci/pipeline_destroy_spec.rb
index 7abd5ca8772..9ddfaf83d34 100644
--- a/spec/requests/api/graphql/mutations/ci/pipeline_destroy_spec.rb
+++ b/spec/requests/api/graphql/mutations/ci/pipeline_destroy_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'PipelineDestroy' do
+RSpec.describe 'PipelineDestroy', feature_category: :continuous_integration do
include GraphqlHelpers
let_it_be(:project) { create(:project) }
diff --git a/spec/requests/api/graphql/mutations/ci/pipeline_retry_spec.rb b/spec/requests/api/graphql/mutations/ci/pipeline_retry_spec.rb
index f6acf29c321..e7edc86bea0 100644
--- a/spec/requests/api/graphql/mutations/ci/pipeline_retry_spec.rb
+++ b/spec/requests/api/graphql/mutations/ci/pipeline_retry_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'PipelineRetry' do
+RSpec.describe 'PipelineRetry', feature_category: :continuous_integration do
include GraphqlHelpers
let_it_be(:user) { create(:user) }
diff --git a/spec/requests/api/graphql/mutations/ci/pipeline_schedule_create_spec.rb b/spec/requests/api/graphql/mutations/ci/pipeline_schedule_create_spec.rb
new file mode 100644
index 00000000000..4a45d255d99
--- /dev/null
+++ b/spec/requests/api/graphql/mutations/ci/pipeline_schedule_create_spec.rb
@@ -0,0 +1,151 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'PipelineSchedulecreate' do
+ include GraphqlHelpers
+
+ let_it_be(:user) { create(:user) }
+ let_it_be(:project) { create(:project, :public, :repository) }
+
+ let(:mutation) do
+ variables = {
+ project_path: project.full_path,
+ **pipeline_schedule_parameters
+ }
+
+ graphql_mutation(
+ :pipeline_schedule_create,
+ variables,
+ <<-QL
+ pipelineSchedule {
+ id
+ description
+ cron
+ refForDisplay
+ active
+ cronTimezone
+ variables {
+ nodes {
+ key
+ value
+ }
+ }
+ owner {
+ id
+ }
+ }
+ errors
+ QL
+ )
+ end
+
+ let(:pipeline_schedule_parameters) do
+ {
+ description: 'created_desc',
+ cron: '0 1 * * *',
+ cronTimezone: 'UTC',
+ ref: 'patch-x',
+ active: true,
+ variables: [
+ { key: 'AAA', value: "AAA123", variableType: 'ENV_VAR' }
+ ]
+ }
+ end
+
+ let(:mutation_response) { graphql_mutation_response(:pipeline_schedule_create) }
+
+ context 'when unauthorized' do
+ it 'returns an error' do
+ post_graphql_mutation(mutation, current_user: user)
+
+ expect(graphql_errors).not_to be_empty
+ expect(graphql_errors[0]['message'])
+ .to eq(
+ "The resource that you are attempting to access does not exist " \
+ "or you don't have permission to perform this action"
+ )
+ end
+ end
+
+ context 'when authorized' do
+ before do
+ project.add_developer(user)
+ end
+
+ context 'when success' do
+ it do
+ post_graphql_mutation(mutation, current_user: user)
+
+ expect(response).to have_gitlab_http_status(:success)
+
+ expect(mutation_response['pipelineSchedule']['owner']['id']).to eq(user.to_global_id.to_s)
+
+ %w[description cron cronTimezone active].each do |key|
+ expect(mutation_response['pipelineSchedule'][key]).to eq(pipeline_schedule_parameters[key.to_sym])
+ end
+
+ expect(mutation_response['pipelineSchedule']['refForDisplay']).to eq(pipeline_schedule_parameters[:ref])
+
+ expect(mutation_response['pipelineSchedule']['variables']['nodes'][0]['key']).to eq('AAA')
+ expect(mutation_response['pipelineSchedule']['variables']['nodes'][0]['value']).to eq('AAA123')
+
+ expect(mutation_response['pipelineSchedule']['owner']['id']).to eq(user.to_global_id.to_s)
+
+ expect(mutation_response['errors']).to eq([])
+ end
+ end
+
+ context 'when failure' do
+ context 'when params are invalid' do
+ let(:pipeline_schedule_parameters) do
+ {
+ description: 'some description',
+ cron: 'abc',
+ cronTimezone: 'cCc',
+ ref: 'asd',
+ active: true,
+ variables: []
+ }
+ end
+
+ it do
+ post_graphql_mutation(mutation, current_user: user)
+
+ expect(response).to have_gitlab_http_status(:success)
+
+ expect(mutation_response['errors'])
+ .to match_array(
+ ["Cron is invalid syntax", "Cron timezone is invalid syntax"]
+ )
+ end
+ end
+
+ context 'when variables have duplicate name' do
+ before do
+ pipeline_schedule_parameters.merge!(
+ {
+ variables: [
+ { key: 'AAA', value: "AAA123", variableType: 'ENV_VAR' },
+ { key: 'AAA', value: "AAA123", variableType: 'ENV_VAR' }
+ ]
+ }
+ )
+ end
+
+ it 'returns error' do
+ post_graphql_mutation(mutation, current_user: user)
+
+ expect(response).to have_gitlab_http_status(:success)
+
+ expect(mutation_response['errors'])
+ .to match_array(
+ [
+ "Variables have duplicate values (AAA)"
+ ]
+ )
+ end
+ end
+ end
+ end
+end
diff --git a/spec/requests/api/graphql/mutations/ci/pipeline_schedule_delete_spec.rb b/spec/requests/api/graphql/mutations/ci/pipeline_schedule_delete_spec.rb
index b197d223463..b846ff0aec8 100644
--- a/spec/requests/api/graphql/mutations/ci/pipeline_schedule_delete_spec.rb
+++ b/spec/requests/api/graphql/mutations/ci/pipeline_schedule_delete_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'PipelineScheduleDelete' do
+RSpec.describe 'PipelineScheduleDelete', feature_category: :continuous_integration do
include GraphqlHelpers
let_it_be(:user) { create(:user) }
diff --git a/spec/requests/api/graphql/mutations/ci/pipeline_schedule_play_spec.rb b/spec/requests/api/graphql/mutations/ci/pipeline_schedule_play_spec.rb
new file mode 100644
index 00000000000..0e43fa024f3
--- /dev/null
+++ b/spec/requests/api/graphql/mutations/ci/pipeline_schedule_play_spec.rb
@@ -0,0 +1,80 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'PipelineSchedulePlay', feature_category: :continuious_integration do
+ include GraphqlHelpers
+
+ let_it_be(:user) { create(:user) }
+ let_it_be(:project) { create(:project) }
+ let_it_be(:pipeline_schedule) do
+ create(
+ :ci_pipeline_schedule,
+ :every_minute,
+ project: project,
+ owner: user
+ )
+ end
+
+ let(:mutation) do
+ graphql_mutation(
+ :pipeline_schedule_play,
+ { id: pipeline_schedule.to_global_id.to_s },
+ <<-QL
+ pipelineSchedule { id, nextRunAt }
+ errors
+ QL
+ )
+ end
+
+ let(:mutation_response) { graphql_mutation_response(:pipeline_schedule_play) }
+
+ context 'when unauthorized' do
+ it 'returns an error' do
+ post_graphql_mutation(mutation, current_user: create(:user))
+
+ expect(graphql_errors).not_to be_empty
+ expect(graphql_errors[0]['message'])
+ .to eq(
+ "The resource that you are attempting to access does not exist " \
+ "or you don't have permission to perform this action"
+ )
+ end
+ end
+
+ context 'when authorized' do
+ before do
+ project.add_maintainer(user)
+ pipeline_schedule.update_columns(next_run_at: 2.hours.ago)
+ end
+
+ context 'when mutation succeeds' do
+ it do
+ post_graphql_mutation(mutation, current_user: user)
+
+ expect(mutation_response['pipelineSchedule']['id']).to include(pipeline_schedule.id.to_s)
+ new_next_run_at = DateTime.parse(mutation_response['pipelineSchedule']['nextRunAt'])
+ expect(new_next_run_at).not_to eq(pipeline_schedule.next_run_at)
+ expect(new_next_run_at).to eq(pipeline_schedule.reset.next_run_at)
+ expect(mutation_response['errors']).to eq([])
+ end
+ end
+
+ context 'when mutation fails' do
+ before do
+ allow(RunPipelineScheduleWorker).to receive(:perform_async).and_return(nil)
+ end
+
+ it do
+ expect(RunPipelineScheduleWorker)
+ .to receive(:perform_async)
+ .with(pipeline_schedule.id, user.id)
+
+ post_graphql_mutation(mutation, current_user: user)
+
+ expect(mutation_response['pipelineSchedule']).to be_nil
+ expect(mutation_response['errors']).to match_array(['Unable to schedule a pipeline to run immediately.'])
+ end
+ end
+ end
+end
diff --git a/spec/requests/api/graphql/mutations/ci/pipeline_schedule_take_ownership_spec.rb b/spec/requests/api/graphql/mutations/ci/pipeline_schedule_take_ownership_spec.rb
index 8dfbf20d00b..2d1f1565a73 100644
--- a/spec/requests/api/graphql/mutations/ci/pipeline_schedule_take_ownership_spec.rb
+++ b/spec/requests/api/graphql/mutations/ci/pipeline_schedule_take_ownership_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'PipelineScheduleTakeOwnership' do
+RSpec.describe 'PipelineScheduleTakeOwnership', feature_category: :continuous_integration do
include GraphqlHelpers
let_it_be(:user) { create(:user) }
diff --git a/spec/requests/api/graphql/mutations/ci/project_ci_cd_settings_update_spec.rb b/spec/requests/api/graphql/mutations/ci/project_ci_cd_settings_update_spec.rb
index c808cf5ede9..7a6ee7c2ecc 100644
--- a/spec/requests/api/graphql/mutations/ci/project_ci_cd_settings_update_spec.rb
+++ b/spec/requests/api/graphql/mutations/ci/project_ci_cd_settings_update_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'ProjectCiCdSettingsUpdate' do
+RSpec.describe 'ProjectCiCdSettingsUpdate', feature_category: :continuous_integration do
include GraphqlHelpers
let_it_be(:project) do
diff --git a/spec/requests/api/graphql/mutations/ci/runners_registration_token/reset_spec.rb b/spec/requests/api/graphql/mutations/ci/runners_registration_token/reset_spec.rb
index 54e63df96a6..752242c3ab3 100644
--- a/spec/requests/api/graphql/mutations/ci/runners_registration_token/reset_spec.rb
+++ b/spec/requests/api/graphql/mutations/ci/runners_registration_token/reset_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'RunnersRegistrationTokenReset' do
+RSpec.describe 'RunnersRegistrationTokenReset', feature_category: :runner_fleet do
include GraphqlHelpers
let(:mutation) { graphql_mutation(:runners_registration_token_reset, input) }
diff --git a/spec/requests/api/graphql/mutations/clusters/agent_tokens/agent_tokens/create_spec.rb b/spec/requests/api/graphql/mutations/clusters/agent_tokens/agent_tokens/create_spec.rb
index aac8eb22771..f544cef8864 100644
--- a/spec/requests/api/graphql/mutations/clusters/agent_tokens/agent_tokens/create_spec.rb
+++ b/spec/requests/api/graphql/mutations/clusters/agent_tokens/agent_tokens/create_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Create a new cluster agent token' do
+RSpec.describe 'Create a new cluster agent token', feature_category: :kubernetes_management do
include GraphqlHelpers
let_it_be(:cluster_agent) { create(:cluster_agent) }
diff --git a/spec/requests/api/graphql/mutations/clusters/agents/create_spec.rb b/spec/requests/api/graphql/mutations/clusters/agents/create_spec.rb
index c2ef2362d66..66e6c5cc629 100644
--- a/spec/requests/api/graphql/mutations/clusters/agents/create_spec.rb
+++ b/spec/requests/api/graphql/mutations/clusters/agents/create_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Create a new cluster agent' do
+RSpec.describe 'Create a new cluster agent', feature_category: :kubernetes_management do
include GraphqlHelpers
let(:project) { create(:project, :public, :repository) }
diff --git a/spec/requests/api/graphql/mutations/clusters/agents/delete_spec.rb b/spec/requests/api/graphql/mutations/clusters/agents/delete_spec.rb
index 4891e64aab8..27a566dfb8c 100644
--- a/spec/requests/api/graphql/mutations/clusters/agents/delete_spec.rb
+++ b/spec/requests/api/graphql/mutations/clusters/agents/delete_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Delete a cluster agent' do
+RSpec.describe 'Delete a cluster agent', feature_category: :kubernetes_management do
include GraphqlHelpers
let(:cluster_agent) { create(:cluster_agent) }
diff --git a/spec/requests/api/graphql/mutations/commits/create_spec.rb b/spec/requests/api/graphql/mutations/commits/create_spec.rb
index 619cba99c4e..e298d8284c6 100644
--- a/spec/requests/api/graphql/mutations/commits/create_spec.rb
+++ b/spec/requests/api/graphql/mutations/commits/create_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Creation of a new commit' do
+RSpec.describe 'Creation of a new commit', feature_category: :source_code_management do
include GraphqlHelpers
let_it_be(:current_user) { create(:user) }
diff --git a/spec/requests/api/graphql/mutations/container_expiration_policy/update_spec.rb b/spec/requests/api/graphql/mutations/container_expiration_policy/update_spec.rb
index ca7c1b2ce5f..97e2a5d0bf7 100644
--- a/spec/requests/api/graphql/mutations/container_expiration_policy/update_spec.rb
+++ b/spec/requests/api/graphql/mutations/container_expiration_policy/update_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Updating the container expiration policy' do
+RSpec.describe 'Updating the container expiration policy', feature_category: :container_registry do
include GraphqlHelpers
using RSpec::Parameterized::TableSyntax
diff --git a/spec/requests/api/graphql/mutations/container_repository/destroy_spec.rb b/spec/requests/api/graphql/mutations/container_repository/destroy_spec.rb
index 5a27d39ecbc..8b76c19cda6 100644
--- a/spec/requests/api/graphql/mutations/container_repository/destroy_spec.rb
+++ b/spec/requests/api/graphql/mutations/container_repository/destroy_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Destroying a container repository' do
+RSpec.describe 'Destroying a container repository', feature_category: :container_registry do
using RSpec::Parameterized::TableSyntax
include GraphqlHelpers
@@ -80,25 +80,6 @@ RSpec.describe 'Destroying a container repository' do
it_behaves_like params[:shared_examples_name]
end
-
- context 'with container_registry_delete_repository_with_cron_worker disabled' do
- before do
- project.add_maintainer(user)
- stub_feature_flags(container_registry_delete_repository_with_cron_worker: false)
- end
-
- it 'enqueues a removal job' do
- expect(::Packages::CreateEventService)
- .to receive(:new).with(nil, user, event_name: :delete_repository, scope: :container).and_call_original
- expect(DeleteContainerRepositoryWorker)
- .to receive(:perform_async).with(user.id, container_repository.id)
-
- expect { subject }.to change { ::Packages::Event.count }.by(1)
-
- expect(container_repository_mutation_response).to match_schema('graphql/container_repository')
- expect(container_repository_mutation_response['status']).to eq('DELETE_SCHEDULED')
- end
- end
end
context 'with invalid id' do
diff --git a/spec/requests/api/graphql/mutations/container_repository/destroy_tags_spec.rb b/spec/requests/api/graphql/mutations/container_repository/destroy_tags_spec.rb
index ef00f45ef18..9e07a831076 100644
--- a/spec/requests/api/graphql/mutations/container_repository/destroy_tags_spec.rb
+++ b/spec/requests/api/graphql/mutations/container_repository/destroy_tags_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Destroying a container repository tags' do
+RSpec.describe 'Destroying a container repository tags', feature_category: :container_registry do
include_context 'container repository delete tags service shared context'
using RSpec::Parameterized::TableSyntax
diff --git a/spec/requests/api/graphql/mutations/custom_emoji/create_spec.rb b/spec/requests/api/graphql/mutations/custom_emoji/create_spec.rb
index 66facdebe78..ea2ce8a13e2 100644
--- a/spec/requests/api/graphql/mutations/custom_emoji/create_spec.rb
+++ b/spec/requests/api/graphql/mutations/custom_emoji/create_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Creation of a new Custom Emoji' do
+RSpec.describe 'Creation of a new Custom Emoji', feature_category: :not_owned do
include GraphqlHelpers
let_it_be(:current_user) { create(:user) }
diff --git a/spec/requests/api/graphql/mutations/custom_emoji/destroy_spec.rb b/spec/requests/api/graphql/mutations/custom_emoji/destroy_spec.rb
index 7d25206e617..ad7a043909a 100644
--- a/spec/requests/api/graphql/mutations/custom_emoji/destroy_spec.rb
+++ b/spec/requests/api/graphql/mutations/custom_emoji/destroy_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Deletion of custom emoji' do
+RSpec.describe 'Deletion of custom emoji', feature_category: :not_owned do
include GraphqlHelpers
let_it_be(:group) { create(:group) }
diff --git a/spec/requests/api/graphql/mutations/dependency_proxy/group_settings/update_spec.rb b/spec/requests/api/graphql/mutations/dependency_proxy/group_settings/update_spec.rb
index 9eb13e534ac..5d5696d3f66 100644
--- a/spec/requests/api/graphql/mutations/dependency_proxy/group_settings/update_spec.rb
+++ b/spec/requests/api/graphql/mutations/dependency_proxy/group_settings/update_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Updating the dependency proxy group settings' do
+RSpec.describe 'Updating the dependency proxy group settings', feature_category: :dependency_proxy do
include GraphqlHelpers
using RSpec::Parameterized::TableSyntax
diff --git a/spec/requests/api/graphql/mutations/dependency_proxy/image_ttl_group_policy/update_spec.rb b/spec/requests/api/graphql/mutations/dependency_proxy/image_ttl_group_policy/update_spec.rb
index 31ba7ecdf0e..66ee17f356c 100644
--- a/spec/requests/api/graphql/mutations/dependency_proxy/image_ttl_group_policy/update_spec.rb
+++ b/spec/requests/api/graphql/mutations/dependency_proxy/image_ttl_group_policy/update_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Updating the dependency proxy image ttl policy' do
+RSpec.describe 'Updating the dependency proxy image ttl policy', feature_category: :dependency_proxy do
include GraphqlHelpers
using RSpec::Parameterized::TableSyntax
diff --git a/spec/requests/api/graphql/mutations/design_management/delete_spec.rb b/spec/requests/api/graphql/mutations/design_management/delete_spec.rb
index e2ab08b301b..7ea32ae6d19 100644
--- a/spec/requests/api/graphql/mutations/design_management/delete_spec.rb
+++ b/spec/requests/api/graphql/mutations/design_management/delete_spec.rb
@@ -2,7 +2,7 @@
require "spec_helper"
-RSpec.describe "deleting designs" do
+RSpec.describe "deleting designs", feature_category: :design_management do
include GraphqlHelpers
include DesignManagementTestHelpers
diff --git a/spec/requests/api/graphql/mutations/design_management/move_spec.rb b/spec/requests/api/graphql/mutations/design_management/move_spec.rb
index dd121ec733e..27b5259c56b 100644
--- a/spec/requests/api/graphql/mutations/design_management/move_spec.rb
+++ b/spec/requests/api/graphql/mutations/design_management/move_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
require "spec_helper"
-RSpec.describe "moving designs" do
+RSpec.describe "moving designs", feature_category: :design_management do
include GraphqlHelpers
include DesignManagementTestHelpers
diff --git a/spec/requests/api/graphql/mutations/design_management/upload_spec.rb b/spec/requests/api/graphql/mutations/design_management/upload_spec.rb
index d3e6c689a59..9b42b32c150 100644
--- a/spec/requests/api/graphql/mutations/design_management/upload_spec.rb
+++ b/spec/requests/api/graphql/mutations/design_management/upload_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
require "spec_helper"
-RSpec.describe "uploading designs" do
+RSpec.describe "uploading designs", feature_category: :design_management do
include GraphqlHelpers
include DesignManagementTestHelpers
include WorkhorseHelpers
diff --git a/spec/requests/api/graphql/mutations/discussions/toggle_resolve_spec.rb b/spec/requests/api/graphql/mutations/discussions/toggle_resolve_spec.rb
index 632a934cd95..16d3bbb6518 100644
--- a/spec/requests/api/graphql/mutations/discussions/toggle_resolve_spec.rb
+++ b/spec/requests/api/graphql/mutations/discussions/toggle_resolve_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Toggling the resolve status of a discussion' do
+RSpec.describe 'Toggling the resolve status of a discussion', feature_category: :team_planning do
include GraphqlHelpers
let_it_be(:project) { create(:project, :public, :repository) }
diff --git a/spec/requests/api/graphql/mutations/environments/canary_ingress/update_spec.rb b/spec/requests/api/graphql/mutations/environments/canary_ingress/update_spec.rb
index 3771ae0746e..0e9317a4879 100644
--- a/spec/requests/api/graphql/mutations/environments/canary_ingress/update_spec.rb
+++ b/spec/requests/api/graphql/mutations/environments/canary_ingress/update_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Update Environment Canary Ingress', :clean_gitlab_redis_cache do
+RSpec.describe 'Update Environment Canary Ingress', :clean_gitlab_redis_cache, feature_category: :deployment_management do
include GraphqlHelpers
include KubernetesHelpers
diff --git a/spec/requests/api/graphql/mutations/groups/update_spec.rb b/spec/requests/api/graphql/mutations/groups/update_spec.rb
index b9dfb8e37ab..ea3d42a4463 100644
--- a/spec/requests/api/graphql/mutations/groups/update_spec.rb
+++ b/spec/requests/api/graphql/mutations/groups/update_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'GroupUpdate' do
+RSpec.describe 'GroupUpdate', feature_category: :subgroups do
include GraphqlHelpers
let_it_be(:user) { create(:user) }
diff --git a/spec/requests/api/graphql/mutations/incident_management/timeline_event/create_spec.rb b/spec/requests/api/graphql/mutations/incident_management/timeline_event/create_spec.rb
index fc3b666dd3d..49cee4f6801 100644
--- a/spec/requests/api/graphql/mutations/incident_management/timeline_event/create_spec.rb
+++ b/spec/requests/api/graphql/mutations/incident_management/timeline_event/create_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Creating an incident timeline event' do
+RSpec.describe 'Creating an incident timeline event', feature_category: :incident_management do
include GraphqlHelpers
let_it_be(:user) { create(:user) }
diff --git a/spec/requests/api/graphql/mutations/incident_management/timeline_event/destroy_spec.rb b/spec/requests/api/graphql/mutations/incident_management/timeline_event/destroy_spec.rb
index 85208869ad9..6e1a7b36736 100644
--- a/spec/requests/api/graphql/mutations/incident_management/timeline_event/destroy_spec.rb
+++ b/spec/requests/api/graphql/mutations/incident_management/timeline_event/destroy_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Removing an incident timeline event' do
+RSpec.describe 'Removing an incident timeline event', feature_category: :incident_management do
include GraphqlHelpers
let_it_be(:user) { create(:user) }
diff --git a/spec/requests/api/graphql/mutations/incident_management/timeline_event/promote_from_note_spec.rb b/spec/requests/api/graphql/mutations/incident_management/timeline_event/promote_from_note_spec.rb
index 62eeecb3fb7..ca9557b3183 100644
--- a/spec/requests/api/graphql/mutations/incident_management/timeline_event/promote_from_note_spec.rb
+++ b/spec/requests/api/graphql/mutations/incident_management/timeline_event/promote_from_note_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Promote an incident timeline event from a comment' do
+RSpec.describe 'Promote an incident timeline event from a comment', feature_category: :incident_management do
include GraphqlHelpers
include NotesHelper
diff --git a/spec/requests/api/graphql/mutations/incident_management/timeline_event/update_spec.rb b/spec/requests/api/graphql/mutations/incident_management/timeline_event/update_spec.rb
index 542d51b990f..163c689e399 100644
--- a/spec/requests/api/graphql/mutations/incident_management/timeline_event/update_spec.rb
+++ b/spec/requests/api/graphql/mutations/incident_management/timeline_event/update_spec.rb
@@ -2,24 +2,36 @@
require 'spec_helper'
-RSpec.describe 'Updating an incident timeline event' do
+RSpec.describe 'Updating an incident timeline event', feature_category: :incident_management do
include GraphqlHelpers
let_it_be(:user) { create(:user) }
let_it_be(:project) { create(:project) }
let_it_be(:incident) { create(:incident, project: project) }
+ let_it_be(:tag1) { create(:incident_management_timeline_event_tag, project: project, name: 'Tag 1') }
+ let_it_be(:tag2) { create(:incident_management_timeline_event_tag, project: project, name: 'Tag 2') }
let_it_be_with_reload(:timeline_event) do
create(:incident_management_timeline_event, incident: incident, project: project)
end
+ # Pre-attach a tag to the event
+ let_it_be(:tag_link1) do
+ create(:incident_management_timeline_event_tag_link,
+ timeline_event: timeline_event,
+ timeline_event_tag: tag1
+ )
+ end
+
let(:occurred_at) { 1.minute.ago.iso8601 }
let(:note) { 'Updated note' }
+ let(:tag_names) { [] }
let(:variables) do
{
id: timeline_event.to_global_id.to_s,
note: note,
- occurred_at: occurred_at
+ occurred_at: occurred_at,
+ timeline_event_tag_names: tag_names
}
end
@@ -33,6 +45,7 @@ RSpec.describe 'Updating an incident timeline event' do
author { id username }
updatedByUser { id username }
incident { id title }
+ timelineEventTags { nodes { name } }
note
noteHtml
occurredAt
@@ -71,6 +84,9 @@ RSpec.describe 'Updating an incident timeline event' do
'id' => incident.to_global_id.to_s,
'title' => incident.title
},
+ 'timelineEventTags' => {
+ 'nodes' => []
+ },
'note' => note,
'noteHtml' => timeline_event.note_html,
'occurredAt' => occurred_at,
@@ -85,4 +101,27 @@ RSpec.describe 'Updating an incident timeline event' do
it_behaves_like 'timeline event mutation responds with validation error',
error_message: 'Timeline text is too long (maximum is 280 characters)'
end
+
+ context 'when timeline event tag names are passed' do
+ context 'when tags exist' do
+ let(:tag_names) { [tag2.name] }
+
+ it 'removes tag1 and adds tag2' do
+ post_graphql_mutation(mutation, current_user: user)
+
+ timeline_event_response = mutation_response['timelineEvent']
+ tag_names = timeline_event_response['timelineEventTags']['nodes']
+
+ expect(response).to have_gitlab_http_status(:success)
+ expect(tag_names).to contain_exactly({ "name" => tag2.name })
+ end
+ end
+
+ context 'when tags do not exist' do
+ let(:tag_names) { ['some other tag'] }
+
+ it_behaves_like 'timeline event mutation responds with validation error',
+ error_message: "Following tags don't exist: [\"some other tag\"]"
+ end
+ end
end
diff --git a/spec/requests/api/graphql/mutations/incident_management/timeline_event_tag/create_spec.rb b/spec/requests/api/graphql/mutations/incident_management/timeline_event_tag/create_spec.rb
index 7476499d9da..b37a5331421 100644
--- a/spec/requests/api/graphql/mutations/incident_management/timeline_event_tag/create_spec.rb
+++ b/spec/requests/api/graphql/mutations/incident_management/timeline_event_tag/create_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Creating a timeline event tag' do
+RSpec.describe 'Creating a timeline event tag', feature_category: :incident_management do
include GraphqlHelpers
let_it_be(:user) { create(:user) }
diff --git a/spec/requests/api/graphql/mutations/issues/create_spec.rb b/spec/requests/api/graphql/mutations/issues/create_spec.rb
index a489b7424e8..d2d2f0014d6 100644
--- a/spec/requests/api/graphql/mutations/issues/create_spec.rb
+++ b/spec/requests/api/graphql/mutations/issues/create_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Create an issue' do
+RSpec.describe 'Create an issue', feature_category: :team_planning do
include GraphqlHelpers
let_it_be(:current_user) { create(:user) }
diff --git a/spec/requests/api/graphql/mutations/issues/link_alerts_spec.rb b/spec/requests/api/graphql/mutations/issues/link_alerts_spec.rb
new file mode 100644
index 00000000000..85e21952f47
--- /dev/null
+++ b/spec/requests/api/graphql/mutations/issues/link_alerts_spec.rb
@@ -0,0 +1,65 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'Link alerts to an incident', feature_category: :incident_management do
+ include GraphqlHelpers
+
+ let_it_be(:user) { create(:user) }
+ let_it_be(:project) { create(:project) }
+ let_it_be(:linked_alert) { create(:alert_management_alert, project: project) }
+ let_it_be(:alert1) { create(:alert_management_alert, project: project) }
+ let_it_be(:alert2) { create(:alert_management_alert, project: project) }
+ let_it_be(:incident) { create(:incident, project: project, alert_management_alerts: [linked_alert]) }
+
+ let(:mutation) do
+ variables = {
+ project_path: project.full_path,
+ iid: incident.iid.to_s,
+ alert_references: [alert1.to_reference, alert2.details_url]
+ }
+
+ graphql_mutation(:issue_link_alerts, variables,
+ <<-QL.strip_heredoc
+ clientMutationId
+ errors
+ issue {
+ iid
+ alertManagementAlerts {
+ nodes {
+ iid
+ }
+ }
+ }
+ QL
+ )
+ end
+
+ def mutation_response
+ graphql_mutation_response(:issue_link_alerts)
+ end
+
+ context 'when the user is not allowed to update the incident' do
+ it 'returns an error' do
+ error = Gitlab::Graphql::Authorize::AuthorizeResource::RESOURCE_ACCESS_ERROR
+ post_graphql_mutation(mutation, current_user: user)
+
+ expect(response).to have_gitlab_http_status(:success)
+ expect(graphql_errors).to include(a_hash_including('message' => error))
+ end
+ end
+
+ context 'when the user is allowed to update the incident' do
+ before do
+ project.add_developer(user)
+ end
+
+ it 'links alerts to the incident' do
+ post_graphql_mutation(mutation, current_user: user)
+
+ expect(response).to have_gitlab_http_status(:success)
+ expected_response = [linked_alert, alert1, alert2].map { |a| { 'iid' => a.iid.to_s } }
+ expect(mutation_response.dig('issue', 'alertManagementAlerts', 'nodes')).to match_array(expected_response)
+ end
+ end
+end
diff --git a/spec/requests/api/graphql/mutations/issues/move_spec.rb b/spec/requests/api/graphql/mutations/issues/move_spec.rb
index 20ed16879f6..7d9579067b6 100644
--- a/spec/requests/api/graphql/mutations/issues/move_spec.rb
+++ b/spec/requests/api/graphql/mutations/issues/move_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Moving an issue' do
+RSpec.describe 'Moving an issue', feature_category: :team_planning do
include GraphqlHelpers
let_it_be(:user) { create(:user) }
diff --git a/spec/requests/api/graphql/mutations/issues/set_confidential_spec.rb b/spec/requests/api/graphql/mutations/issues/set_confidential_spec.rb
index 12ab504da14..c5e6901d8f8 100644
--- a/spec/requests/api/graphql/mutations/issues/set_confidential_spec.rb
+++ b/spec/requests/api/graphql/mutations/issues/set_confidential_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Setting an issue as confidential' do
+RSpec.describe 'Setting an issue as confidential', feature_category: :team_planning do
include GraphqlHelpers
let(:current_user) { create(:user) }
diff --git a/spec/requests/api/graphql/mutations/issues/set_crm_contacts_spec.rb b/spec/requests/api/graphql/mutations/issues/set_crm_contacts_spec.rb
index 395a490bfc3..9fce5f8497f 100644
--- a/spec/requests/api/graphql/mutations/issues/set_crm_contacts_spec.rb
+++ b/spec/requests/api/graphql/mutations/issues/set_crm_contacts_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Setting issues crm contacts' do
+RSpec.describe 'Setting issues crm contacts', feature_category: :service_desk do
include GraphqlHelpers
let_it_be(:user) { create(:user) }
diff --git a/spec/requests/api/graphql/mutations/issues/set_due_date_spec.rb b/spec/requests/api/graphql/mutations/issues/set_due_date_spec.rb
index 8e223b6fdaf..1a5a64e4196 100644
--- a/spec/requests/api/graphql/mutations/issues/set_due_date_spec.rb
+++ b/spec/requests/api/graphql/mutations/issues/set_due_date_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Setting Due Date of an issue' do
+RSpec.describe 'Setting Due Date of an issue', feature_category: :team_planning do
include GraphqlHelpers
let(:current_user) { create(:user) }
diff --git a/spec/requests/api/graphql/mutations/issues/set_escalation_status_spec.rb b/spec/requests/api/graphql/mutations/issues/set_escalation_status_spec.rb
index a81364d37b2..8fc3ad4236d 100644
--- a/spec/requests/api/graphql/mutations/issues/set_escalation_status_spec.rb
+++ b/spec/requests/api/graphql/mutations/issues/set_escalation_status_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Setting the escalation status of an incident' do
+RSpec.describe 'Setting the escalation status of an incident', feature_category: :incident_management do
include GraphqlHelpers
let_it_be(:project) { create(:project) }
diff --git a/spec/requests/api/graphql/mutations/issues/set_locked_spec.rb b/spec/requests/api/graphql/mutations/issues/set_locked_spec.rb
index 435ed0f9eb2..a8025894b1e 100644
--- a/spec/requests/api/graphql/mutations/issues/set_locked_spec.rb
+++ b/spec/requests/api/graphql/mutations/issues/set_locked_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Setting an issue as locked' do
+RSpec.describe 'Setting an issue as locked', feature_category: :team_planning do
include GraphqlHelpers
let_it_be(:current_user) { create(:user) }
diff --git a/spec/requests/api/graphql/mutations/issues/set_severity_spec.rb b/spec/requests/api/graphql/mutations/issues/set_severity_spec.rb
index cd9d695bd2c..77262c7f64f 100644
--- a/spec/requests/api/graphql/mutations/issues/set_severity_spec.rb
+++ b/spec/requests/api/graphql/mutations/issues/set_severity_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Setting severity level of an incident' do
+RSpec.describe 'Setting severity level of an incident', feature_category: :incident_management do
include GraphqlHelpers
let_it_be(:user) { create(:user) }
diff --git a/spec/requests/api/graphql/mutations/issues/set_subscription_spec.rb b/spec/requests/api/graphql/mutations/issues/set_subscription_spec.rb
index 1edc1e0553b..6c8e5b1d15d 100644
--- a/spec/requests/api/graphql/mutations/issues/set_subscription_spec.rb
+++ b/spec/requests/api/graphql/mutations/issues/set_subscription_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Setting subscribed status of an issue' do
+RSpec.describe 'Setting subscribed status of an issue', feature_category: :team_planning do
include GraphqlHelpers
it_behaves_like 'a subscribable resource api' do
diff --git a/spec/requests/api/graphql/mutations/issues/unlink_alerts_spec.rb b/spec/requests/api/graphql/mutations/issues/unlink_alerts_spec.rb
new file mode 100644
index 00000000000..7f6f968b1dd
--- /dev/null
+++ b/spec/requests/api/graphql/mutations/issues/unlink_alerts_spec.rb
@@ -0,0 +1,89 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'Unlink alert from an incident', feature_category: :incident_management do
+ include GraphqlHelpers
+
+ let_it_be(:user) { create(:user) }
+ let_it_be(:project) { create(:project) }
+ let_it_be(:another_project) { create(:project) }
+ let_it_be(:internal_alert) { create(:alert_management_alert, project: project) }
+ let_it_be(:external_alert) { create(:alert_management_alert, project: another_project) }
+ let_it_be(:incident) do
+ create(:incident, project: project, alert_management_alerts: [internal_alert, external_alert])
+ end
+
+ let(:mutation) do
+ variables = {
+ project_path: project.full_path,
+ iid: incident.iid.to_s,
+ alert_id: alert_to_unlink.to_global_id.to_s
+ }
+
+ graphql_mutation(:issue_unlink_alert, variables,
+ <<-QL.strip_heredoc
+ clientMutationId
+ errors
+ issue {
+ iid
+ alertManagementAlerts {
+ nodes {
+ id
+ }
+ }
+ }
+ QL
+ )
+ end
+
+ def mutation_response
+ graphql_mutation_response(:issue_unlink_alert)
+ end
+
+ context 'when the user is not allowed to update the incident' do
+ let(:alert_to_unlink) { internal_alert }
+
+ it 'returns an error' do
+ error = Gitlab::Graphql::Authorize::AuthorizeResource::RESOURCE_ACCESS_ERROR
+ post_graphql_mutation(mutation, current_user: user)
+
+ expect(response).to have_gitlab_http_status(:success)
+ expect(graphql_errors).to include(a_hash_including('message' => error))
+ end
+ end
+
+ context 'when the user is allowed to update the incident' do
+ before_all do
+ project.add_developer(user)
+ end
+
+ shared_examples 'unlinking' do
+ it 'unlinks the alert from the incident', :aggregate_failures do
+ post_graphql_mutation(mutation, current_user: user)
+
+ expect(response).to have_gitlab_http_status(:success)
+ expected_response = visible_remainded_alerts.map { |a| { 'id' => a.to_global_id.to_s } }
+ expect(mutation_response.dig('issue', 'alertManagementAlerts', 'nodes')).to match_array(expected_response)
+
+ expect(incident.reload.alert_management_alerts).to match_array(actual_remainded_alerts)
+ end
+ end
+
+ context 'when the alert is internal' do
+ let(:alert_to_unlink) { internal_alert }
+ let(:actual_remainded_alerts) { [external_alert] }
+ let(:visible_remainded_alerts) { [] } # The user cannot fetch external alerts without reading permissions
+
+ it_behaves_like 'unlinking'
+ end
+
+ context 'when the alert is external' do
+ let(:alert_to_unlink) { external_alert }
+ let(:actual_remainded_alerts) { [internal_alert] }
+ let(:visible_remainded_alerts) { [internal_alert] }
+
+ it_behaves_like 'unlinking'
+ end
+ end
+end
diff --git a/spec/requests/api/graphql/mutations/issues/update_spec.rb b/spec/requests/api/graphql/mutations/issues/update_spec.rb
index f38deb426b1..e51c057c182 100644
--- a/spec/requests/api/graphql/mutations/issues/update_spec.rb
+++ b/spec/requests/api/graphql/mutations/issues/update_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Update of an existing issue' do
+RSpec.describe 'Update of an existing issue', feature_category: :team_planning do
include GraphqlHelpers
let_it_be(:current_user) { create(:user) }
diff --git a/spec/requests/api/graphql/mutations/jira_import/import_users_spec.rb b/spec/requests/api/graphql/mutations/jira_import/import_users_spec.rb
index b438e1ba881..ab15aa97680 100644
--- a/spec/requests/api/graphql/mutations/jira_import/import_users_spec.rb
+++ b/spec/requests/api/graphql/mutations/jira_import/import_users_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Importing Jira Users' do
+RSpec.describe 'Importing Jira Users', feature_category: :integrations do
include JiraIntegrationHelpers
include GraphqlHelpers
diff --git a/spec/requests/api/graphql/mutations/jira_import/start_spec.rb b/spec/requests/api/graphql/mutations/jira_import/start_spec.rb
index 1508ba31e37..a864bc88afc 100644
--- a/spec/requests/api/graphql/mutations/jira_import/start_spec.rb
+++ b/spec/requests/api/graphql/mutations/jira_import/start_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Starting a Jira Import' do
+RSpec.describe 'Starting a Jira Import', feature_category: :integrations do
include JiraIntegrationHelpers
include GraphqlHelpers
diff --git a/spec/requests/api/graphql/mutations/labels/create_spec.rb b/spec/requests/api/graphql/mutations/labels/create_spec.rb
index d19411f6c1d..607e20af977 100644
--- a/spec/requests/api/graphql/mutations/labels/create_spec.rb
+++ b/spec/requests/api/graphql/mutations/labels/create_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Mutations::Labels::Create do
+RSpec.describe Mutations::Labels::Create, feature_category: :team_planning do
include GraphqlHelpers
let_it_be(:current_user) { create(:user) }
diff --git a/spec/requests/api/graphql/mutations/merge_requests/create_spec.rb b/spec/requests/api/graphql/mutations/merge_requests/create_spec.rb
index 3a4508489a1..c954fd50cc4 100644
--- a/spec/requests/api/graphql/mutations/merge_requests/create_spec.rb
+++ b/spec/requests/api/graphql/mutations/merge_requests/create_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Creation of a new merge request' do
+RSpec.describe 'Creation of a new merge request', feature_category: :code_review do
include GraphqlHelpers
let_it_be(:current_user) { create(:user) }
diff --git a/spec/requests/api/graphql/mutations/merge_requests/reviewer_rereview_spec.rb b/spec/requests/api/graphql/mutations/merge_requests/reviewer_rereview_spec.rb
index 2e4f35cbcde..c41161eff2b 100644
--- a/spec/requests/api/graphql/mutations/merge_requests/reviewer_rereview_spec.rb
+++ b/spec/requests/api/graphql/mutations/merge_requests/reviewer_rereview_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Setting assignees of a merge request' do
+RSpec.describe 'Setting assignees of a merge request', feature_category: :code_review do
include GraphqlHelpers
let(:current_user) { create(:user) }
diff --git a/spec/requests/api/graphql/mutations/merge_requests/set_assignees_spec.rb b/spec/requests/api/graphql/mutations/merge_requests/set_assignees_spec.rb
index 8cec5867aca..364d13291db 100644
--- a/spec/requests/api/graphql/mutations/merge_requests/set_assignees_spec.rb
+++ b/spec/requests/api/graphql/mutations/merge_requests/set_assignees_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Setting assignees of a merge request', :assume_throttled do
+RSpec.describe 'Setting assignees of a merge request', :assume_throttled, feature_category: :code_review do
include GraphqlHelpers
let_it_be(:project) { create(:project, :repository) }
diff --git a/spec/requests/api/graphql/mutations/merge_requests/set_draft_spec.rb b/spec/requests/api/graphql/mutations/merge_requests/set_draft_spec.rb
index bea2365eaa6..b48a94fbeb9 100644
--- a/spec/requests/api/graphql/mutations/merge_requests/set_draft_spec.rb
+++ b/spec/requests/api/graphql/mutations/merge_requests/set_draft_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Setting Draft status of a merge request' do
+RSpec.describe 'Setting Draft status of a merge request', feature_category: :code_review do
include GraphqlHelpers
let(:current_user) { create(:user) }
@@ -64,7 +64,7 @@ RSpec.describe 'Setting Draft status of a merge request' do
post_graphql_mutation(mutation, current_user: current_user)
expect(response).to have_gitlab_http_status(:success)
- expect(mutation_response['mergeRequest']['title']).not_to start_with(/draft\:/)
+ expect(mutation_response['mergeRequest']['title']).not_to start_with(/draft:/)
end
it 'unmarks the merge request as `Draft`' do
diff --git a/spec/requests/api/graphql/mutations/merge_requests/set_locked_spec.rb b/spec/requests/api/graphql/mutations/merge_requests/set_locked_spec.rb
index a1a35bc1dcc..d88982c508c 100644
--- a/spec/requests/api/graphql/mutations/merge_requests/set_locked_spec.rb
+++ b/spec/requests/api/graphql/mutations/merge_requests/set_locked_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Setting locked status of a merge request' do
+RSpec.describe 'Setting locked status of a merge request', feature_category: :code_review do
include GraphqlHelpers
let(:current_user) { create(:user) }
diff --git a/spec/requests/api/graphql/mutations/merge_requests/set_milestone_spec.rb b/spec/requests/api/graphql/mutations/merge_requests/set_milestone_spec.rb
index d7e2602bd0a..a0f0e45d1fc 100644
--- a/spec/requests/api/graphql/mutations/merge_requests/set_milestone_spec.rb
+++ b/spec/requests/api/graphql/mutations/merge_requests/set_milestone_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Setting milestone of a merge request' do
+RSpec.describe 'Setting milestone of a merge request', feature_category: :code_review do
include GraphqlHelpers
let(:current_user) { create(:user) }
diff --git a/spec/requests/api/graphql/mutations/merge_requests/set_reviewers_spec.rb b/spec/requests/api/graphql/mutations/merge_requests/set_reviewers_spec.rb
index be786256ef2..a5be2a95c8b 100644
--- a/spec/requests/api/graphql/mutations/merge_requests/set_reviewers_spec.rb
+++ b/spec/requests/api/graphql/mutations/merge_requests/set_reviewers_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Setting reviewers of a merge request', :assume_throttled do
+RSpec.describe 'Setting reviewers of a merge request', :assume_throttled, feature_category: :code_review do
include GraphqlHelpers
let_it_be(:project) { create(:project, :repository) }
diff --git a/spec/requests/api/graphql/mutations/merge_requests/set_subscription_spec.rb b/spec/requests/api/graphql/mutations/merge_requests/set_subscription_spec.rb
index d90faa605c0..daf1f529847 100644
--- a/spec/requests/api/graphql/mutations/merge_requests/set_subscription_spec.rb
+++ b/spec/requests/api/graphql/mutations/merge_requests/set_subscription_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Setting subscribed status of a merge request' do
+RSpec.describe 'Setting subscribed status of a merge request', feature_category: :code_review do
include GraphqlHelpers
it_behaves_like 'a subscribable resource api' do
diff --git a/spec/requests/api/graphql/mutations/metrics/dashboard/annotations/create_spec.rb b/spec/requests/api/graphql/mutations/metrics/dashboard/annotations/create_spec.rb
index 9ef443af76a..bce57b47aab 100644
--- a/spec/requests/api/graphql/mutations/metrics/dashboard/annotations/create_spec.rb
+++ b/spec/requests/api/graphql/mutations/metrics/dashboard/annotations/create_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Mutations::Metrics::Dashboard::Annotations::Create do
+RSpec.describe Mutations::Metrics::Dashboard::Annotations::Create, feature_category: :metrics do
include GraphqlHelpers
let_it_be(:current_user) { create(:user) }
diff --git a/spec/requests/api/graphql/mutations/metrics/dashboard/annotations/delete_spec.rb b/spec/requests/api/graphql/mutations/metrics/dashboard/annotations/delete_spec.rb
index b956734068c..f505dc25dc0 100644
--- a/spec/requests/api/graphql/mutations/metrics/dashboard/annotations/delete_spec.rb
+++ b/spec/requests/api/graphql/mutations/metrics/dashboard/annotations/delete_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Mutations::Metrics::Dashboard::Annotations::Delete do
+RSpec.describe Mutations::Metrics::Dashboard::Annotations::Delete, feature_category: :metrics do
include GraphqlHelpers
let_it_be(:current_user) { create(:user) }
diff --git a/spec/requests/api/graphql/mutations/namespace/package_settings/update_spec.rb b/spec/requests/api/graphql/mutations/namespace/package_settings/update_spec.rb
index 567d8799d93..f4f4f34fe29 100644
--- a/spec/requests/api/graphql/mutations/namespace/package_settings/update_spec.rb
+++ b/spec/requests/api/graphql/mutations/namespace/package_settings/update_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Updating the package settings' do
+RSpec.describe 'Updating the package settings', feature_category: :package_registry do
include GraphqlHelpers
using RSpec::Parameterized::TableSyntax
diff --git a/spec/requests/api/graphql/mutations/notes/create/diff_note_spec.rb b/spec/requests/api/graphql/mutations/notes/create/diff_note_spec.rb
index a432fb17a70..3cf78230a4c 100644
--- a/spec/requests/api/graphql/mutations/notes/create/diff_note_spec.rb
+++ b/spec/requests/api/graphql/mutations/notes/create/diff_note_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Adding a DiffNote' do
+RSpec.describe 'Adding a DiffNote', feature_category: :team_planning do
include GraphqlHelpers
let_it_be(:current_user) { create(:user) }
diff --git a/spec/requests/api/graphql/mutations/notes/create/image_diff_note_spec.rb b/spec/requests/api/graphql/mutations/notes/create/image_diff_note_spec.rb
index 8f2438cb741..0ce239d9ca5 100644
--- a/spec/requests/api/graphql/mutations/notes/create/image_diff_note_spec.rb
+++ b/spec/requests/api/graphql/mutations/notes/create/image_diff_note_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Adding an image DiffNote' do
+RSpec.describe 'Adding an image DiffNote', feature_category: :team_planning do
include GraphqlHelpers
let_it_be(:current_user) { create(:user) }
diff --git a/spec/requests/api/graphql/mutations/notes/create/note_spec.rb b/spec/requests/api/graphql/mutations/notes/create/note_spec.rb
index 9c3842db31a..00e25909746 100644
--- a/spec/requests/api/graphql/mutations/notes/create/note_spec.rb
+++ b/spec/requests/api/graphql/mutations/notes/create/note_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Adding a Note' do
+RSpec.describe 'Adding a Note', feature_category: :team_planning do
include GraphqlHelpers
let_it_be(:current_user) { create(:user) }
@@ -102,6 +102,35 @@ RSpec.describe 'Adding a Note' do
it_behaves_like 'a Note mutation with confidential notes'
end
+
+ context 'as work item' do
+ let(:noteable) { create(:work_item, :issue, project: project) }
+
+ context 'when using internal param' do
+ let(:variables_extra) { { internal: true } }
+
+ it_behaves_like 'a Note mutation with confidential notes'
+ end
+
+ context 'when using deprecated confidential param' do
+ let(:variables_extra) { { confidential: true } }
+
+ it_behaves_like 'a Note mutation with confidential notes'
+ end
+
+ context 'without notes widget' do
+ let(:variables_extra) { {} }
+
+ before do
+ stub_const('WorkItems::Type::BASE_TYPES', { issue: { name: 'NoNotesWidget', enum_value: 0 } })
+ stub_const('WorkItems::Type::WIDGETS_FOR_TYPE', { issue: [::WorkItems::Widgets::Description] })
+ end
+
+ it_behaves_like 'a Note mutation that does not create a Note'
+ it_behaves_like 'a mutation that returns top-level errors',
+ errors: [Gitlab::Graphql::Authorize::AuthorizeResource::RESOURCE_ACCESS_ERROR]
+ end
+ end
end
context 'when body only contains quick actions' do
diff --git a/spec/requests/api/graphql/mutations/notes/destroy_spec.rb b/spec/requests/api/graphql/mutations/notes/destroy_spec.rb
index 49f09fadfea..eb45e2aa033 100644
--- a/spec/requests/api/graphql/mutations/notes/destroy_spec.rb
+++ b/spec/requests/api/graphql/mutations/notes/destroy_spec.rb
@@ -2,17 +2,14 @@
require 'spec_helper'
-RSpec.describe 'Destroying a Note' do
+RSpec.describe 'Destroying a Note', feature_category: :team_planning do
include GraphqlHelpers
- let!(:note) { create(:note) }
- let(:mutation) do
- variables = {
- id: GitlabSchema.id_from_object(note).to_s
- }
-
- graphql_mutation(:destroy_note, variables)
- end
+ let(:noteable) { create(:work_item, :issue) }
+ let!(:note) { create(:note, noteable: noteable, project: noteable.project) }
+ let(:global_note_id) { GitlabSchema.id_from_object(note).to_s }
+ let(:variables) { { id: global_note_id } }
+ let(:mutation) { graphql_mutation(:destroy_note, variables) }
def mutation_response
graphql_mutation_response(:destroy_note)
@@ -47,5 +44,31 @@ RSpec.describe 'Destroying a Note' do
expect(mutation_response).to have_key('note')
expect(mutation_response['note']).to be_nil
end
+
+ context 'when note is system' do
+ let!(:note) { create(:note, :system) }
+
+ it 'does not destroy system note' do
+ expect do
+ post_graphql_mutation(mutation, current_user: current_user)
+ end.not_to change { Note.count }
+ end
+ end
+
+ context 'without notes widget' do
+ before do
+ stub_const('WorkItems::Type::BASE_TYPES', { issue: { name: 'NoNotesWidget', enum_value: 0 } })
+ stub_const('WorkItems::Type::WIDGETS_FOR_TYPE', { issue: [::WorkItems::Widgets::Description] })
+ end
+
+ it 'does not update the Note' do
+ expect do
+ post_graphql_mutation(mutation, current_user: current_user)
+ end.to not_change { Note.count }
+ end
+
+ it_behaves_like 'a mutation that returns top-level errors',
+ errors: [Gitlab::Graphql::Authorize::AuthorizeResource::RESOURCE_ACCESS_ERROR]
+ end
end
end
diff --git a/spec/requests/api/graphql/mutations/notes/reposition_image_diff_note_spec.rb b/spec/requests/api/graphql/mutations/notes/reposition_image_diff_note_spec.rb
index c4674155aa0..e9cd27a1e20 100644
--- a/spec/requests/api/graphql/mutations/notes/reposition_image_diff_note_spec.rb
+++ b/spec/requests/api/graphql/mutations/notes/reposition_image_diff_note_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Repositioning an ImageDiffNote' do
+RSpec.describe 'Repositioning an ImageDiffNote', feature_category: :team_planning do
include GraphqlHelpers
let_it_be(:noteable) { create(:merge_request) }
diff --git a/spec/requests/api/graphql/mutations/notes/update/image_diff_note_spec.rb b/spec/requests/api/graphql/mutations/notes/update/image_diff_note_spec.rb
index cfd0b34b815..a5cd3c8b019 100644
--- a/spec/requests/api/graphql/mutations/notes/update/image_diff_note_spec.rb
+++ b/spec/requests/api/graphql/mutations/notes/update/image_diff_note_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Updating an image DiffNote' do
+RSpec.describe 'Updating an image DiffNote', feature_category: :team_planning do
include GraphqlHelpers
using RSpec::Parameterized::TableSyntax
diff --git a/spec/requests/api/graphql/mutations/notes/update/note_spec.rb b/spec/requests/api/graphql/mutations/notes/update/note_spec.rb
index bae5c58abff..dff8a87314b 100644
--- a/spec/requests/api/graphql/mutations/notes/update/note_spec.rb
+++ b/spec/requests/api/graphql/mutations/notes/update/note_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Updating a Note' do
+RSpec.describe 'Updating a Note', feature_category: :team_planning do
include GraphqlHelpers
let!(:note) { create(:note, note: original_body) }
@@ -36,49 +36,32 @@ RSpec.describe 'Updating a Note' do
it_behaves_like 'a Note mutation when the given resource id is not for a Note'
- it 'updates the Note' do
- post_graphql_mutation(mutation, current_user: current_user)
-
- expect(note.reload.note).to eq(updated_body)
- end
-
- it 'returns the updated Note' do
- post_graphql_mutation(mutation, current_user: current_user)
-
- expect(mutation_response['note']['body']).to eq(updated_body)
- end
+ it_behaves_like 'a Note mutation updates a note successfully'
+ it_behaves_like 'a Note mutation update with errors'
+ it_behaves_like 'a Note mutation update only with quick actions'
- context 'when there are ActiveRecord validation errors' do
- let(:params) { { body: '', confidential: true } }
+ context 'for work item' do
+ let(:noteable) { create(:work_item, :issue) }
+ let(:note) { create(:note, noteable: noteable, project: noteable.project, note: original_body) }
- it_behaves_like 'a mutation that returns errors in the response',
- errors: ["Note can't be blank", 'Confidential can not be changed for existing notes']
+ it_behaves_like 'a Note mutation updates a note successfully'
+ it_behaves_like 'a Note mutation update with errors'
+ it_behaves_like 'a Note mutation update only with quick actions'
- it 'does not update the Note' do
- post_graphql_mutation(mutation, current_user: current_user)
-
- expect(note.reload.note).to eq(original_body)
- expect(note.confidential).to be_falsey
- end
-
- it 'returns the original Note' do
- post_graphql_mutation(mutation, current_user: current_user)
-
- expect(mutation_response['note']['body']).to eq(original_body)
- expect(mutation_response['note']['confidential']).to be_falsey
- end
- end
+ context 'without notes widget' do
+ before do
+ stub_const('WorkItems::Type::BASE_TYPES', { issue: { name: 'NoNotesWidget', enum_value: 0 } })
+ stub_const('WorkItems::Type::WIDGETS_FOR_TYPE', { issue: [::WorkItems::Widgets::Description] })
+ end
- context 'when body only contains quick actions' do
- let(:updated_body) { '/close' }
+ it 'does not update the Note' do
+ post_graphql_mutation(mutation, current_user: current_user)
- it 'returns a nil note and empty errors' do
- post_graphql_mutation(mutation, current_user: current_user)
+ expect(note.reload.note).to eq(original_body)
+ end
- expect(mutation_response).to include(
- 'errors' => [],
- 'note' => nil
- )
+ it_behaves_like 'a mutation that returns top-level errors',
+ errors: [Gitlab::Graphql::Authorize::AuthorizeResource::RESOURCE_ACCESS_ERROR]
end
end
end
diff --git a/spec/requests/api/graphql/mutations/packages/bulk_destroy_spec.rb b/spec/requests/api/graphql/mutations/packages/bulk_destroy_spec.rb
index 1fe01af4f1c..d0980a2b43d 100644
--- a/spec/requests/api/graphql/mutations/packages/bulk_destroy_spec.rb
+++ b/spec/requests/api/graphql/mutations/packages/bulk_destroy_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Destroying multiple packages' do
+RSpec.describe 'Destroying multiple packages', feature_category: :package_registry do
using RSpec::Parameterized::TableSyntax
include GraphqlHelpers
diff --git a/spec/requests/api/graphql/mutations/packages/cleanup/policy/update_spec.rb b/spec/requests/api/graphql/mutations/packages/cleanup/policy/update_spec.rb
index 7e00f3ca53a..2540e06be9a 100644
--- a/spec/requests/api/graphql/mutations/packages/cleanup/policy/update_spec.rb
+++ b/spec/requests/api/graphql/mutations/packages/cleanup/policy/update_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Updating the packages cleanup policy' do
+RSpec.describe 'Updating the packages cleanup policy', feature_category: :package_registry do
include GraphqlHelpers
using RSpec::Parameterized::TableSyntax
diff --git a/spec/requests/api/graphql/mutations/packages/destroy_file_spec.rb b/spec/requests/api/graphql/mutations/packages/destroy_file_spec.rb
index cd25aba9e00..a4b7001fdd5 100644
--- a/spec/requests/api/graphql/mutations/packages/destroy_file_spec.rb
+++ b/spec/requests/api/graphql/mutations/packages/destroy_file_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Destroying a package file' do
+RSpec.describe 'Destroying a package file', feature_category: :package_registry do
using RSpec::Parameterized::TableSyntax
include GraphqlHelpers
diff --git a/spec/requests/api/graphql/mutations/packages/destroy_files_spec.rb b/spec/requests/api/graphql/mutations/packages/destroy_files_spec.rb
index 002cd634ebd..cdd05d80fc2 100644
--- a/spec/requests/api/graphql/mutations/packages/destroy_files_spec.rb
+++ b/spec/requests/api/graphql/mutations/packages/destroy_files_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Destroying multiple package files' do
+RSpec.describe 'Destroying multiple package files', feature_category: :package_registry do
using RSpec::Parameterized::TableSyntax
include GraphqlHelpers
diff --git a/spec/requests/api/graphql/mutations/packages/destroy_spec.rb b/spec/requests/api/graphql/mutations/packages/destroy_spec.rb
index 2340a6a36d8..86167e7116f 100644
--- a/spec/requests/api/graphql/mutations/packages/destroy_spec.rb
+++ b/spec/requests/api/graphql/mutations/packages/destroy_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Destroying a package' do
+RSpec.describe 'Destroying a package', feature_category: :package_registry do
using RSpec::Parameterized::TableSyntax
include GraphqlHelpers
diff --git a/spec/requests/api/graphql/mutations/release_asset_links/create_spec.rb b/spec/requests/api/graphql/mutations/release_asset_links/create_spec.rb
index c7a4cb1ebce..418a0e47a36 100644
--- a/spec/requests/api/graphql/mutations/release_asset_links/create_spec.rb
+++ b/spec/requests/api/graphql/mutations/release_asset_links/create_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Creation of a new release asset link' do
+RSpec.describe 'Creation of a new release asset link', feature_category: :release_orchestration do
include GraphqlHelpers
let_it_be(:project) { create(:project, :private, :repository) }
diff --git a/spec/requests/api/graphql/mutations/release_asset_links/delete_spec.rb b/spec/requests/api/graphql/mutations/release_asset_links/delete_spec.rb
index 57489c82ec2..b6d2c3f691d 100644
--- a/spec/requests/api/graphql/mutations/release_asset_links/delete_spec.rb
+++ b/spec/requests/api/graphql/mutations/release_asset_links/delete_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Deletes a release asset link' do
+RSpec.describe 'Deletes a release asset link', feature_category: :release_orchestration do
include GraphqlHelpers
let_it_be(:project) { create(:project, :private, :repository) }
diff --git a/spec/requests/api/graphql/mutations/release_asset_links/update_spec.rb b/spec/requests/api/graphql/mutations/release_asset_links/update_spec.rb
index 92b558d4be3..61395cc4042 100644
--- a/spec/requests/api/graphql/mutations/release_asset_links/update_spec.rb
+++ b/spec/requests/api/graphql/mutations/release_asset_links/update_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Updating an existing release asset link' do
+RSpec.describe 'Updating an existing release asset link', feature_category: :release_orchestration do
include GraphqlHelpers
let_it_be(:project) { create(:project, :private, :repository) }
diff --git a/spec/requests/api/graphql/mutations/releases/create_spec.rb b/spec/requests/api/graphql/mutations/releases/create_spec.rb
index 2541072b766..295b8c0e97e 100644
--- a/spec/requests/api/graphql/mutations/releases/create_spec.rb
+++ b/spec/requests/api/graphql/mutations/releases/create_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Creation of a new release' do
+RSpec.describe 'Creation of a new release', feature_category: :release_orchestration do
include GraphqlHelpers
include Presentable
diff --git a/spec/requests/api/graphql/mutations/releases/delete_spec.rb b/spec/requests/api/graphql/mutations/releases/delete_spec.rb
index eb4f0b594ea..bb398787cc6 100644
--- a/spec/requests/api/graphql/mutations/releases/delete_spec.rb
+++ b/spec/requests/api/graphql/mutations/releases/delete_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Deleting a release' do
+RSpec.describe 'Deleting a release', feature_category: :release_orchestration do
include GraphqlHelpers
include Presentable
diff --git a/spec/requests/api/graphql/mutations/releases/update_spec.rb b/spec/requests/api/graphql/mutations/releases/update_spec.rb
index 240db764f40..2b88576a70e 100644
--- a/spec/requests/api/graphql/mutations/releases/update_spec.rb
+++ b/spec/requests/api/graphql/mutations/releases/update_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Updating an existing release' do
+RSpec.describe 'Updating an existing release', feature_category: :release_orchestration do
include GraphqlHelpers
include Presentable
diff --git a/spec/requests/api/graphql/mutations/security/ci_configuration/configure_sast_iac_spec.rb b/spec/requests/api/graphql/mutations/security/ci_configuration/configure_sast_iac_spec.rb
index 0c034f38dc8..cdd25f8f6ec 100644
--- a/spec/requests/api/graphql/mutations/security/ci_configuration/configure_sast_iac_spec.rb
+++ b/spec/requests/api/graphql/mutations/security/ci_configuration/configure_sast_iac_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'ConfigureSastIac' do
+RSpec.describe 'ConfigureSastIac', feature_category: :static_application_security_testing do
include GraphqlHelpers
let_it_be(:project) { create(:project, :test_repo) }
diff --git a/spec/requests/api/graphql/mutations/security/ci_configuration/configure_secret_detection_spec.rb b/spec/requests/api/graphql/mutations/security/ci_configuration/configure_secret_detection_spec.rb
index 8fa6e44b208..370abf2fe00 100644
--- a/spec/requests/api/graphql/mutations/security/ci_configuration/configure_secret_detection_spec.rb
+++ b/spec/requests/api/graphql/mutations/security/ci_configuration/configure_secret_detection_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'ConfigureSecretDetection' do
+RSpec.describe 'ConfigureSecretDetection', feature_category: :secret_detection do
include GraphqlHelpers
let_it_be(:project) { create(:project, :test_repo) }
diff --git a/spec/requests/api/graphql/mutations/snippets/create_spec.rb b/spec/requests/api/graphql/mutations/snippets/create_spec.rb
index 264fa5732c3..0b1af2bf628 100644
--- a/spec/requests/api/graphql/mutations/snippets/create_spec.rb
+++ b/spec/requests/api/graphql/mutations/snippets/create_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Creating a Snippet' do
+RSpec.describe 'Creating a Snippet', feature_category: :source_code_management do
include GraphqlHelpers
let_it_be(:user) { create(:user) }
diff --git a/spec/requests/api/graphql/mutations/snippets/destroy_spec.rb b/spec/requests/api/graphql/mutations/snippets/destroy_spec.rb
index 1be8ce142ac..09e884d9412 100644
--- a/spec/requests/api/graphql/mutations/snippets/destroy_spec.rb
+++ b/spec/requests/api/graphql/mutations/snippets/destroy_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Destroying a Snippet' do
+RSpec.describe 'Destroying a Snippet', feature_category: :source_code_management do
include GraphqlHelpers
let(:current_user) { snippet.author }
diff --git a/spec/requests/api/graphql/mutations/snippets/mark_as_spam_spec.rb b/spec/requests/api/graphql/mutations/snippets/mark_as_spam_spec.rb
index 77fd6cddc09..9a8c027da8a 100644
--- a/spec/requests/api/graphql/mutations/snippets/mark_as_spam_spec.rb
+++ b/spec/requests/api/graphql/mutations/snippets/mark_as_spam_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Mark snippet as spam' do
+RSpec.describe 'Mark snippet as spam', feature_category: :source_code_management do
include GraphqlHelpers
include AfterNextHelpers
diff --git a/spec/requests/api/graphql/mutations/snippets/update_spec.rb b/spec/requests/api/graphql/mutations/snippets/update_spec.rb
index 1a5d3620f22..fa087e6773c 100644
--- a/spec/requests/api/graphql/mutations/snippets/update_spec.rb
+++ b/spec/requests/api/graphql/mutations/snippets/update_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Updating a Snippet' do
+RSpec.describe 'Updating a Snippet', feature_category: :source_code_management do
include GraphqlHelpers
include SessionHelpers
@@ -192,11 +192,18 @@ RSpec.describe 'Updating a Snippet' do
stub_session('warden.user.user.key' => [[current_user.id], current_user.authenticatable_salt])
end
- it_behaves_like 'Snowplow event tracking' do
+ it_behaves_like 'Snowplow event tracking with RedisHLL context' do
+ let(:feature_flag_name) { :route_hll_to_snowplow_phase2 }
let(:user) { current_user }
+ let(:property) { 'g_edit_by_snippet_ide' }
let(:namespace) { project.namespace }
- let(:category) { 'ide_edit' }
- let(:action) { 'g_edit_by_snippet_ide' }
+ let(:category) { 'Gitlab::UsageDataCounters::EditorUniqueCounter' }
+ let(:action) { 'ide_edit' }
+ let(:label) { 'usage_activity_by_stage_monthly.create.action_monthly_active_users_ide_edit' }
+ let(:context) do
+ [Gitlab::Tracking::ServicePingContext.new(data_source: :redis_hll, event: event_name).to_context]
+ end
+
let(:feature_flag_name) { :route_hll_to_snowplow_phase2 }
end
end
diff --git a/spec/requests/api/graphql/mutations/timelogs/create_spec.rb b/spec/requests/api/graphql/mutations/timelogs/create_spec.rb
index eea04b89783..42249818a92 100644
--- a/spec/requests/api/graphql/mutations/timelogs/create_spec.rb
+++ b/spec/requests/api/graphql/mutations/timelogs/create_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Create a timelog' do
+RSpec.describe 'Create a timelog', feature_category: :team_planning do
include GraphqlHelpers
let_it_be(:author) { create(:user) }
@@ -11,14 +11,6 @@ RSpec.describe 'Create a timelog' do
let(:current_user) { nil }
let(:users_container) { project }
- let(:mutation) do
- graphql_mutation(:timelogCreate, {
- 'time_spent' => time_spent,
- 'spent_at' => '2022-07-08',
- 'summary' => 'Test summary',
- 'issuable_id' => issuable.to_global_id.to_s
- })
- end
let(:mutation_response) { graphql_mutation_response(:timelog_create) }
diff --git a/spec/requests/api/graphql/mutations/timelogs/delete_spec.rb b/spec/requests/api/graphql/mutations/timelogs/delete_spec.rb
index d304bfbdf00..d04b4d193e6 100644
--- a/spec/requests/api/graphql/mutations/timelogs/delete_spec.rb
+++ b/spec/requests/api/graphql/mutations/timelogs/delete_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Delete a timelog' do
+RSpec.describe 'Delete a timelog', feature_category: :team_planning do
include GraphqlHelpers
let_it_be(:author) { create(:user) }
let_it_be(:project) { create(:project, :public) }
diff --git a/spec/requests/api/graphql/mutations/todos/create_spec.rb b/spec/requests/api/graphql/mutations/todos/create_spec.rb
index aca00519682..5d7ecb3c927 100644
--- a/spec/requests/api/graphql/mutations/todos/create_spec.rb
+++ b/spec/requests/api/graphql/mutations/todos/create_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Create a todo' do
+RSpec.describe 'Create a todo', feature_category: :team_planning do
include GraphqlHelpers
let_it_be(:current_user) { create(:user) }
diff --git a/spec/requests/api/graphql/mutations/todos/mark_all_done_spec.rb b/spec/requests/api/graphql/mutations/todos/mark_all_done_spec.rb
index dc20fde8e3c..c611c6ee2a1 100644
--- a/spec/requests/api/graphql/mutations/todos/mark_all_done_spec.rb
+++ b/spec/requests/api/graphql/mutations/todos/mark_all_done_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Marking all todos done' do
+RSpec.describe 'Marking all todos done', feature_category: :team_planning do
include GraphqlHelpers
let_it_be(:project) { create(:project) }
diff --git a/spec/requests/api/graphql/mutations/todos/mark_done_spec.rb b/spec/requests/api/graphql/mutations/todos/mark_done_spec.rb
index 7f5ea71c760..60700d8024c 100644
--- a/spec/requests/api/graphql/mutations/todos/mark_done_spec.rb
+++ b/spec/requests/api/graphql/mutations/todos/mark_done_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Marking todos done' do
+RSpec.describe 'Marking todos done', feature_category: :team_planning do
include GraphqlHelpers
let_it_be(:project) { create(:project) }
diff --git a/spec/requests/api/graphql/mutations/todos/restore_many_spec.rb b/spec/requests/api/graphql/mutations/todos/restore_many_spec.rb
index 4316bd060c1..9daa243cf8e 100644
--- a/spec/requests/api/graphql/mutations/todos/restore_many_spec.rb
+++ b/spec/requests/api/graphql/mutations/todos/restore_many_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Restoring many Todos' do
+RSpec.describe 'Restoring many Todos', feature_category: :team_planning do
include GraphqlHelpers
let_it_be(:project) { create(:project) }
diff --git a/spec/requests/api/graphql/mutations/todos/restore_spec.rb b/spec/requests/api/graphql/mutations/todos/restore_spec.rb
index d995191c97e..868298763ec 100644
--- a/spec/requests/api/graphql/mutations/todos/restore_spec.rb
+++ b/spec/requests/api/graphql/mutations/todos/restore_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Restoring Todos' do
+RSpec.describe 'Restoring Todos', feature_category: :team_planning do
include GraphqlHelpers
let_it_be(:project) { create(:project) }
diff --git a/spec/requests/api/graphql/mutations/uploads/delete_spec.rb b/spec/requests/api/graphql/mutations/uploads/delete_spec.rb
index 2d1b33cc086..08dbbe23b6b 100644
--- a/spec/requests/api/graphql/mutations/uploads/delete_spec.rb
+++ b/spec/requests/api/graphql/mutations/uploads/delete_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Delete an upload' do
+RSpec.describe 'Delete an upload', feature_category: :navigation do
include GraphqlHelpers
let_it_be(:group) { create(:group) }
diff --git a/spec/requests/api/graphql/mutations/user_callouts/create_spec.rb b/spec/requests/api/graphql/mutations/user_callouts/create_spec.rb
index 28a46583d2a..eb35d310760 100644
--- a/spec/requests/api/graphql/mutations/user_callouts/create_spec.rb
+++ b/spec/requests/api/graphql/mutations/user_callouts/create_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Create a user callout' do
+RSpec.describe 'Create a user callout', feature_category: :navigation do
include GraphqlHelpers
let_it_be(:current_user) { create(:user) }
diff --git a/spec/requests/api/graphql/mutations/user_preferences/update_spec.rb b/spec/requests/api/graphql/mutations/user_preferences/update_spec.rb
index e1c7fd9d60d..31d17401b9e 100644
--- a/spec/requests/api/graphql/mutations/user_preferences/update_spec.rb
+++ b/spec/requests/api/graphql/mutations/user_preferences/update_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Mutations::UserPreferences::Update do
+RSpec.describe Mutations::UserPreferences::Update, feature_category: :users do
include GraphqlHelpers
let_it_be(:current_user) { create(:user) }
diff --git a/spec/requests/api/graphql/mutations/work_items/create_from_task_spec.rb b/spec/requests/api/graphql/mutations/work_items/create_from_task_spec.rb
index c6a980b5cef..97bf060356a 100644
--- a/spec/requests/api/graphql/mutations/work_items/create_from_task_spec.rb
+++ b/spec/requests/api/graphql/mutations/work_items/create_from_task_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe "Create a work item from a task in a work item's description" do
+RSpec.describe "Create a work item from a task in a work item's description", feature_category: :team_planning do
include GraphqlHelpers
let_it_be(:project) { create(:project) }
diff --git a/spec/requests/api/graphql/mutations/work_items/create_spec.rb b/spec/requests/api/graphql/mutations/work_items/create_spec.rb
index be3917316c3..16f78b67b5c 100644
--- a/spec/requests/api/graphql/mutations/work_items/create_spec.rb
+++ b/spec/requests/api/graphql/mutations/work_items/create_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Create a work item' do
+RSpec.describe 'Create a work item', feature_category: :team_planning do
include GraphqlHelpers
let_it_be(:project) { create(:project) }
@@ -123,7 +123,7 @@ RSpec.describe 'Create a work item' do
post_graphql_mutation(mutation, current_user: current_user)
expect(mutation_response['errors'])
- .to contain_exactly(/cannot be added: only Issue and Incident can be parent of Task./)
+ .to contain_exactly(/cannot be added: is not allowed to add this type of parent/)
expect(mutation_response['workItem']).to be_nil
end
end
diff --git a/spec/requests/api/graphql/mutations/work_items/delete_spec.rb b/spec/requests/api/graphql/mutations/work_items/delete_spec.rb
index 0a84225a7ab..e25ff5613e4 100644
--- a/spec/requests/api/graphql/mutations/work_items/delete_spec.rb
+++ b/spec/requests/api/graphql/mutations/work_items/delete_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Delete a work item' do
+RSpec.describe 'Delete a work item', feature_category: :team_planning do
include GraphqlHelpers
let_it_be(:project) { create(:project) }
diff --git a/spec/requests/api/graphql/mutations/work_items/delete_task_spec.rb b/spec/requests/api/graphql/mutations/work_items/delete_task_spec.rb
index c44939c8d54..b1828de046f 100644
--- a/spec/requests/api/graphql/mutations/work_items/delete_task_spec.rb
+++ b/spec/requests/api/graphql/mutations/work_items/delete_task_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe "Delete a task in a work item's description" do
+RSpec.describe "Delete a task in a work item's description", feature_category: :team_planning do
include GraphqlHelpers
let_it_be(:project) { create(:project) }
diff --git a/spec/requests/api/graphql/mutations/work_items/update_spec.rb b/spec/requests/api/graphql/mutations/work_items/update_spec.rb
index 96736457f26..14cb18d04b8 100644
--- a/spec/requests/api/graphql/mutations/work_items/update_spec.rb
+++ b/spec/requests/api/graphql/mutations/work_items/update_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Update a work item' do
+RSpec.describe 'Update a work item', feature_category: :team_planning do
include GraphqlHelpers
let_it_be(:group) { create(:group) }
@@ -339,7 +339,7 @@ RSpec.describe 'Update a work item' do
let_it_be(:invalid_parent) { create(:work_item, :task, project: project) }
context 'when parent work item type is invalid' do
- let(:error) { "#{work_item.to_reference} cannot be added: only Issue and Incident can be parent of Task." }
+ let(:error) { "#{work_item.to_reference} cannot be added: is not allowed to add this type of parent" }
let(:input) do
{ 'hierarchyWidget' => { 'parentId' => invalid_parent.to_global_id.to_s }, 'title' => 'new title' }
end
@@ -450,7 +450,7 @@ RSpec.describe 'Update a work item' do
let(:input) { { 'hierarchyWidget' => { 'childrenIds' => children_ids } } }
let(:error) do
- "#{invalid_child.to_reference} cannot be added: only Task can be assigned as a child in hierarchy."
+ "#{invalid_child.to_reference} cannot be added: is not allowed to add this type of parent"
end
context 'when child work item type is invalid' do
@@ -632,7 +632,7 @@ RSpec.describe 'Update a work item' do
end
context 'when unsupported widget input is sent' do
- let_it_be(:test_case) { create(:work_item_type, :default, :test_case, name: 'some_test_case_name') }
+ let_it_be(:test_case) { create(:work_item_type, :default, :test_case) }
let_it_be(:work_item) { create(:work_item, work_item_type: test_case, project: project) }
let(:input) do
@@ -642,7 +642,7 @@ RSpec.describe 'Update a work item' do
end
it_behaves_like 'a mutation that returns top-level errors',
- errors: ["Following widget keys are not supported by some_test_case_name type: [:hierarchy_widget]"]
+ errors: ["Following widget keys are not supported by Test Case type: [:hierarchy_widget]"]
end
end
end
diff --git a/spec/requests/api/graphql/mutations/work_items/update_task_spec.rb b/spec/requests/api/graphql/mutations/work_items/update_task_spec.rb
index 55285be5a5d..999c685ac6a 100644
--- a/spec/requests/api/graphql/mutations/work_items/update_task_spec.rb
+++ b/spec/requests/api/graphql/mutations/work_items/update_task_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Update a work item task' do
+RSpec.describe 'Update a work item task', feature_category: :team_planning do
include GraphqlHelpers
let_it_be(:project) { create(:project) }
diff --git a/spec/requests/api/graphql/namespace/package_settings_spec.rb b/spec/requests/api/graphql/namespace/package_settings_spec.rb
index 42fd07dbdc7..bd441032626 100644
--- a/spec/requests/api/graphql/namespace/package_settings_spec.rb
+++ b/spec/requests/api/graphql/namespace/package_settings_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'getting namespace package settings in a namespace' do
+RSpec.describe 'getting namespace package settings in a namespace', feature_category: :package_registry do
include GraphqlHelpers
let_it_be(:package_settings) { create(:namespace_package_setting) }
diff --git a/spec/requests/api/graphql/namespace/projects_spec.rb b/spec/requests/api/graphql/namespace/projects_spec.rb
index d5410f1a7cb..4e12da3e3ab 100644
--- a/spec/requests/api/graphql/namespace/projects_spec.rb
+++ b/spec/requests/api/graphql/namespace/projects_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'getting projects' do
+RSpec.describe 'getting projects', feature_category: :projects do
include GraphqlHelpers
let(:group) { create(:group) }
diff --git a/spec/requests/api/graphql/namespace/root_storage_statistics_spec.rb b/spec/requests/api/graphql/namespace/root_storage_statistics_spec.rb
index 8d8a0baae36..cee698d6dc5 100644
--- a/spec/requests/api/graphql/namespace/root_storage_statistics_spec.rb
+++ b/spec/requests/api/graphql/namespace/root_storage_statistics_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'rendering namespace statistics' do
+RSpec.describe 'rendering namespace statistics', feature_category: :metrics do
include GraphqlHelpers
let(:namespace) { user.namespace }
diff --git a/spec/requests/api/graphql/namespace_query_spec.rb b/spec/requests/api/graphql/namespace_query_spec.rb
index e17469901c6..d12a3875ebf 100644
--- a/spec/requests/api/graphql/namespace_query_spec.rb
+++ b/spec/requests/api/graphql/namespace_query_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Query' do
+RSpec.describe 'Query', feature_category: :subgroups do
include GraphqlHelpers
let_it_be(:user) { create(:user) }
diff --git a/spec/requests/api/graphql/packages/composer_spec.rb b/spec/requests/api/graphql/packages/composer_spec.rb
index 89c01d44771..dd61582b055 100644
--- a/spec/requests/api/graphql/packages/composer_spec.rb
+++ b/spec/requests/api/graphql/packages/composer_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
require 'spec_helper'
-RSpec.describe 'package details' do
+RSpec.describe 'package details', feature_category: :package_registry do
include GraphqlHelpers
include_context 'package details setup'
diff --git a/spec/requests/api/graphql/packages/conan_spec.rb b/spec/requests/api/graphql/packages/conan_spec.rb
index 7ad85edecef..b8226c482ac 100644
--- a/spec/requests/api/graphql/packages/conan_spec.rb
+++ b/spec/requests/api/graphql/packages/conan_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
require 'spec_helper'
-RSpec.describe 'conan package details' do
+RSpec.describe 'conan package details', feature_category: :package_registry do
include GraphqlHelpers
include_context 'package details setup'
diff --git a/spec/requests/api/graphql/packages/helm_spec.rb b/spec/requests/api/graphql/packages/helm_spec.rb
index 79a589e2dc2..65b3f80d6df 100644
--- a/spec/requests/api/graphql/packages/helm_spec.rb
+++ b/spec/requests/api/graphql/packages/helm_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
require 'spec_helper'
-RSpec.describe 'helm package details' do
+RSpec.describe 'helm package details', feature_category: :package_registry do
include GraphqlHelpers
include_context 'package details setup'
diff --git a/spec/requests/api/graphql/packages/maven_spec.rb b/spec/requests/api/graphql/packages/maven_spec.rb
index b7f39efcf73..26c45ada4a1 100644
--- a/spec/requests/api/graphql/packages/maven_spec.rb
+++ b/spec/requests/api/graphql/packages/maven_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
require 'spec_helper'
-RSpec.describe 'maven package details' do
+RSpec.describe 'maven package details', feature_category: :package_registry do
include GraphqlHelpers
include_context 'package details setup'
diff --git a/spec/requests/api/graphql/packages/nuget_spec.rb b/spec/requests/api/graphql/packages/nuget_spec.rb
index 7de132d1574..1c3af46909e 100644
--- a/spec/requests/api/graphql/packages/nuget_spec.rb
+++ b/spec/requests/api/graphql/packages/nuget_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
require 'spec_helper'
-RSpec.describe 'nuget package details' do
+RSpec.describe 'nuget package details', feature_category: :package_registry do
include GraphqlHelpers
include_context 'package details setup'
diff --git a/spec/requests/api/graphql/packages/package_spec.rb b/spec/requests/api/graphql/packages/package_spec.rb
index 02a3206f587..42927634119 100644
--- a/spec/requests/api/graphql/packages/package_spec.rb
+++ b/spec/requests/api/graphql/packages/package_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
require 'spec_helper'
-RSpec.describe 'package details' do
+RSpec.describe 'package details', feature_category: :package_registry do
include GraphqlHelpers
let_it_be_with_reload(:group) { create(:group) }
@@ -226,5 +226,16 @@ RSpec.describe 'package details' do
end
end
end
+
+ context 'with package that has no default status' do
+ before do
+ composer_package.update!(status: :error)
+ subject
+ end
+
+ it "does not return package's details" do
+ expect(package_details).to be_nil
+ end
+ end
end
end
diff --git a/spec/requests/api/graphql/packages/pypi_spec.rb b/spec/requests/api/graphql/packages/pypi_spec.rb
index c0e589f3597..4441f04dabb 100644
--- a/spec/requests/api/graphql/packages/pypi_spec.rb
+++ b/spec/requests/api/graphql/packages/pypi_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
require 'spec_helper'
-RSpec.describe 'pypi package details' do
+RSpec.describe 'pypi package details', feature_category: :package_registry do
include GraphqlHelpers
include_context 'package details setup'
diff --git a/spec/requests/api/graphql/project/alert_management/alert/assignees_spec.rb b/spec/requests/api/graphql/project/alert_management/alert/assignees_spec.rb
index a59402208ec..c4843c3cf97 100644
--- a/spec/requests/api/graphql/project/alert_management/alert/assignees_spec.rb
+++ b/spec/requests/api/graphql/project/alert_management/alert/assignees_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'getting Alert Management Alert Assignees' do
+RSpec.describe 'getting Alert Management Alert Assignees', feature_category: :projects do
include GraphqlHelpers
let_it_be(:project) { create(:project) }
diff --git a/spec/requests/api/graphql/project/alert_management/alert/issue_spec.rb b/spec/requests/api/graphql/project/alert_management/alert/issue_spec.rb
index 29896c16f5b..3c9ec4fb60b 100644
--- a/spec/requests/api/graphql/project/alert_management/alert/issue_spec.rb
+++ b/spec/requests/api/graphql/project/alert_management/alert/issue_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'getting Alert Management Alert Issue' do
+RSpec.describe 'getting Alert Management Alert Issue', feature_category: :team_planning do
include GraphqlHelpers
let_it_be(:project) { create(:project) }
diff --git a/spec/requests/api/graphql/project/alert_management/alert/metrics_dashboard_url_spec.rb b/spec/requests/api/graphql/project/alert_management/alert/metrics_dashboard_url_spec.rb
index 352a94cfc1d..b430fdeb18f 100644
--- a/spec/requests/api/graphql/project/alert_management/alert/metrics_dashboard_url_spec.rb
+++ b/spec/requests/api/graphql/project/alert_management/alert/metrics_dashboard_url_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'getting Alert Management Alert Assignees' do
+RSpec.describe 'getting Alert Management Alert Assignees', feature_category: :projects do
include GraphqlHelpers
let_it_be(:project) { create(:project) }
diff --git a/spec/requests/api/graphql/project/alert_management/alert/notes_spec.rb b/spec/requests/api/graphql/project/alert_management/alert/notes_spec.rb
index 72d185144ef..16dd0dfcfcb 100644
--- a/spec/requests/api/graphql/project/alert_management/alert/notes_spec.rb
+++ b/spec/requests/api/graphql/project/alert_management/alert/notes_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'getting Alert Management Alert Notes' do
+RSpec.describe 'getting Alert Management Alert Notes', feature_category: :team_planning do
include GraphqlHelpers
let_it_be(:project) { create(:project) }
diff --git a/spec/requests/api/graphql/project/alert_management/alert/todos_spec.rb b/spec/requests/api/graphql/project/alert_management/alert/todos_spec.rb
index ca58079fdfe..ad4361dfa50 100644
--- a/spec/requests/api/graphql/project/alert_management/alert/todos_spec.rb
+++ b/spec/requests/api/graphql/project/alert_management/alert/todos_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'getting Alert Management Alert Assignees' do
+RSpec.describe 'getting Alert Management Alert Assignees', feature_category: :team_planning do
include GraphqlHelpers
let_it_be(:project) { create(:project) }
diff --git a/spec/requests/api/graphql/project/alert_management/alert_status_counts_spec.rb b/spec/requests/api/graphql/project/alert_management/alert_status_counts_spec.rb
index ecd93d169d3..7ce5bf23357 100644
--- a/spec/requests/api/graphql/project/alert_management/alert_status_counts_spec.rb
+++ b/spec/requests/api/graphql/project/alert_management/alert_status_counts_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
require 'spec_helper'
-RSpec.describe 'getting Alert Management Alert counts by status' do
+RSpec.describe 'getting Alert Management Alert counts by status', feature_category: :incident_management do
include GraphqlHelpers
let_it_be(:project) { create(:project, :repository) }
diff --git a/spec/requests/api/graphql/project/alert_management/alerts_spec.rb b/spec/requests/api/graphql/project/alert_management/alerts_spec.rb
index fe77d9dc86d..304edfbf4e4 100644
--- a/spec/requests/api/graphql/project/alert_management/alerts_spec.rb
+++ b/spec/requests/api/graphql/project/alert_management/alerts_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
require 'spec_helper'
-RSpec.describe 'getting Alert Management Alerts' do
+RSpec.describe 'getting Alert Management Alerts', feature_category: :incident_management do
include GraphqlHelpers
let_it_be(:payload) { { 'custom' => { 'alert' => 'payload' }, 'runbook' => 'runbook' } }
@@ -59,6 +59,7 @@ RSpec.describe 'getting Alert Management Alerts' do
it 'returns the correct properties of the alerts' do
expect(first_alert).to include(
+ 'id' => triggered_alert.to_global_id.to_s,
'iid' => triggered_alert.iid.to_s,
'title' => triggered_alert.title,
'description' => triggered_alert.description,
@@ -80,6 +81,7 @@ RSpec.describe 'getting Alert Management Alerts' do
)
expect(second_alert).to include(
+ 'id' => resolved_alert.to_global_id.to_s,
'iid' => resolved_alert.iid.to_s,
'status' => 'RESOLVED',
'endedAt' => resolved_alert.ended_at.strftime('%Y-%m-%dT%H:%M:%SZ')
diff --git a/spec/requests/api/graphql/project/alert_management/integrations_spec.rb b/spec/requests/api/graphql/project/alert_management/integrations_spec.rb
index 773922c1864..e8d19513a4e 100644
--- a/spec/requests/api/graphql/project/alert_management/integrations_spec.rb
+++ b/spec/requests/api/graphql/project/alert_management/integrations_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
require 'spec_helper'
-RSpec.describe 'getting Alert Management Integrations' do
+RSpec.describe 'getting Alert Management Integrations', feature_category: :integrations do
include ::Gitlab::Routing
include GraphqlHelpers
diff --git a/spec/requests/api/graphql/project/base_service_spec.rb b/spec/requests/api/graphql/project/base_service_spec.rb
index 58d10ade8cf..7b1b95eaf58 100644
--- a/spec/requests/api/graphql/project/base_service_spec.rb
+++ b/spec/requests/api/graphql/project/base_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'query Jira service' do
+RSpec.describe 'query Jira service', feature_category: :authentication_and_authorization do
include GraphqlHelpers
let_it_be(:current_user) { create(:user) }
diff --git a/spec/requests/api/graphql/project/branch_protections/merge_access_levels_spec.rb b/spec/requests/api/graphql/project/branch_protections/merge_access_levels_spec.rb
index a80f683ea93..d7672cc5116 100644
--- a/spec/requests/api/graphql/project/branch_protections/merge_access_levels_spec.rb
+++ b/spec/requests/api/graphql/project/branch_protections/merge_access_levels_spec.rb
@@ -2,6 +2,6 @@
require 'spec_helper'
-RSpec.describe 'getting merge access levels for a branch protection' do
- include_examples 'perform graphql requests for AccessLevel type objects', :merge
+RSpec.describe 'getting merge access levels for a branch protection', feature_category: :source_code_management do
+ it_behaves_like 'a GraphQL query for access levels', :merge
end
diff --git a/spec/requests/api/graphql/project/branch_protections/push_access_levels_spec.rb b/spec/requests/api/graphql/project/branch_protections/push_access_levels_spec.rb
index cfdaf1096c3..65b9bc93a6b 100644
--- a/spec/requests/api/graphql/project/branch_protections/push_access_levels_spec.rb
+++ b/spec/requests/api/graphql/project/branch_protections/push_access_levels_spec.rb
@@ -2,6 +2,6 @@
require 'spec_helper'
-RSpec.describe 'getting push access levels for a branch protection' do
- include_examples 'perform graphql requests for AccessLevel type objects', :push
+RSpec.describe 'getting push access levels for a branch protection', feature_category: :source_code_management do
+ it_behaves_like 'a GraphQL query for access levels', :push
end
diff --git a/spec/requests/api/graphql/project/branch_rules/branch_protection_spec.rb b/spec/requests/api/graphql/project/branch_rules/branch_protection_spec.rb
index 8a3f546ef95..560819cb989 100644
--- a/spec/requests/api/graphql/project/branch_rules/branch_protection_spec.rb
+++ b/spec/requests/api/graphql/project/branch_rules/branch_protection_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'getting branch protection for a branch rule' do
+RSpec.describe 'getting branch protection for a branch rule', feature_category: :source_code_management do
include GraphqlHelpers
let_it_be(:current_user) { create(:user) }
diff --git a/spec/requests/api/graphql/project/branch_rules_spec.rb b/spec/requests/api/graphql/project/branch_rules_spec.rb
index ed866305445..7f6a66e2377 100644
--- a/spec/requests/api/graphql/project/branch_rules_spec.rb
+++ b/spec/requests/api/graphql/project/branch_rules_spec.rb
@@ -2,21 +2,11 @@
require 'spec_helper'
-RSpec.describe 'getting list of branch rules for a project' do
+RSpec.describe 'getting list of branch rules for a project', feature_category: :source_code_management do
include GraphqlHelpers
let_it_be(:project) { create(:project, :repository, :public) }
let_it_be(:current_user) { create(:user) }
- let_it_be(:branch_name_a) { TestEnv::BRANCH_SHA.each_key.first }
- let_it_be(:branch_name_b) { 'diff-*' }
- let_it_be(:branch_rules) { [branch_rule_a, branch_rule_b] }
- let_it_be(:branch_rule_a) do
- create(:protected_branch, project: project, name: branch_name_a)
- end
-
- let_it_be(:branch_rule_b) do
- create(:protected_branch, project: project, name: branch_name_b)
- end
let(:branch_rules_data) { graphql_data_at('project', 'branchRules', 'edges') }
let(:variables) { { path: project.full_path } }
@@ -61,39 +51,39 @@ RSpec.describe 'getting list of branch rules for a project' do
end
describe 'queries' do
+ include_context 'when user tracking is disabled'
+
+ let(:query) do
+ <<~GQL
+ query($path: ID!) {
+ project(fullPath: $path) {
+ branchRules {
+ nodes {
+ matchingBranchesCount
+ }
+ }
+ }
+ }
+ GQL
+ end
+
before do
- # rubocop:disable RSpec/AnyInstanceOf
- allow_any_instance_of(User).to receive(:update_tracked_fields!)
- allow_any_instance_of(Users::ActivityService).to receive(:execute)
- # rubocop:enable RSpec/AnyInstanceOf
+ create(:protected_branch, project: project)
allow_next_instance_of(Resolvers::ProjectResolver) do |resolver|
allow(resolver).to receive(:resolve)
.with(full_path: project.full_path)
.and_return(project)
end
allow(project.repository).to receive(:branch_names).and_call_original
- allow(project.repository.gitaly_ref_client).to receive(:branch_names).and_call_original
end
- it 'matching_branches_count avoids N+1 queries' do
- query = <<~GQL
- query($path: ID!) {
- project(fullPath: $path) {
- branchRules {
- nodes {
- matchingBranchesCount
- }
- }
- }
- }
- GQL
-
- control = ActiveRecord::QueryRecorder.new do
+ it 'avoids N+1 queries', :use_sql_query_cache, :aggregate_failures do
+ control = ActiveRecord::QueryRecorder.new(skip_cached: false) do
post_graphql(query, current_user: current_user, variables: variables)
end
# Verify the response includes the field
- expect_n_matching_branches_count_fields(2)
+ expect_n_matching_branches_count_fields(1)
create(:protected_branch, project: project)
create(:protected_branch, name: '*', project: project)
@@ -102,10 +92,8 @@ RSpec.describe 'getting list of branch rules for a project' do
post_graphql(query, current_user: current_user, variables: variables)
end.not_to exceed_all_query_limit(control)
+ expect_n_matching_branches_count_fields(3)
expect(project.repository).to have_received(:branch_names).at_least(2).times
- expect(project.repository.gitaly_ref_client).to have_received(:branch_names).once
-
- expect_n_matching_branches_count_fields(4)
end
def expect_n_matching_branches_count_fields(count)
@@ -118,21 +106,28 @@ RSpec.describe 'getting list of branch rules for a project' do
end
describe 'response' do
+ let_it_be(:branch_name_a) { TestEnv::BRANCH_SHA.each_key.first }
+ let_it_be(:branch_name_b) { 'diff-*' }
+ let_it_be(:branch_rules) { [branch_rule_a, branch_rule_b] }
+ let_it_be(:branch_rule_a) do
+ create(:protected_branch, project: project, name: branch_name_a, id: 9999)
+ end
+
+ let_it_be(:branch_rule_b) do
+ create(:protected_branch, project: project, name: branch_name_b, id: 10000)
+ end
+
+ # branchRules are returned in reverse order, newest first, sorted by primary_key.
+ let(:branch_rule_b_data) { branch_rules_data.dig(0, 'node') }
+ let(:branch_rule_a_data) { branch_rules_data.dig(1, 'node') }
+
before do
post_graphql(query, current_user: current_user, variables: variables)
end
it_behaves_like 'a working graphql query'
- it 'includes all fields', :aggregate_failures do
- # Responses will be sorted alphabetically. Branch names for this spec
- # come from an external constant so we check which is first
- br_a_idx = branch_name_a < branch_name_b ? 0 : 1
- br_b_idx = 1 - br_a_idx
-
- branch_rule_a_data = branch_rules_data.dig(br_a_idx, 'node')
- branch_rule_b_data = branch_rules_data.dig(br_b_idx, 'node')
-
+ it 'includes all fields', :use_sql_query_cache, :aggregate_failures do
expect(branch_rule_a_data['name']).to eq(branch_name_a)
expect(branch_rule_a_data['isDefault']).to be(true).or be(false)
expect(branch_rule_a_data['branchProtection']).to be_present
diff --git a/spec/requests/api/graphql/project/cluster_agents_spec.rb b/spec/requests/api/graphql/project/cluster_agents_spec.rb
index bb716cf2849..0881eb9cdc3 100644
--- a/spec/requests/api/graphql/project/cluster_agents_spec.rb
+++ b/spec/requests/api/graphql/project/cluster_agents_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Project.cluster_agents' do
+RSpec.describe 'Project.cluster_agents', feature_category: :kubernetes_management do
include GraphqlHelpers
let_it_be(:project) { create(:project, :public) }
diff --git a/spec/requests/api/graphql/project/container_expiration_policy_spec.rb b/spec/requests/api/graphql/project/container_expiration_policy_spec.rb
index e3ea9e46353..e484e0618aa 100644
--- a/spec/requests/api/graphql/project/container_expiration_policy_spec.rb
+++ b/spec/requests/api/graphql/project/container_expiration_policy_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
require 'spec_helper'
-RSpec.describe 'getting a repository in a project' do
+RSpec.describe 'getting a repository in a project', feature_category: :container_registry do
include GraphqlHelpers
let_it_be(:project) { create(:project) }
diff --git a/spec/requests/api/graphql/project/container_repositories_spec.rb b/spec/requests/api/graphql/project/container_repositories_spec.rb
index 01b117a89d8..7ccf8a6f5bf 100644
--- a/spec/requests/api/graphql/project/container_repositories_spec.rb
+++ b/spec/requests/api/graphql/project/container_repositories_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
require 'spec_helper'
-RSpec.describe 'getting container repositories in a project' do
+RSpec.describe 'getting container repositories in a project', feature_category: :container_registry do
using RSpec::Parameterized::TableSyntax
include GraphqlHelpers
diff --git a/spec/requests/api/graphql/project/deployment_spec.rb b/spec/requests/api/graphql/project/deployment_spec.rb
index e5ef7bcafbf..e3ec33ec131 100644
--- a/spec/requests/api/graphql/project/deployment_spec.rb
+++ b/spec/requests/api/graphql/project/deployment_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Project Deployment query' do
+RSpec.describe 'Project Deployment query', feature_category: :continuous_delivery do
let_it_be(:project) { create(:project, :private, :repository) }
let_it_be(:developer) { create(:user).tap { |u| project.add_developer(u) } }
let_it_be(:guest) { create(:user).tap { |u| project.add_guest(u) } }
diff --git a/spec/requests/api/graphql/project/environments_spec.rb b/spec/requests/api/graphql/project/environments_spec.rb
index e5b6aebbf2c..618f591affa 100644
--- a/spec/requests/api/graphql/project/environments_spec.rb
+++ b/spec/requests/api/graphql/project/environments_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Project Environments query' do
+RSpec.describe 'Project Environments query', feature_category: :continuous_delivery do
include GraphqlHelpers
let_it_be(:project) { create(:project, :private, :repository) }
@@ -47,6 +47,60 @@ RSpec.describe 'Project Environments query' do
expect(environment_data['environmentType']).to eq(production.environment_type)
end
+ describe 'user permissions' do
+ let(:query) do
+ %(
+ query {
+ project(fullPath: "#{project.full_path}") {
+ environment(name: "#{production.name}") {
+ userPermissions {
+ updateEnvironment
+ destroyEnvironment
+ stopEnvironment
+ }
+ }
+ }
+ }
+ )
+ end
+
+ it 'returns user permissions of the environment', :aggregate_failures do
+ subject
+
+ permission_data = graphql_data.dig('project', 'environment', 'userPermissions')
+ expect(permission_data['updateEnvironment']).to eq(true)
+ expect(permission_data['destroyEnvironment']).to eq(false)
+ expect(permission_data['stopEnvironment']).to eq(true)
+ end
+
+ context 'when fetching user permissions for multiple environments' do
+ let(:query) do
+ %(
+ query {
+ project(fullPath: "#{project.full_path}") {
+ environments {
+ nodes {
+ userPermissions {
+ updateEnvironment
+ destroyEnvironment
+ stopEnvironment
+ }
+ }
+ }
+ }
+ }
+ )
+ end
+
+ it 'limits the result', :aggregate_failures do
+ subject
+
+ expect_graphql_errors_to_include('"userPermissions" field can be requested only ' \
+ 'for 1 Environment(s) at a time.')
+ end
+ end
+ end
+
describe 'last deployments of environments' do
::Deployment.statuses.each do |status, _|
let_it_be(:"production_#{status}_deployment") do
@@ -130,4 +184,81 @@ RSpec.describe 'Project Environments query' do
expect(multi).not_to exceed_query_limit(baseline)
end
end
+
+ describe 'nested environments' do
+ let_it_be(:testing1) { create(:environment, name: 'testing/one', project: project) }
+ let_it_be(:testing2) { create(:environment, name: 'testing/two', project: project) }
+
+ context 'with query' do
+ let(:query) do
+ %(
+ query {
+ project(fullPath: "#{project.full_path}") {
+ nestedEnvironments {
+ nodes {
+ name
+ size
+ environment {
+ name
+ path
+ }
+ }
+ }
+ }
+ }
+ )
+ end
+
+ it 'can fetch nested environments' do
+ subject
+
+ nested_envs = graphql_data.dig('project', 'nestedEnvironments', 'nodes')
+ expect(nested_envs.count).to be(3)
+ expect(nested_envs.pluck('name')).to match_array(%w[production staging testing])
+ expect(nested_envs.pluck('size')).to match_array([1, 1, 2])
+ expect(nested_envs[0].dig('environment', 'name')).to eq(production.name)
+ end
+
+ context 'when user is guest' do
+ let(:user) { create(:user).tap { |u| project.add_guest(u) } }
+
+ it 'returns nothing' do
+ subject
+
+ nested_envs = graphql_data.dig('project', 'nestedEnvironments', 'nodes')
+
+ expect(nested_envs).to be_nil
+ end
+ end
+ end
+
+ context 'when using pagination' do
+ let(:query) do
+ %(
+ query {
+ project(fullPath: "#{project.full_path}") {
+ nestedEnvironments(first: 1) {
+ nodes {
+ name
+ }
+ pageInfo {
+ hasPreviousPage
+ startCursor
+ endCursor
+ hasNextPage
+ }
+ }
+ }
+ }
+ )
+ end
+
+ it 'supports pagination' do
+ subject
+ nested_envs = graphql_data.dig('project', 'nestedEnvironments')
+ expect(nested_envs['nodes'].count).to eq(1)
+ expect(nested_envs.dig('pageInfo', 'hasNextPage')).to be_truthy
+ end
+ end
+ end
end
diff --git a/spec/requests/api/graphql/project/error_tracking/sentry_detailed_error_request_spec.rb b/spec/requests/api/graphql/project/error_tracking/sentry_detailed_error_request_spec.rb
index 2fe5fb593fe..e1a8304dce6 100644
--- a/spec/requests/api/graphql/project/error_tracking/sentry_detailed_error_request_spec.rb
+++ b/spec/requests/api/graphql/project/error_tracking/sentry_detailed_error_request_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
require 'spec_helper'
-RSpec.describe 'getting a detailed sentry error' do
+RSpec.describe 'getting a detailed sentry error', feature_category: :error_tracking do
include GraphqlHelpers
let_it_be(:project) { create(:project, :repository) }
diff --git a/spec/requests/api/graphql/project/error_tracking/sentry_errors_request_spec.rb b/spec/requests/api/graphql/project/error_tracking/sentry_errors_request_spec.rb
index 3ca0e35882a..2abb1f62ea9 100644
--- a/spec/requests/api/graphql/project/error_tracking/sentry_errors_request_spec.rb
+++ b/spec/requests/api/graphql/project/error_tracking/sentry_errors_request_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
require 'spec_helper'
-RSpec.describe 'sentry errors requests' do
+RSpec.describe 'sentry errors requests', feature_category: :error_tracking do
include GraphqlHelpers
let_it_be(:project) { create(:project, :repository) }
diff --git a/spec/requests/api/graphql/project/fork_details_spec.rb b/spec/requests/api/graphql/project/fork_details_spec.rb
new file mode 100644
index 00000000000..efd48b00833
--- /dev/null
+++ b/spec/requests/api/graphql/project/fork_details_spec.rb
@@ -0,0 +1,60 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'getting project fork details', feature_category: :source_code_management do
+ include GraphqlHelpers
+ include ProjectForksHelper
+
+ let_it_be(:project) { create(:project, :public, :repository_private, :repository) }
+ let_it_be(:current_user) { create(:user, maintainer_projects: [project]) }
+ let_it_be(:forked_project) { fork_project(project, current_user, repository: true) }
+
+ let(:queried_project) { forked_project }
+
+ let(:query) do
+ graphql_query_for(:project,
+ { full_path: queried_project.full_path }, <<~QUERY
+ forkDetails(ref: "feature"){
+ ahead
+ behind
+ }
+ QUERY
+ )
+ end
+
+ it 'returns fork details' do
+ post_graphql(query, current_user: current_user)
+
+ expect(graphql_data['project']['forkDetails']).to eq(
+ { 'ahead' => 1, 'behind' => 29 }
+ )
+ end
+
+ context 'when a project is not a fork' do
+ let(:queried_project) { project }
+
+ it 'does not return fork details' do
+ post_graphql(query, current_user: current_user)
+
+ expect(graphql_data['project']['forkDetails']).to be_nil
+ end
+ end
+
+ context 'when a user cannot read the code' do
+ let_it_be(:current_user) { create(:user) }
+
+ before do
+ forked_project.update!({
+ repository_access_level: 'private',
+ merge_requests_access_level: 'private'
+ })
+ end
+
+ it 'does not return fork details' do
+ post_graphql(query, current_user: current_user)
+
+ expect(graphql_data['project']['forkDetails']).to be_nil
+ end
+ end
+end
diff --git a/spec/requests/api/graphql/project/fork_targets_spec.rb b/spec/requests/api/graphql/project/fork_targets_spec.rb
index b21a11ff4dc..f2a3901b2c6 100644
--- a/spec/requests/api/graphql/project/fork_targets_spec.rb
+++ b/spec/requests/api/graphql/project/fork_targets_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'getting a list of fork targets for a project' do
+RSpec.describe 'getting a list of fork targets for a project', feature_category: :source_code_management do
include GraphqlHelpers
let_it_be(:group) { create(:group) }
diff --git a/spec/requests/api/graphql/project/grafana_integration_spec.rb b/spec/requests/api/graphql/project/grafana_integration_spec.rb
index e7534945e7a..1d4f52a8ace 100644
--- a/spec/requests/api/graphql/project/grafana_integration_spec.rb
+++ b/spec/requests/api/graphql/project/grafana_integration_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
require 'spec_helper'
-RSpec.describe 'Getting Grafana Integration' do
+RSpec.describe 'Getting Grafana Integration', feature_category: :metrics do
include GraphqlHelpers
let_it_be(:project) { create(:project, :repository) }
diff --git a/spec/requests/api/graphql/project/incident_management/timeline_events_spec.rb b/spec/requests/api/graphql/project/incident_management/timeline_events_spec.rb
index 544d2d7bd95..7587b227d9f 100644
--- a/spec/requests/api/graphql/project/incident_management/timeline_events_spec.rb
+++ b/spec/requests/api/graphql/project/incident_management/timeline_events_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'getting incident timeline events' do
+RSpec.describe 'getting incident timeline events', feature_category: :incident_management do
include GraphqlHelpers
let_it_be(:project) { create(:project) }
diff --git a/spec/requests/api/graphql/project/issue/design_collection/version_spec.rb b/spec/requests/api/graphql/project/issue/design_collection/version_spec.rb
index 0444ce43c22..5ccf5c1999a 100644
--- a/spec/requests/api/graphql/project/issue/design_collection/version_spec.rb
+++ b/spec/requests/api/graphql/project/issue/design_collection/version_spec.rb
@@ -2,7 +2,8 @@
require 'spec_helper'
-RSpec.describe 'Query.project(fullPath).issue(iid).designCollection.version(sha)' do
+RSpec.describe 'Query.project(fullPath).issue(iid).designCollection.version(sha)',
+feature_category: :design_management do
include GraphqlHelpers
include DesignManagementTestHelpers
@@ -67,7 +68,7 @@ RSpec.describe 'Query.project(fullPath).issue(iid).designCollection.version(sha)
query_graphql_field(:design_at_version, dav_params, 'id filename')
end
- shared_examples :finds_dav do
+ shared_examples 'finds dav' do
it 'finds all the designs as of the given version' do
post_query
@@ -88,19 +89,19 @@ RSpec.describe 'Query.project(fullPath).issue(iid).designCollection.version(sha)
context 'by ID' do
let(:dav_params) { { id: global_id_of(design_at_version) } }
- include_examples :finds_dav
+ include_examples 'finds dav'
end
context 'by filename' do
let(:dav_params) { { filename: design.filename } }
- include_examples :finds_dav
+ include_examples 'finds dav'
end
context 'by design_id' do
let(:dav_params) { { design_id: global_id_of(design) } }
- include_examples :finds_dav
+ include_examples 'finds dav'
end
end
diff --git a/spec/requests/api/graphql/project/issue/design_collection/versions_spec.rb b/spec/requests/api/graphql/project/issue/design_collection/versions_spec.rb
index 46fd65db1c5..a15e4c1e792 100644
--- a/spec/requests/api/graphql/project/issue/design_collection/versions_spec.rb
+++ b/spec/requests/api/graphql/project/issue/design_collection/versions_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Getting versions related to an issue' do
+RSpec.describe 'Getting versions related to an issue', feature_category: :design_management do
include GraphqlHelpers
include DesignManagementTestHelpers
diff --git a/spec/requests/api/graphql/project/issue/designs/designs_spec.rb b/spec/requests/api/graphql/project/issue/designs/designs_spec.rb
index 965534654ea..3765899daf2 100644
--- a/spec/requests/api/graphql/project/issue/designs/designs_spec.rb
+++ b/spec/requests/api/graphql/project/issue/designs/designs_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Getting designs related to an issue' do
+RSpec.describe 'Getting designs related to an issue', feature_category: :design_management do
include GraphqlHelpers
include DesignManagementTestHelpers
diff --git a/spec/requests/api/graphql/project/issue/designs/notes_spec.rb b/spec/requests/api/graphql/project/issue/designs/notes_spec.rb
index 3b1eb0b4b02..69ca7030292 100644
--- a/spec/requests/api/graphql/project/issue/designs/notes_spec.rb
+++ b/spec/requests/api/graphql/project/issue/designs/notes_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Getting designs related to an issue' do
+RSpec.describe 'Getting designs related to an issue', feature_category: :design_management do
include GraphqlHelpers
include DesignManagementTestHelpers
diff --git a/spec/requests/api/graphql/project/issue/notes_spec.rb b/spec/requests/api/graphql/project/issue/notes_spec.rb
index 97f5261ef1d..0c7f042510e 100644
--- a/spec/requests/api/graphql/project/issue/notes_spec.rb
+++ b/spec/requests/api/graphql/project/issue/notes_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'getting notes for an issue' do
+RSpec.describe 'getting notes for an issue', feature_category: :team_planning do
include GraphqlHelpers
let(:noteable) { create(:issue) }
diff --git a/spec/requests/api/graphql/project/issue_spec.rb b/spec/requests/api/graphql/project/issue_spec.rb
index 2415e9ef60f..bc90f9e89e6 100644
--- a/spec/requests/api/graphql/project/issue_spec.rb
+++ b/spec/requests/api/graphql/project/issue_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Query.project(fullPath).issue(iid)' do
+RSpec.describe 'Query.project(fullPath).issue(iid)', feature_category: :team_planning do
include GraphqlHelpers
let_it_be(:project) { create(:project) }
diff --git a/spec/requests/api/graphql/project/issues_spec.rb b/spec/requests/api/graphql/project/issues_spec.rb
index 214165cb171..ec5e3c6f0de 100644
--- a/spec/requests/api/graphql/project/issues_spec.rb
+++ b/spec/requests/api/graphql/project/issues_spec.rb
@@ -2,44 +2,92 @@
require 'spec_helper'
-RSpec.describe 'getting an issue list for a project' do
+RSpec.describe 'getting an issue list for a project', feature_category: :team_planning do
include GraphqlHelpers
let_it_be(:group) { create(:group) }
let_it_be(:project) { create(:project, :repository, :public, group: group) }
let_it_be(:current_user) { create(:user) }
let_it_be(:another_user) { create(:user).tap { |u| group.add_reporter(u) } }
- let_it_be(:early_milestone) { create(:milestone, project: project, due_date: 10.days.from_now) }
- let_it_be(:late_milestone) { create(:milestone, project: project, due_date: 30.days.from_now) }
+ let_it_be(:milestone1) { create(:milestone, project: project, due_date: 10.days.from_now) }
+ let_it_be(:milestone2) { create(:milestone, project: project, due_date: 20.days.from_now) }
+ let_it_be(:milestone3) { create(:milestone, project: project, due_date: 30.days.from_now) }
+ let_it_be(:milestone4) { create(:milestone, project: project, due_date: 40.days.from_now) }
let_it_be(:priority1) { create(:label, project: project, priority: 1) }
let_it_be(:priority2) { create(:label, project: project, priority: 5) }
let_it_be(:priority3) { create(:label, project: project, priority: 10) }
- let_it_be(:issue_a, reload: true) { create(:issue, project: project, discussion_locked: true, labels: [priority3]) }
- let_it_be(:issue_b, reload: true) { create(:issue, :with_alert, project: project, title: 'title matching issue i') }
- let_it_be(:issue_c) { create(:issue, project: project, labels: [priority1], milestone: late_milestone) }
- let_it_be(:issue_d) { create(:issue, project: project, labels: [priority2]) }
- let_it_be(:issue_e) { create(:issue, project: project, milestone: early_milestone) }
- let_it_be(:issues, reload: true) { [issue_a, issue_b, issue_c, issue_d, issue_e] }
+ let_it_be(:issue_a) do
+ create(
+ :issue,
+ project: project,
+ discussion_locked: true,
+ labels: [priority3],
+ relative_position: 1000,
+ milestone: milestone4
+ )
+ end
- let(:issue_a_gid) { issue_a.to_global_id.to_s }
- let(:issue_b_gid) { issue_b.to_global_id.to_s }
- let(:issues_data) { graphql_data['project']['issues']['nodes'] }
- let(:issue_filter_params) { {} }
+ let_it_be(:issue_b) do
+ create(
+ :issue,
+ :with_alert,
+ project: project,
+ title: 'title matching issue i',
+ due_date: 3.days.ago,
+ relative_position: 3000,
+ labels: [priority2, priority3],
+ milestone: milestone1
+ )
+ end
- let(:fields) do
- <<~QUERY
- nodes {
- #{all_graphql_fields_for('issues'.classify)}
- }
- QUERY
+ let_it_be(:issue_c) do
+ create(
+ :issue,
+ project: project,
+ labels: [priority1],
+ milestone: milestone2,
+ due_date: 1.day.ago,
+ relative_position: nil
+ )
+ end
+
+ let_it_be(:issue_d) do
+ create(:issue,
+ project: project,
+ labels: [priority2],
+ due_date: 3.days.from_now,
+ relative_position: 5000,
+ milestone: milestone3
+ )
+ end
+
+ let_it_be(:issue_e) do
+ create(
+ :issue,
+ :confidential,
+ project: project,
+ due_date: 1.day.from_now,
+ relative_position: nil
+ )
end
+ let_it_be(:issues, reload: true) { [issue_a, issue_b, issue_c, issue_d, issue_e] }
+
+ let(:issue_nodes_path) { %w[project issues nodes] }
+ let(:issue_filter_params) { {} }
+
# All new specs should be added to the shared example if the change also
# affects the `issues` query at the root level of the API.
# Shared example also used in spec/requests/api/graphql/issues_spec.rb
it_behaves_like 'graphql issue list request spec' do
- subject(:post_query) { post_graphql(query, current_user: current_user) }
+ let_it_be(:external_user) { create(:user) }
+
+ let(:public_projects) { [project] }
+
+ before_all do
+ group.add_developer(current_user)
+ end
# filters
let(:expected_negated_assignee_issues) { [issue_b, issue_c, issue_d, issue_e] }
@@ -50,24 +98,31 @@ RSpec.describe 'getting an issue list for a project' do
let(:unlocked_discussion_issues) { [issue_b, issue_c, issue_d, issue_e] }
let(:search_title_term) { 'matching issue' }
let(:title_search_issue) { issue_b }
+ let(:confidential_issues) { [issue_e] }
+ let(:non_confidential_issues) { [issue_a, issue_b, issue_c, issue_d] }
+ let(:public_non_confidential_issues) { non_confidential_issues }
# sorting
let(:data_path) { [:project, :issues] }
- let(:expected_severity_sorted_asc) { [issue_c, issue_a, issue_b, issue_e, issue_d] }
- let(:expected_priority_sorted_asc) { [issue_e, issue_c, issue_d, issue_a, issue_b] }
- let(:expected_priority_sorted_desc) { [issue_c, issue_e, issue_a, issue_d, issue_b] }
+ let(:expected_priority_sorted_asc) { [issue_b, issue_c, issue_d, issue_a, issue_e] }
+ let(:expected_priority_sorted_desc) { [issue_a, issue_d, issue_c, issue_b, issue_e] }
+ let(:expected_due_date_sorted_desc) { [issue_d, issue_e, issue_c, issue_b, issue_a] }
+ let(:expected_due_date_sorted_asc) { [issue_b, issue_c, issue_e, issue_d, issue_a] }
+ let(:expected_relative_position_sorted_asc) { [issue_a, issue_b, issue_d, issue_c, issue_e] }
+ let(:expected_label_priority_sorted_asc) { [issue_c, issue_d, issue_b, issue_a, issue_e] }
+ let(:expected_label_priority_sorted_desc) { [issue_a, issue_d, issue_b, issue_c, issue_e] }
+ let(:expected_milestone_sorted_asc) { [issue_b, issue_c, issue_d, issue_a, issue_e] }
+ let(:expected_milestone_sorted_desc) { [issue_a, issue_d, issue_c, issue_b, issue_e] }
+
+ # N+1 queries
+ let(:same_project_issue1) { issue_a }
+ let(:same_project_issue2) { issue_b }
before_all do
issue_a.assignee_ids = current_user.id
issue_b.assignee_ids = another_user.id
create(:award_emoji, :upvote, user: current_user, awardable: issue_a)
-
- # severity sorting
- create(:issuable_severity, issue: issue_a, severity: :unknown)
- create(:issuable_severity, issue: issue_b, severity: :low)
- create(:issuable_severity, issue: issue_d, severity: :critical)
- create(:issuable_severity, issue: issue_e, severity: :high)
end
def pagination_query(params)
@@ -77,591 +132,10 @@ RSpec.describe 'getting an issue list for a project' do
query_graphql_field(:issues, params, "#{page_info} nodes { id }")
)
end
- end
-
- context 'when limiting the number of results' do
- let(:query) do
- <<~GQL
- query($path: ID!, $n: Int) {
- project(fullPath: $path) {
- issues(first: $n) { #{fields} }
- }
- }
- GQL
- end
-
- let(:issue_limit) { 1 }
- let(:variables) do
- { path: project.full_path, n: issue_limit }
- end
-
- it_behaves_like 'a working graphql query' do
- before do
- post_graphql(query, current_user: current_user, variables: variables)
- end
-
- it 'only returns N issues' do
- expect(issues_data.size).to eq(issue_limit)
- end
- end
-
- context 'when no limit is provided' do
- let(:issue_limit) { nil }
-
- it 'returns all issues' do
- post_graphql(query, current_user: current_user, variables: variables)
-
- expect(issues_data.size).to be > 1
- end
- end
-
- it 'is expected to check permissions on the first issue only' do
- allow(Ability).to receive(:allowed?).and_call_original
- # Newest first, we only want to see the newest checked
- expect(Ability).not_to receive(:allowed?).with(current_user, :read_issue, issues.first)
-
- post_graphql(query, current_user: current_user, variables: variables)
- end
- end
-
- context 'when the user does not have access to the issue' do
- it 'returns nil' do
- project.project_feature.update!(issues_access_level: ProjectFeature::PRIVATE)
-
- post_graphql(query)
-
- expect(issues_data).to eq([])
- end
- end
-
- context 'when there is a confidential issue' do
- let_it_be(:confidential_issue) do
- create(:issue, :confidential, project: project)
- end
-
- let(:confidential_issue_gid) { confidential_issue.to_global_id.to_s }
-
- context 'when the user cannot see confidential issues' do
- it 'returns issues without confidential issues' do
- post_graphql(query, current_user: current_user)
-
- expect(issues_data.size).to eq(5)
-
- issues_data.each do |issue|
- expect(issue['confidential']).to eq(false)
- end
- end
-
- context 'filtering for confidential issues' do
- let(:issue_filter_params) { { confidential: true } }
-
- it 'returns no issues' do
- post_graphql(query, current_user: current_user)
-
- expect(issues_data.size).to eq(0)
- end
- end
-
- context 'filtering for non-confidential issues' do
- let(:issue_filter_params) { { confidential: false } }
-
- it 'returns correctly filtered issues' do
- post_graphql(query, current_user: current_user)
-
- expect(issue_ids).to match_array(issues.map { |i| i.to_gid.to_s })
- end
- end
- end
-
- context 'when the user can see confidential issues' do
- before do
- project.add_developer(current_user)
- end
-
- it 'returns issues with confidential issues' do
- post_graphql(query, current_user: current_user)
-
- expect(issues_data.size).to eq(6)
-
- confidentials = issues_data.map do |issue|
- issue['confidential']
- end
-
- expect(confidentials).to contain_exactly(true, false, false, false, false, false)
- end
-
- context 'filtering for confidential issues' do
- let(:issue_filter_params) { { confidential: true } }
-
- it 'returns correctly filtered issues' do
- post_graphql(query, current_user: current_user)
-
- expect(issue_ids).to contain_exactly(confidential_issue_gid)
- end
- end
-
- context 'filtering for non-confidential issues' do
- let(:issue_filter_params) { { confidential: false } }
-
- it 'returns correctly filtered issues' do
- post_graphql(query, current_user: current_user)
-
- expect(issue_ids).to match_array([issue_a, issue_b, issue_c, issue_d, issue_e].map { |i| i.to_gid.to_s })
- end
- end
- end
- end
-
- describe 'sorting and pagination' do
- let_it_be(:sort_project) { create(:project, :public) }
- let_it_be(:data_path) { [:project, :issues] }
-
- def pagination_query(params)
- graphql_query_for(
- :project,
- { full_path: sort_project.full_path },
- query_graphql_field(:issues, params, "#{page_info} nodes { iid }")
- )
- end
- def pagination_results_data(data)
- data.map { |issue| issue['iid'].to_i }
+ def post_query(request_user = current_user)
+ post_graphql(query, current_user: request_user)
end
-
- # rubocop:disable RSpec/MultipleMemoizedHelpers
- context 'when sorting by due date' do
- let_it_be(:due_issue1) { create(:issue, project: sort_project, due_date: 3.days.from_now) }
- let_it_be(:due_issue2) { create(:issue, project: sort_project, due_date: nil) }
- let_it_be(:due_issue3) { create(:issue, project: sort_project, due_date: 2.days.ago) }
- let_it_be(:due_issue4) { create(:issue, project: sort_project, due_date: nil) }
- let_it_be(:due_issue5) { create(:issue, project: sort_project, due_date: 1.day.ago) }
-
- context 'when ascending' do
- it_behaves_like 'sorted paginated query' do
- let(:sort_param) { :DUE_DATE_ASC }
- let(:first_param) { 2 }
- let(:all_records) { [due_issue3.iid, due_issue5.iid, due_issue1.iid, due_issue4.iid, due_issue2.iid] }
- end
- end
-
- context 'when descending' do
- it_behaves_like 'sorted paginated query' do
- let(:sort_param) { :DUE_DATE_DESC }
- let(:first_param) { 2 }
- let(:all_records) { [due_issue1.iid, due_issue5.iid, due_issue3.iid, due_issue4.iid, due_issue2.iid] }
- end
- end
- end
-
- context 'when sorting by relative position' do
- let_it_be(:relative_issue1) { create(:issue, project: sort_project, relative_position: 2000) }
- let_it_be(:relative_issue2) { create(:issue, project: sort_project, relative_position: nil) }
- let_it_be(:relative_issue3) { create(:issue, project: sort_project, relative_position: 1000) }
- let_it_be(:relative_issue4) { create(:issue, project: sort_project, relative_position: nil) }
- let_it_be(:relative_issue5) { create(:issue, project: sort_project, relative_position: 500) }
-
- context 'when ascending' do
- it_behaves_like 'sorted paginated query', is_reversible: true do
- let(:sort_param) { :RELATIVE_POSITION_ASC }
- let(:first_param) { 2 }
- let(:all_records) do
- [
- relative_issue5.iid, relative_issue3.iid, relative_issue1.iid,
- relative_issue2.iid, relative_issue4.iid
- ]
- end
- end
- end
- end
-
- context 'when sorting by label priority' do
- let_it_be(:label1) { create(:label, project: sort_project, priority: 1) }
- let_it_be(:label2) { create(:label, project: sort_project, priority: 5) }
- let_it_be(:label3) { create(:label, project: sort_project, priority: 10) }
- let_it_be(:label_issue1) { create(:issue, project: sort_project, labels: [label1]) }
- let_it_be(:label_issue2) { create(:issue, project: sort_project, labels: [label2]) }
- let_it_be(:label_issue3) { create(:issue, project: sort_project, labels: [label1, label3]) }
- let_it_be(:label_issue4) { create(:issue, project: sort_project) }
-
- context 'when ascending' do
- it_behaves_like 'sorted paginated query' do
- let(:sort_param) { :LABEL_PRIORITY_ASC }
- let(:first_param) { 2 }
- let(:all_records) { [label_issue3.iid, label_issue1.iid, label_issue2.iid, label_issue4.iid] }
- end
- end
-
- context 'when descending' do
- it_behaves_like 'sorted paginated query' do
- let(:sort_param) { :LABEL_PRIORITY_DESC }
- let(:first_param) { 2 }
- let(:all_records) { [label_issue2.iid, label_issue3.iid, label_issue1.iid, label_issue4.iid] }
- end
- end
- end
- # rubocop:enable RSpec/MultipleMemoizedHelpers
-
- context 'when sorting by milestone due date' do
- let_it_be(:early_milestone) { create(:milestone, project: sort_project, due_date: 10.days.from_now) }
- let_it_be(:late_milestone) { create(:milestone, project: sort_project, due_date: 30.days.from_now) }
- let_it_be(:milestone_issue1) { create(:issue, project: sort_project) }
- let_it_be(:milestone_issue2) { create(:issue, project: sort_project, milestone: early_milestone) }
- let_it_be(:milestone_issue3) { create(:issue, project: sort_project, milestone: late_milestone) }
-
- context 'when ascending' do
- it_behaves_like 'sorted paginated query' do
- let(:sort_param) { :MILESTONE_DUE_ASC }
- let(:first_param) { 2 }
- let(:all_records) { [milestone_issue2.iid, milestone_issue3.iid, milestone_issue1.iid] }
- end
- end
-
- context 'when descending' do
- it_behaves_like 'sorted paginated query' do
- let(:sort_param) { :MILESTONE_DUE_DESC }
- let(:first_param) { 2 }
- let(:all_records) { [milestone_issue3.iid, milestone_issue2.iid, milestone_issue1.iid] }
- end
- end
- end
- end
-
- context 'when fetching alert management alert' do
- let(:fields) do
- <<~QUERY
- nodes {
- iid
- alertManagementAlert {
- title
- }
- alertManagementAlerts {
- nodes {
- title
- }
- }
- }
- QUERY
- end
-
- # Alerts need to have developer permission and above
- before do
- project.add_developer(current_user)
- end
-
- it 'avoids N+1 queries' do
- control = ActiveRecord::QueryRecorder.new { post_graphql(query, current_user: current_user) }
-
- create(:alert_management_alert, :with_incident, project: project)
-
- expect { post_graphql(query, current_user: current_user) }.not_to exceed_query_limit(control)
- end
-
- it 'returns the alert data' do
- post_graphql(query, current_user: current_user)
-
- alert_titles = issues_data.map { |issue| issue.dig('alertManagementAlert', 'title') }
- expected_titles = issues.map { |issue| issue.alert_management_alert&.title }
-
- expect(alert_titles).to contain_exactly(*expected_titles)
- end
-
- it 'returns the alerts data' do
- post_graphql(query, current_user: current_user)
-
- alert_titles = issues_data.map { |issue| issue.dig('alertManagementAlerts', 'nodes') }
- expected_titles = issues.map do |issue|
- issue.alert_management_alerts.map { |alert| { 'title' => alert.title } }
- end
-
- expect(alert_titles).to contain_exactly(*expected_titles)
- end
- end
-
- context 'when fetching customer_relations_contacts' do
- let(:fields) do
- <<~QUERY
- nodes {
- id
- customerRelationsContacts {
- nodes {
- firstName
- }
- }
- }
- QUERY
- end
-
- def clean_state_query
- run_with_clean_state(query, context: { current_user: current_user })
- end
-
- it 'avoids N+1 queries' do
- create(:issue_customer_relations_contact, :for_issue, issue: issue_a)
-
- control = ActiveRecord::QueryRecorder.new(skip_cached: false) { clean_state_query }
-
- create(:issue_customer_relations_contact, :for_issue, issue: issue_a)
-
- expect { clean_state_query }.not_to exceed_all_query_limit(control)
- end
- end
-
- context 'when fetching labels' do
- let(:fields) do
- <<~QUERY
- nodes {
- id
- labels {
- nodes {
- id
- }
- }
- }
- QUERY
- end
-
- before do
- issues.each do |issue|
- # create a label for each issue we have to properly test N+1
- label = create(:label, project: project)
- issue.update!(labels: [label])
- end
- end
-
- def response_label_ids(response_data)
- response_data.map do |node|
- node['labels']['nodes'].map { |u| u['id'] }
- end.flatten
- end
-
- def labels_as_global_ids(issues)
- issues.map(&:labels).flatten.map(&:to_global_id).map(&:to_s)
- end
-
- it 'avoids N+1 queries', :aggregate_failures do
- control = ActiveRecord::QueryRecorder.new { post_graphql(query, current_user: current_user) }
- expect(issues_data.count).to eq(5)
- expect(response_label_ids(issues_data)).to match_array(labels_as_global_ids(issues))
-
- new_issues = issues + [create(:issue, project: project, labels: [create(:label, project: project)])]
-
- expect { post_graphql(query, current_user: current_user) }.not_to exceed_query_limit(control)
- # graphql_data is memoized (see spec/support/helpers/graphql_helpers.rb)
- # so we have to parse the body ourselves the second time
- issues_data = Gitlab::Json.parse(response.body)['data']['project']['issues']['nodes']
- expect(issues_data.count).to eq(6)
- expect(response_label_ids(issues_data)).to match_array(labels_as_global_ids(new_issues))
- end
- end
-
- context 'when fetching assignees' do
- let(:fields) do
- <<~QUERY
- nodes {
- id
- assignees {
- nodes {
- id
- }
- }
- }
- QUERY
- end
-
- before do
- issues.each do |issue|
- # create an assignee for each issue we have to properly test N+1
- assignee = create(:user)
- issue.update!(assignees: [assignee])
- end
- end
-
- def response_assignee_ids(response_data)
- response_data.map do |node|
- node['assignees']['nodes'].map { |node| node['id'] }
- end.flatten
- end
-
- def assignees_as_global_ids(issues)
- issues.map(&:assignees).flatten.map(&:to_global_id).map(&:to_s)
- end
-
- it 'avoids N+1 queries', :aggregate_failures do
- control = ActiveRecord::QueryRecorder.new { post_graphql(query, current_user: current_user) }
- expect(issues_data.count).to eq(5)
- expect(response_assignee_ids(issues_data)).to match_array(assignees_as_global_ids(issues))
-
- new_issues = issues + [create(:issue, project: project, assignees: [create(:user)])]
-
- expect { post_graphql(query, current_user: current_user) }.not_to exceed_query_limit(control)
- # graphql_data is memoized (see spec/support/helpers/graphql_helpers.rb)
- # so we have to parse the body ourselves the second time
- issues_data = Gitlab::Json.parse(response.body)['data']['project']['issues']['nodes']
- expect(issues_data.count).to eq(6)
- expect(response_assignee_ids(issues_data)).to match_array(assignees_as_global_ids(new_issues))
- end
- end
-
- context 'when fetching escalation status' do
- let_it_be(:escalation_status) { create(:incident_management_issuable_escalation_status, issue: issue_a) }
-
- let(:statuses) { issue_data.to_h { |issue| [issue['iid'], issue['escalationStatus']] } }
- let(:fields) do
- <<~QUERY
- nodes {
- id
- escalationStatus
- }
- QUERY
- end
-
- before do
- issue_a.update!(issue_type: Issue.issue_types[:incident])
- end
-
- it 'returns the escalation status values' do
- post_graphql(query, current_user: current_user)
-
- statuses = issues_data.map { |issue| issue['escalationStatus'] }
-
- expect(statuses).to contain_exactly(escalation_status.status_name.upcase.to_s, nil, nil, nil, nil)
- end
-
- it 'avoids N+1 queries', :aggregate_failures do
- base_count = ActiveRecord::QueryRecorder.new { run_with_clean_state(query, context: { current_user: current_user }) }
-
- new_incident = create(:incident, project: project)
- create(:incident_management_issuable_escalation_status, issue: new_incident)
-
- expect { run_with_clean_state(query, context: { current_user: current_user }) }.not_to exceed_query_limit(base_count)
- end
- end
-
- describe 'N+1 query checks' do
- let(:extra_iid_for_second_query) { issue_b.iid.to_s }
- let(:search_params) { { iids: [issue_a.iid.to_s] } }
-
- def execute_query
- query = graphql_query_for(
- :project,
- { full_path: project.full_path },
- query_graphql_field(
- :issues, search_params,
- query_graphql_field(:nodes, nil, requested_fields)
- )
- )
- post_graphql(query, current_user: current_user)
- end
-
- context 'when requesting `user_notes_count`' do
- let(:requested_fields) { [:user_notes_count] }
-
- before do
- create_list(:note_on_issue, 2, noteable: issue_a, project: project)
- create(:note_on_issue, noteable: issue_b, project: project)
- end
-
- include_examples 'N+1 query check'
- end
-
- context 'when requesting `user_discussions_count`' do
- let(:requested_fields) { [:user_discussions_count] }
-
- before do
- create_list(:note_on_issue, 2, noteable: issue_a, project: project)
- create(:note_on_issue, noteable: issue_b, project: project)
- end
-
- include_examples 'N+1 query check'
- end
-
- context 'when requesting `merge_requests_count`' do
- let(:requested_fields) { [:merge_requests_count] }
-
- before do
- create_list(:merge_requests_closing_issues, 2, issue: issue_a)
- create_list(:merge_requests_closing_issues, 3, issue: issue_b)
- end
-
- include_examples 'N+1 query check'
- end
-
- context 'when requesting `timelogs`' do
- let(:requested_fields) { 'timelogs { nodes { timeSpent } }' }
-
- before do
- create_list(:issue_timelog, 2, issue: issue_a)
- create(:issue_timelog, issue: issue_b)
- end
-
- include_examples 'N+1 query check'
- end
-
- context 'when requesting `closed_as_duplicate_of`' do
- let(:requested_fields) { 'closedAsDuplicateOf { id }' }
- let(:issue_a_dup) { create(:issue, project: project) }
- let(:issue_b_dup) { create(:issue, project: project) }
-
- before do
- issue_a.update!(duplicated_to_id: issue_a_dup)
- issue_b.update!(duplicated_to_id: issue_a_dup)
- end
-
- include_examples 'N+1 query check'
- end
-
- context 'when award emoji votes' do
- let(:requested_fields) { [:upvotes, :downvotes] }
-
- before do
- create_list(:award_emoji, 2, name: 'thumbsup', awardable: issue_a)
- create_list(:award_emoji, 2, name: 'thumbsdown', awardable: issue_b)
- end
-
- include_examples 'N+1 query check'
- end
-
- context 'when requesting participants' do
- let_it_be(:issue_c) { create(:issue, project: project) }
-
- let(:search_params) { { iids: [issue_a.iid.to_s, issue_c.iid.to_s] } }
- let(:requested_fields) { 'participants { nodes { name } }' }
-
- before do
- create(:award_emoji, :upvote, awardable: issue_a)
- create(:award_emoji, :upvote, awardable: issue_b)
- create(:award_emoji, :upvote, awardable: issue_c)
-
- note_with_emoji_a = create(:note_on_issue, noteable: issue_a, project: project)
- note_with_emoji_b = create(:note_on_issue, noteable: issue_b, project: project)
- note_with_emoji_c = create(:note_on_issue, noteable: issue_c, project: project)
-
- create(:award_emoji, :upvote, awardable: note_with_emoji_a)
- create(:award_emoji, :upvote, awardable: note_with_emoji_b)
- create(:award_emoji, :upvote, awardable: note_with_emoji_c)
- end
-
- # Executes 3 extra queries to fetch participant_attrs
- include_examples 'N+1 query check', threshold: 3
- end
-
- context 'when requesting labels' do
- let(:requested_fields) { ['labels { nodes { id } }'] }
-
- before do
- project_labels = create_list(:label, 2, project: project)
- group_labels = create_list(:group_label, 2, group: group)
-
- issue_a.update!(labels: [project_labels.first, group_labels.first].flatten)
- issue_b.update!(labels: [project_labels, group_labels].flatten)
- end
-
- include_examples 'N+1 query check', skip_cached: false
- end
- end
-
- def issue_ids
- graphql_dig_at(issues_data, :id)
end
def query(params = issue_filter_params)
diff --git a/spec/requests/api/graphql/project/jira_import_spec.rb b/spec/requests/api/graphql/project/jira_import_spec.rb
index 202220f4bf6..821357b6988 100644
--- a/spec/requests/api/graphql/project/jira_import_spec.rb
+++ b/spec/requests/api/graphql/project/jira_import_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'query Jira import data' do
+RSpec.describe 'query Jira import data', feature_category: :integrations do
include GraphqlHelpers
let_it_be(:current_user) { create(:user) }
diff --git a/spec/requests/api/graphql/project/jira_projects_spec.rb b/spec/requests/api/graphql/project/jira_projects_spec.rb
index 410d5b21505..3cd689deda5 100644
--- a/spec/requests/api/graphql/project/jira_projects_spec.rb
+++ b/spec/requests/api/graphql/project/jira_projects_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'query Jira projects' do
+RSpec.describe 'query Jira projects', feature_category: :integrations do
include GraphqlHelpers
let_it_be(:current_user) { create(:user) }
diff --git a/spec/requests/api/graphql/project/jira_service_spec.rb b/spec/requests/api/graphql/project/jira_service_spec.rb
index d6abe94b873..23f32d2c2d2 100644
--- a/spec/requests/api/graphql/project/jira_service_spec.rb
+++ b/spec/requests/api/graphql/project/jira_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'query Jira service' do
+RSpec.describe 'query Jira service', feature_category: :integrations do
include GraphqlHelpers
let_it_be(:current_user) { create(:user) }
diff --git a/spec/requests/api/graphql/project/job_spec.rb b/spec/requests/api/graphql/project/job_spec.rb
index 6edd4cf753f..ba1c8a1f616 100644
--- a/spec/requests/api/graphql/project/job_spec.rb
+++ b/spec/requests/api/graphql/project/job_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Query.project.job' do
+RSpec.describe 'Query.project.job', feature_category: :continuous_integration do
include GraphqlHelpers
let_it_be(:project) { create(:project) }
diff --git a/spec/requests/api/graphql/project/jobs_spec.rb b/spec/requests/api/graphql/project/jobs_spec.rb
index 7d0eb203d60..d05d4a2f4b6 100644
--- a/spec/requests/api/graphql/project/jobs_spec.rb
+++ b/spec/requests/api/graphql/project/jobs_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
require 'spec_helper'
-RSpec.describe 'Query.project.jobs' do
+RSpec.describe 'Query.project.jobs', feature_category: :continuous_integration do
include GraphqlHelpers
let_it_be(:project) { create(:project, :repository, :public) }
diff --git a/spec/requests/api/graphql/project/labels_query_spec.rb b/spec/requests/api/graphql/project/labels_query_spec.rb
index eeaaaaee575..1930a22ad30 100644
--- a/spec/requests/api/graphql/project/labels_query_spec.rb
+++ b/spec/requests/api/graphql/project/labels_query_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'getting project label information' do
+RSpec.describe 'getting project label information', feature_category: :team_planning do
include GraphqlHelpers
let_it_be(:project) { create(:project, :public) }
diff --git a/spec/requests/api/graphql/project/languages_spec.rb b/spec/requests/api/graphql/project/languages_spec.rb
index 6ef500cde41..88a196c3ff4 100644
--- a/spec/requests/api/graphql/project/languages_spec.rb
+++ b/spec/requests/api/graphql/project/languages_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Project.languages' do
+RSpec.describe 'Project.languages', feature_category: :internationalization do
include GraphqlHelpers
let_it_be(:user) { create(:user) }
diff --git a/spec/requests/api/graphql/project/merge_request/diff_notes_spec.rb b/spec/requests/api/graphql/project/merge_request/diff_notes_spec.rb
index b1ecb32b365..36e148468bc 100644
--- a/spec/requests/api/graphql/project/merge_request/diff_notes_spec.rb
+++ b/spec/requests/api/graphql/project/merge_request/diff_notes_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'getting notes for a merge request' do
+RSpec.describe 'getting notes for a merge request', feature_category: :code_review do
include GraphqlHelpers
let_it_be(:noteable) { create(:merge_request) }
diff --git a/spec/requests/api/graphql/project/merge_request/pipelines_spec.rb b/spec/requests/api/graphql/project/merge_request/pipelines_spec.rb
index 4dc272b5c2e..fb7e46cff8e 100644
--- a/spec/requests/api/graphql/project/merge_request/pipelines_spec.rb
+++ b/spec/requests/api/graphql/project/merge_request/pipelines_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Query.project.mergeRequests.pipelines' do
+RSpec.describe 'Query.project.mergeRequests.pipelines', feature_category: :continuous_integration do
include GraphqlHelpers
let_it_be(:project) { create(:project, :public, :repository) }
diff --git a/spec/requests/api/graphql/project/merge_request_spec.rb b/spec/requests/api/graphql/project/merge_request_spec.rb
index 6a59df81405..b7aafdf305a 100644
--- a/spec/requests/api/graphql/project/merge_request_spec.rb
+++ b/spec/requests/api/graphql/project/merge_request_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'getting merge request information nested in a project' do
+RSpec.describe 'getting merge request information nested in a project', feature_category: :code_review do
include GraphqlHelpers
let_it_be(:project) { create(:project, :repository, :public) }
diff --git a/spec/requests/api/graphql/project/merge_requests_spec.rb b/spec/requests/api/graphql/project/merge_requests_spec.rb
index 2895737ae6f..b3b4c8fe0d5 100644
--- a/spec/requests/api/graphql/project/merge_requests_spec.rb
+++ b/spec/requests/api/graphql/project/merge_requests_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'getting merge request listings nested in a project' do
+RSpec.describe 'getting merge request listings nested in a project', feature_category: :code_review do
include GraphqlHelpers
let_it_be(:group) { create(:group) }
diff --git a/spec/requests/api/graphql/project/milestones_spec.rb b/spec/requests/api/graphql/project/milestones_spec.rb
index a577c367fe5..3b31da77a75 100644
--- a/spec/requests/api/graphql/project/milestones_spec.rb
+++ b/spec/requests/api/graphql/project/milestones_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'getting milestone listings nested in a project' do
+RSpec.describe 'getting milestone listings nested in a project', feature_category: :team_planning do
include GraphqlHelpers
let_it_be(:today) { Time.now.utc.to_date }
diff --git a/spec/requests/api/graphql/project/packages_cleanup_policy_spec.rb b/spec/requests/api/graphql/project/packages_cleanup_policy_spec.rb
index 33e1dbcba27..a7d5cc79f1a 100644
--- a/spec/requests/api/graphql/project/packages_cleanup_policy_spec.rb
+++ b/spec/requests/api/graphql/project/packages_cleanup_policy_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
require 'spec_helper'
-RSpec.describe 'getting the packages cleanup policy linked to a project' do
+RSpec.describe 'getting the packages cleanup policy linked to a project', feature_category: :package_registry do
using RSpec::Parameterized::TableSyntax
include GraphqlHelpers
diff --git a/spec/requests/api/graphql/project/packages_spec.rb b/spec/requests/api/graphql/project/packages_spec.rb
index d9ee997eb02..3413b80e8b4 100644
--- a/spec/requests/api/graphql/project/packages_spec.rb
+++ b/spec/requests/api/graphql/project/packages_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'getting a package list for a project' do
+RSpec.describe 'getting a package list for a project', feature_category: :package_registry do
include GraphqlHelpers
let_it_be(:resource) { create(:project, :repository) }
diff --git a/spec/requests/api/graphql/project/pipeline_spec.rb b/spec/requests/api/graphql/project/pipeline_spec.rb
index 41915d3cdee..0eeb382510e 100644
--- a/spec/requests/api/graphql/project/pipeline_spec.rb
+++ b/spec/requests/api/graphql/project/pipeline_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'getting pipeline information nested in a project' do
+RSpec.describe 'getting pipeline information nested in a project', feature_category: :continuous_integration do
include GraphqlHelpers
let_it_be(:project) { create(:project, :repository, :public) }
diff --git a/spec/requests/api/graphql/project/project_members_spec.rb b/spec/requests/api/graphql/project/project_members_spec.rb
index 97a79ab3b0e..1f1d8027592 100644
--- a/spec/requests/api/graphql/project/project_members_spec.rb
+++ b/spec/requests/api/graphql/project/project_members_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'getting project members information' do
+RSpec.describe 'getting project members information', feature_category: :projects do
include GraphqlHelpers
let_it_be(:parent_group) { create(:group, :public) }
diff --git a/spec/requests/api/graphql/project/project_pipeline_statistics_spec.rb b/spec/requests/api/graphql/project/project_pipeline_statistics_spec.rb
index 39a68d98d84..a13e96eb9d3 100644
--- a/spec/requests/api/graphql/project/project_pipeline_statistics_spec.rb
+++ b/spec/requests/api/graphql/project/project_pipeline_statistics_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'rendering project pipeline statistics' do
+RSpec.describe 'rendering project pipeline statistics', feature_category: :continuous_integration do
include GraphqlHelpers
let_it_be(:project) { create(:project) }
diff --git a/spec/requests/api/graphql/project/project_statistics_spec.rb b/spec/requests/api/graphql/project/project_statistics_spec.rb
index b57c594c64f..d078659b954 100644
--- a/spec/requests/api/graphql/project/project_statistics_spec.rb
+++ b/spec/requests/api/graphql/project/project_statistics_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'rendering project statistics' do
+RSpec.describe 'rendering project statistics', feature_category: :project_statistics do
include GraphqlHelpers
let(:project) { create(:project) }
diff --git a/spec/requests/api/graphql/project/recent_issue_boards_query_spec.rb b/spec/requests/api/graphql/project/recent_issue_boards_query_spec.rb
index b3daf86c4af..ae459fd26fb 100644
--- a/spec/requests/api/graphql/project/recent_issue_boards_query_spec.rb
+++ b/spec/requests/api/graphql/project/recent_issue_boards_query_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'getting project recent issue boards' do
+RSpec.describe 'getting project recent issue boards', feature_category: :team_planning do
include GraphqlHelpers
it_behaves_like 'querying a GraphQL type recent boards' do
diff --git a/spec/requests/api/graphql/project/release_spec.rb b/spec/requests/api/graphql/project/release_spec.rb
index c4899dbb71e..477388585ca 100644
--- a/spec/requests/api/graphql/project/release_spec.rb
+++ b/spec/requests/api/graphql/project/release_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Query.project(fullPath).release(tagName)' do
+RSpec.describe 'Query.project(fullPath).release(tagName)', feature_category: :release_orchestration do
include GraphqlHelpers
include Presentable
diff --git a/spec/requests/api/graphql/project/releases_spec.rb b/spec/requests/api/graphql/project/releases_spec.rb
index c28a6fa7666..aa454349fcf 100644
--- a/spec/requests/api/graphql/project/releases_spec.rb
+++ b/spec/requests/api/graphql/project/releases_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Query.project(fullPath).releases()' do
+RSpec.describe 'Query.project(fullPath).releases()', feature_category: :release_orchestration do
include GraphqlHelpers
let_it_be(:stranger) { create(:user) }
diff --git a/spec/requests/api/graphql/project/repository/blobs_spec.rb b/spec/requests/api/graphql/project/repository/blobs_spec.rb
index ba87f1100f2..a4ee0910d30 100644
--- a/spec/requests/api/graphql/project/repository/blobs_spec.rb
+++ b/spec/requests/api/graphql/project/repository/blobs_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
require 'spec_helper'
-RSpec.describe 'getting blobs in a project repository' do
+RSpec.describe 'getting blobs in a project repository', feature_category: :source_code_management do
include GraphqlHelpers
let(:project) { create(:project, :repository) }
diff --git a/spec/requests/api/graphql/project/repository_spec.rb b/spec/requests/api/graphql/project/repository_spec.rb
index b00f64c3db6..9f4d69c7b17 100644
--- a/spec/requests/api/graphql/project/repository_spec.rb
+++ b/spec/requests/api/graphql/project/repository_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
require 'spec_helper'
-RSpec.describe 'getting a repository in a project' do
+RSpec.describe 'getting a repository in a project', feature_category: :source_code_management do
include GraphqlHelpers
let(:project) { create(:project, :repository) }
diff --git a/spec/requests/api/graphql/project/runners_spec.rb b/spec/requests/api/graphql/project/runners_spec.rb
new file mode 100644
index 00000000000..7304de7bec6
--- /dev/null
+++ b/spec/requests/api/graphql/project/runners_spec.rb
@@ -0,0 +1,68 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'Project.runners', feature_category: :runner do
+ include GraphqlHelpers
+
+ let_it_be(:user) { create(:user) }
+ let_it_be(:group) { create(:group, :public) }
+ let_it_be(:project) { create(:project, :public, group: group) }
+ let_it_be(:instance_runner) { create(:ci_runner, :instance) }
+ let_it_be(:project_runner) { create(:ci_runner, :project, projects: [project]) }
+ let_it_be(:group_runner) { create(:ci_runner, :group, groups: [group]) }
+ let_it_be(:other_project) { create(:project, :repository, :public) }
+ let_it_be(:other_project_runner) { create(:ci_runner, :project, projects: [other_project]) }
+
+ let_it_be(:query) do
+ %(
+ query {
+ project(fullPath: "#{project.full_path}") {
+ runners {
+ nodes {
+ id
+ }
+ }
+ }
+ }
+ )
+ end
+
+ context 'when the user is a project admin' do
+ before do
+ project.add_maintainer(user)
+ end
+
+ let(:expected_ids) { [project_runner, group_runner, instance_runner].map { |g| g.to_global_id.to_s } }
+
+ it 'returns all runners available to project' do
+ post_graphql(query, current_user: user)
+
+ expect(graphql_data_at(:project, :runners, :nodes).pluck('id')).to match_array(expected_ids)
+ end
+ end
+
+ context 'when the user is a project developer' do
+ before do
+ project.add_developer(user)
+ end
+
+ it 'returns no runners' do
+ post_graphql(query, current_user: user)
+
+ expect(graphql_data_at(:project, :runners, :nodes)).to be_empty
+ end
+ end
+
+ context 'when on_demand_scans_runner_tags feature flag is disabled' do
+ before do
+ stub_feature_flags(on_demand_scans_runner_tags: false)
+ end
+
+ it 'returns no runners' do
+ post_graphql(query, current_user: user)
+
+ expect(graphql_data_at(:project, :runners, :nodes)).to be_empty
+ end
+ end
+end
diff --git a/spec/requests/api/graphql/project/terraform/state_spec.rb b/spec/requests/api/graphql/project/terraform/state_spec.rb
index 5e207ec0963..1889e7a1064 100644
--- a/spec/requests/api/graphql/project/terraform/state_spec.rb
+++ b/spec/requests/api/graphql/project/terraform/state_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'query a single terraform state' do
+RSpec.describe 'query a single terraform state', feature_category: :infrastructure_as_code do
include GraphqlHelpers
include ::API::Helpers::RelatedResourcesHelpers
diff --git a/spec/requests/api/graphql/project/terraform/states_spec.rb b/spec/requests/api/graphql/project/terraform/states_spec.rb
index cc3660bcc6b..25fc07ef509 100644
--- a/spec/requests/api/graphql/project/terraform/states_spec.rb
+++ b/spec/requests/api/graphql/project/terraform/states_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'query terraform states' do
+RSpec.describe 'query terraform states', feature_category: :infrastructure_as_code do
include GraphqlHelpers
include ::API::Helpers::RelatedResourcesHelpers
diff --git a/spec/requests/api/graphql/project/tree/tree_spec.rb b/spec/requests/api/graphql/project/tree/tree_spec.rb
index e63e0d3dd04..77b72bf39a1 100644
--- a/spec/requests/api/graphql/project/tree/tree_spec.rb
+++ b/spec/requests/api/graphql/project/tree/tree_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
require 'spec_helper'
-RSpec.describe 'getting a tree in a project' do
+RSpec.describe 'getting a tree in a project', feature_category: :source_code_management do
include GraphqlHelpers
let_it_be(:project) { create(:project, :repository) }
@@ -166,6 +166,54 @@ RSpec.describe 'getting a tree in a project' do
end
end
+ context 'when the ref points to a SSH-signed commit' do
+ let_it_be(:ref) { 'ssh-signed-commit' }
+ let_it_be(:commit) { project.commit(ref) }
+ let_it_be(:current_user) { create(:user, email: commit.committer_email).tap { |user| project.add_owner(user) } }
+
+ let(:fields) do
+ <<~QUERY
+ tree(path:"#{path}", ref:"#{ref}") {
+ lastCommit {
+ signature {
+ ... on SshSignature {
+ #{all_graphql_fields_for('SshSignature'.classify, max_depth: 2)}
+ }
+ }
+ }
+ }
+ QUERY
+ end
+
+ let_it_be(:key) do
+ create(:key, user: current_user, key: extract_public_key_from_commit(commit), expires_at: 2.days.from_now)
+ end
+
+ def extract_public_key_from_commit(commit)
+ ssh_commit = Gitlab::Ssh::Commit.new(commit)
+ signature_data = ::SSHData::Signature.parse_pem(ssh_commit.signature_text)
+ signature_data.public_key.openssh
+ end
+
+ before do
+ post_graphql(query, current_user: current_user)
+ end
+
+ it 'returns the expected signature data' do
+ signature = graphql_data['project']['repository']['tree']['lastCommit']['signature']
+
+ expect(signature['commitSha']).to eq(commit.id)
+ expect(signature['verificationStatus']).to eq('VERIFIED')
+ expect(signature['project']['id']).to eq("gid://gitlab/Project/#{project.id}")
+ expect(signature['user']['id']).to eq("gid://gitlab/User/#{current_user.id}")
+ expect(signature['key']['id']).to eq("gid://gitlab/Key/#{key.id}")
+ expect(signature['key']['title']).to eq(key.title)
+ expect(signature['key']['createdAt']).to be_present
+ expect(signature['key']['expiresAt']).to be_present
+ expect(signature['key']['key']).to match(key.key)
+ end
+ end
+
context 'when current user is nil' do
it 'returns empty project' do
post_graphql(query, current_user: nil)
diff --git a/spec/requests/api/graphql/project/work_item_types_spec.rb b/spec/requests/api/graphql/project/work_item_types_spec.rb
index 3d30baab816..c31a260c4b8 100644
--- a/spec/requests/api/graphql/project/work_item_types_spec.rb
+++ b/spec/requests/api/graphql/project/work_item_types_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'getting a list of work item types for a project' do
+RSpec.describe 'getting a list of work item types for a project', feature_category: :team_planning do
include GraphqlHelpers
let_it_be(:developer) { create(:user) }
diff --git a/spec/requests/api/graphql/project/work_items_spec.rb b/spec/requests/api/graphql/project/work_items_spec.rb
index 6d20799c9ec..a59da706a8a 100644
--- a/spec/requests/api/graphql/project/work_items_spec.rb
+++ b/spec/requests/api/graphql/project/work_items_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'getting a work item list for a project' do
+RSpec.describe 'getting a work item list for a project', feature_category: :team_planning do
include GraphqlHelpers
let_it_be(:group) { create(:group) }
@@ -93,6 +93,11 @@ RSpec.describe 'getting a work item list for a project' do
}
... on WorkItemWidgetHierarchy {
parent { id }
+ children {
+ nodes {
+ id
+ }
+ }
}
... on WorkItemWidgetLabels {
labels { nodes { id } }
@@ -112,6 +117,57 @@ RSpec.describe 'getting a work item list for a project' do
end
end
+ context 'when querying WorkItemWidgetHierarchy' do
+ let_it_be(:children) { create_list(:work_item, 3, :task, project: project) }
+ let_it_be(:child_link1) { create(:parent_link, work_item_parent: item1, work_item: children[0]) }
+
+ let(:fields) do
+ <<~GRAPHQL
+ nodes {
+ widgets {
+ type
+ ... on WorkItemWidgetHierarchy {
+ hasChildren
+ parent { id }
+ children { nodes { id } }
+ }
+ }
+ }
+ GRAPHQL
+ end
+
+ it 'executes limited number of N+1 queries' do
+ post_graphql(query, current_user: current_user) # warm-up
+
+ control = ActiveRecord::QueryRecorder.new do
+ post_graphql(query, current_user: current_user)
+ end
+
+ parent_work_items = create_list(:work_item, 2, project: project)
+ create(:parent_link, work_item_parent: parent_work_items[0], work_item: children[1])
+ create(:parent_link, work_item_parent: parent_work_items[1], work_item: children[2])
+
+ # There are 2 extra queries for fetching the children field
+ # See: https://gitlab.com/gitlab-org/gitlab/-/issues/363569
+ expect { post_graphql(query, current_user: current_user) }
+ .not_to exceed_query_limit(control).with_threshold(2)
+ end
+
+ it 'avoids N+1 queries when children are added to a work item' do
+ post_graphql(query, current_user: current_user) # warm-up
+
+ control = ActiveRecord::QueryRecorder.new do
+ post_graphql(query, current_user: current_user)
+ end
+
+ create(:parent_link, work_item_parent: item1, work_item: children[1])
+ create(:parent_link, work_item_parent: item1, work_item: children[2])
+
+ expect { post_graphql(query, current_user: current_user) }
+ .not_to exceed_query_limit(control)
+ end
+ end
+
it_behaves_like 'a working graphql query' do
before do
post_graphql(query, current_user: current_user)
@@ -188,6 +244,60 @@ RSpec.describe 'getting a work item list for a project' do
end
end
+ describe 'fetching work item notes widget' do
+ let(:item_filter_params) { { iid: item2.iid.to_s } }
+ let(:fields) do
+ <<~GRAPHQL
+ edges {
+ node {
+ widgets {
+ type
+ ... on WorkItemWidgetNotes {
+ system: discussions(filter: ONLY_ACTIVITY, first: 10) { nodes { id notes { nodes { id system internal body } } } },
+ comments: discussions(filter: ONLY_COMMENTS, first: 10) { nodes { id notes { nodes { id system internal body } } } },
+ all_notes: discussions(filter: ALL_NOTES, first: 10) { nodes { id notes { nodes { id system internal body } } } }
+ }
+ }
+ }
+ }
+ GRAPHQL
+ end
+
+ before do
+ create_notes(item1, "some note1")
+ create_notes(item2, "some note2")
+ end
+
+ shared_examples 'fetches work item notes' do |user_comments_count:, system_notes_count:|
+ it "fetches notes" do
+ post_graphql(query, current_user: current_user)
+
+ all_widgets = graphql_dig_at(items_data, :node, :widgets)
+ notes_widget = all_widgets.find { |x| x["type"] == "NOTES" }
+
+ all_notes = graphql_dig_at(notes_widget["all_notes"], :nodes)
+ system_notes = graphql_dig_at(notes_widget["system"], :nodes)
+ comments = graphql_dig_at(notes_widget["comments"], :nodes)
+
+ expect(comments.count).to eq(user_comments_count)
+ expect(system_notes.count).to eq(system_notes_count)
+ expect(all_notes.count).to eq(user_comments_count + system_notes_count)
+ end
+ end
+
+ context 'when user has permission to view internal notes' do
+ before do
+ project.add_developer(current_user)
+ end
+
+ it_behaves_like 'fetches work item notes', user_comments_count: 2, system_notes_count: 5
+ end
+
+ context 'when user cannot view internal notes' do
+ it_behaves_like 'fetches work item notes', user_comments_count: 1, system_notes_count: 5
+ end
+ end
+
def item_ids
graphql_dig_at(items_data, :node, :id)
end
@@ -199,4 +309,26 @@ RSpec.describe 'getting a work item list for a project' do
query_graphql_field('workItems', params, fields)
)
end
+
+ def create_notes(work_item, note_body)
+ create(:note, system: true, project: work_item.project, noteable: work_item)
+
+ disc_start = create(:discussion_note_on_issue, noteable: work_item, project: work_item.project, note: note_body)
+ create(:note,
+ discussion_id: disc_start.discussion_id, noteable: work_item,
+ project: work_item.project, note: "reply on #{note_body}")
+
+ create(:resource_label_event, user: current_user, issue: work_item, label: label1, action: 'add')
+ create(:resource_label_event, user: current_user, issue: work_item, label: label1, action: 'remove')
+
+ create(:resource_milestone_event, issue: work_item, milestone: milestone1, action: 'add')
+ create(:resource_milestone_event, issue: work_item, milestone: milestone1, action: 'remove')
+
+ # confidential notes are currently available only on issues and epics
+ conf_disc_start = create(:discussion_note_on_issue, :confidential,
+ noteable: work_item, project: work_item.project, note: "confidential #{note_body}")
+ create(:note, :confidential,
+ discussion_id: conf_disc_start.discussion_id, noteable: work_item,
+ project: work_item.project, note: "reply on confidential #{note_body}")
+ end
end
diff --git a/spec/requests/api/graphql/project_query_spec.rb b/spec/requests/api/graphql/project_query_spec.rb
index d1b990629a1..281a08e6548 100644
--- a/spec/requests/api/graphql/project_query_spec.rb
+++ b/spec/requests/api/graphql/project_query_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'getting project information' do
+RSpec.describe 'getting project information', feature_category: :projects do
include GraphqlHelpers
let_it_be(:group) { create(:group) }
diff --git a/spec/requests/api/graphql/query_spec.rb b/spec/requests/api/graphql/query_spec.rb
index 359c599cd3a..2b9d66ec744 100644
--- a/spec/requests/api/graphql/query_spec.rb
+++ b/spec/requests/api/graphql/query_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Query' do
+RSpec.describe 'Query', feature_category: :not_owned do
include GraphqlHelpers
let_it_be(:project) { create(:project) }
diff --git a/spec/requests/api/graphql/read_only_spec.rb b/spec/requests/api/graphql/read_only_spec.rb
index d2a45603886..aec8d3151c8 100644
--- a/spec/requests/api/graphql/read_only_spec.rb
+++ b/spec/requests/api/graphql/read_only_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Requests on a read-only node' do
+RSpec.describe 'Requests on a read-only node', feature_category: :database do
context 'when db is read-only' do
before do
allow(Gitlab::Database).to receive(:read_only?) { true }
diff --git a/spec/requests/api/graphql/snippets_spec.rb b/spec/requests/api/graphql/snippets_spec.rb
index 9edd805678a..3cd95b0841c 100644
--- a/spec/requests/api/graphql/snippets_spec.rb
+++ b/spec/requests/api/graphql/snippets_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'snippets' do
+RSpec.describe 'snippets', feature_category: :source_code_management do
include GraphqlHelpers
let_it_be(:current_user) { create(:user) }
diff --git a/spec/requests/api/graphql/tasks/task_completion_status_spec.rb b/spec/requests/api/graphql/tasks/task_completion_status_spec.rb
index 5f4d2aec718..ea89487c176 100644
--- a/spec/requests/api/graphql/tasks/task_completion_status_spec.rb
+++ b/spec/requests/api/graphql/tasks/task_completion_status_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'getting task completion status information' do
+RSpec.describe 'getting task completion status information', feature_category: :team_planning do
include GraphqlHelpers
description_0_done = '- [ ] task 1\n- [ ] task 2'
diff --git a/spec/requests/api/graphql/terraform/state/delete_spec.rb b/spec/requests/api/graphql/terraform/state/delete_spec.rb
index ba0619ea611..f4af402492c 100644
--- a/spec/requests/api/graphql/terraform/state/delete_spec.rb
+++ b/spec/requests/api/graphql/terraform/state/delete_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'delete a terraform state' do
+RSpec.describe 'delete a terraform state', feature_category: :infrastructure_as_code do
include GraphqlHelpers
let_it_be(:project) { create(:project) }
diff --git a/spec/requests/api/graphql/terraform/state/lock_spec.rb b/spec/requests/api/graphql/terraform/state/lock_spec.rb
index e4d3b6336ab..4219f4f4651 100644
--- a/spec/requests/api/graphql/terraform/state/lock_spec.rb
+++ b/spec/requests/api/graphql/terraform/state/lock_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'lock a terraform state' do
+RSpec.describe 'lock a terraform state', feature_category: :infrastructure_as_code do
include GraphqlHelpers
let_it_be(:project) { create(:project) }
diff --git a/spec/requests/api/graphql/terraform/state/unlock_spec.rb b/spec/requests/api/graphql/terraform/state/unlock_spec.rb
index e90730f2d8f..84ccc09711d 100644
--- a/spec/requests/api/graphql/terraform/state/unlock_spec.rb
+++ b/spec/requests/api/graphql/terraform/state/unlock_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'unlock a terraform state' do
+RSpec.describe 'unlock a terraform state', feature_category: :infrastructure_as_code do
include GraphqlHelpers
let_it_be(:project) { create(:project) }
diff --git a/spec/requests/api/graphql/todo_query_spec.rb b/spec/requests/api/graphql/todo_query_spec.rb
index 7fe19448083..b8ce065dbbb 100644
--- a/spec/requests/api/graphql/todo_query_spec.rb
+++ b/spec/requests/api/graphql/todo_query_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Todo Query' do
+RSpec.describe 'Todo Query', feature_category: :team_planning do
include GraphqlHelpers
let_it_be(:current_user) { nil }
diff --git a/spec/requests/api/graphql/usage_trends_measurements_spec.rb b/spec/requests/api/graphql/usage_trends_measurements_spec.rb
index 78a4321f522..68b97fbb130 100644
--- a/spec/requests/api/graphql/usage_trends_measurements_spec.rb
+++ b/spec/requests/api/graphql/usage_trends_measurements_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'UsageTrendsMeasurements' do
+RSpec.describe 'UsageTrendsMeasurements', feature_category: :devops_reports do
include GraphqlHelpers
let(:current_user) { create(:user, :admin) }
diff --git a/spec/requests/api/graphql/user/group_member_query_spec.rb b/spec/requests/api/graphql/user/group_member_query_spec.rb
index e47cef8cc37..d09cb319877 100644
--- a/spec/requests/api/graphql/user/group_member_query_spec.rb
+++ b/spec/requests/api/graphql/user/group_member_query_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'GroupMember' do
+RSpec.describe 'GroupMember', feature_category: :subgroups do
include GraphqlHelpers
let_it_be(:member) { create(:group_member, :developer) }
diff --git a/spec/requests/api/graphql/user/project_member_query_spec.rb b/spec/requests/api/graphql/user/project_member_query_spec.rb
index 01827e94d5d..1baa7815793 100644
--- a/spec/requests/api/graphql/user/project_member_query_spec.rb
+++ b/spec/requests/api/graphql/user/project_member_query_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'ProjectMember' do
+RSpec.describe 'ProjectMember', feature_category: :subgroups do
include GraphqlHelpers
let_it_be(:member) { create(:project_member, :developer) }
diff --git a/spec/requests/api/graphql/user/starred_projects_query_spec.rb b/spec/requests/api/graphql/user/starred_projects_query_spec.rb
index 75a17ed34c4..7d4284300d8 100644
--- a/spec/requests/api/graphql/user/starred_projects_query_spec.rb
+++ b/spec/requests/api/graphql/user/starred_projects_query_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Getting starredProjects of the user' do
+RSpec.describe 'Getting starredProjects of the user', feature_category: :projects do
include GraphqlHelpers
let(:query) do
diff --git a/spec/requests/api/graphql/user_query_spec.rb b/spec/requests/api/graphql/user_query_spec.rb
index 8f286180617..ca319ed1b2e 100644
--- a/spec/requests/api/graphql/user_query_spec.rb
+++ b/spec/requests/api/graphql/user_query_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'getting user information' do
+RSpec.describe 'getting user information', feature_category: :user_management do
include GraphqlHelpers
let(:query) do
diff --git a/spec/requests/api/graphql/user_spec.rb b/spec/requests/api/graphql/user_spec.rb
index a3b2b750bc3..2e1e4971767 100644
--- a/spec/requests/api/graphql/user_spec.rb
+++ b/spec/requests/api/graphql/user_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'User' do
+RSpec.describe 'User', feature_category: :users do
include GraphqlHelpers
let_it_be(:current_user) { create(:user) }
diff --git a/spec/requests/api/graphql/users_spec.rb b/spec/requests/api/graphql/users_spec.rb
index 79ee3c2cb57..83c360fdaf8 100644
--- a/spec/requests/api/graphql/users_spec.rb
+++ b/spec/requests/api/graphql/users_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Users' do
+RSpec.describe 'Users', feature_category: :user_management do
include GraphqlHelpers
let_it_be(:user0) { create(:user, created_at: 1.day.ago) }
diff --git a/spec/requests/api/graphql/work_item_spec.rb b/spec/requests/api/graphql/work_item_spec.rb
index a55de6adfb2..df7dbaea420 100644
--- a/spec/requests/api/graphql/work_item_spec.rb
+++ b/spec/requests/api/graphql/work_item_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Query.work_item(id)' do
+RSpec.describe 'Query.work_item(id)', feature_category: :team_planning do
include GraphqlHelpers
let_it_be(:developer) { create(:user) }
@@ -116,6 +116,7 @@ RSpec.describe 'Query.work_item(id)' do
id
}
}
+ hasChildren
}
}
GRAPHQL
@@ -132,7 +133,8 @@ RSpec.describe 'Query.work_item(id)' do
[
hash_including('id' => child_link1.work_item.to_gid.to_s),
hash_including('id' => child_link2.work_item.to_gid.to_s)
- ]) }
+ ]) },
+ 'hasChildren' => true
)
)
)
@@ -165,7 +167,8 @@ RSpec.describe 'Query.work_item(id)' do
'children' => { 'nodes' => match_array(
[
hash_including('id' => child_link1.work_item.to_gid.to_s)
- ]) }
+ ]) },
+ 'hasChildren' => true
)
)
)
@@ -183,7 +186,8 @@ RSpec.describe 'Query.work_item(id)' do
hash_including(
'type' => 'HIERARCHY',
'parent' => hash_including('id' => parent_link.work_item_parent.to_gid.to_s),
- 'children' => { 'nodes' => match_array([]) }
+ 'children' => { 'nodes' => match_array([]) },
+ 'hasChildren' => false
)
)
)