Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2023-08-07 15:09:47 +00:00
parent 28f0cd8e07
commit 33c86930e0
23 changed files with 229 additions and 430 deletions

View File

@ -78,7 +78,7 @@
.settings-section::after {
content: '';
display: block;
@include gl-pb-7;
@include gl-mb-7;
}
.settings-section,

View File

@ -61,14 +61,10 @@ module Mutations
end
end
def resolve(args)
annotation_response = ::Metrics::Dashboard::Annotations::CreateService.new(context[:current_user], annotation_create_params(args)).execute
annotation = annotation_response[:annotation]
def resolve(_args)
{
annotation: annotation.valid? ? annotation : nil,
errors: errors_on_object(annotation)
annotation: nil,
errors: []
}
end

View File

@ -1,40 +0,0 @@
# frozen_string_literal: true
# Base class for embed services. Contains a few basic helper
# methods that the embed services share.
module Metrics
module Dashboard
class BaseEmbedService < ::Metrics::Dashboard::BaseService
def self.embedded?(embed_param)
ActiveModel::Type::Boolean.new.cast(embed_param)
end
def cache_key
"dynamic_metrics_dashboard_#{identifiers}"
end
protected
def dashboard_path
params[:dashboard_path].presence ||
::Metrics::Dashboard::SystemDashboardService::DASHBOARD_PATH
end
def group
params[:group]
end
def title
params[:title]
end
def y_label
params[:y_label]
end
def identifiers
[dashboard_path, group, title, y_label].join('|')
end
end
end
end

View File

@ -21,7 +21,7 @@ ClickHouse::Client.configure do |config|
config.http_post_proc = ->(url, headers, body) do
options = {
headers: headers,
body: body,
body: ActiveSupport::Gzip.compress(body),
allow_local_requests: Rails.env.development? || Rails.env.test?
}

View File

@ -0,0 +1,19 @@
# frozen_string_literal: true
class AddUniqueIndexProjectAuthorizationsOnUniqueProjectUser < Gitlab::Database::Migration[2.1]
INDEX_NAME = 'index_unique_project_authorizations_on_unique_project_user'
disable_ddl_transaction!
def up
add_concurrent_index :project_authorizations,
%i[project_id user_id],
unique: true,
where: "is_unique",
name: INDEX_NAME
end
def down
remove_concurrent_index_by_name :project_authorizations, INDEX_NAME
end
end

View File

@ -0,0 +1 @@
e43d57a88d6dce76867753e349850c7d405397c3356b263ced5ffb47922850f1

View File

@ -33492,6 +33492,8 @@ CREATE UNIQUE INDEX index_unique_ci_runner_projects_on_runner_id_and_project_id
CREATE UNIQUE INDEX index_unique_issue_metrics_issue_id ON issue_metrics USING btree (issue_id);
CREATE UNIQUE INDEX index_unique_project_authorizations_on_unique_project_user ON project_authorizations USING btree (project_id, user_id) WHERE is_unique;
CREATE INDEX index_unit_test_failures_failed_at ON ci_unit_test_failures USING btree (failed_at DESC);
CREATE UNIQUE INDEX index_unit_test_failures_unique_columns ON ci_unit_test_failures USING btree (unit_test_id, failed_at DESC, build_id);

View File

@ -283,6 +283,36 @@ If the merge train pipeline was canceled before the merge request was merged, wi
- Add it to the train again.
### Merge request rules widget shows a scan result policy is invalid or duplicated **(ULTIMATE SELF)**
On GitLab self-managed 15.0 and later, the most likely cause is that the project was exported from a
group and imported into another, and had scan result policy rules. These rules are stored in a
separate project to the one that was exported. As a result, the project contains policy rules that
reference entities that don't exist in the imported project's group. The result is policy rules that
are invalid, duplicated, or both.
To remove all invalid scan result policy rules from a GitLab instance, an administrator can run
the following script in the [Rails console](../administration/operations/rails_console.md).
```ruby
Project.joins(:approval_rules).where(approval_rules: { report_type: %i[scan_finding license_scanning] }).where.not(approval_rules: { security_orchestration_policy_configuration_id: nil }).find_in_batches.flat_map do |batch|
batch.map do |project|
# Get projects and their configuration_ids for applicable project rules
[project, project.approval_rules.where(report_type: %i[scan_finding license_scanning]).pluck(:security_orchestration_policy_configuration_id).uniq]
end.uniq.map do |project, configuration_ids| # We take only unique combinations of project + configuration_ids
# If we find more configurations than what is available for the project, we take records with the extra configurations
[project, configuration_ids - project.all_security_orchestration_policy_configurations.pluck(:id)]
end.select { |_project, configuration_ids| configuration_ids.any? }
end.each do |project, configuration_ids|
# For each found pair project + ghost configuration, we remove these rules for a given project
Security::OrchestrationPolicyConfiguration.where(id: configuration_ids).each do |configuration|
configuration.delete_scan_finding_rules_for_project(project.id)
end
# Ensure we sync any potential rules from new group's policy
Security::ScanResultPolicies::SyncProjectWorker.perform_async(project.id)
end
```
### Project `group/project` not found or access denied
This message is shown if configuration is added with [`include`](yaml/index.md#include) and one of the following:

View File

@ -847,11 +847,12 @@ Sometimes they are more precise and will be maintained more actively.
For each external link you add, weigh the customer benefit with the maintenance difficulties.
### Links that require permissions
### Confidential or restricted access links
Don't link directly to:
- [Confidential issues](../../../user/project/issues/confidential_issues.md).
- Internal handbook pages.
- Project features that require [special permissions](../../../user/permissions.md)
to view.
@ -862,8 +863,8 @@ These links fail for:
If you must use one of these links:
- If the link is to a confidential issue, mention that the issue is visible only to GitLab team members, as in the first example.
- If the link requires a specific role or permissions, mention that information, as in the second example.
- If the link is to a confidential issue or internal handbook page, mention that the issue or page is visible only to GitLab team members.
- If the link requires a specific role or permissions, mention that information.
- Put the link in backticks so that it does not cause link checkers to fail.
Examples:
@ -873,6 +874,9 @@ GitLab team members can view more information in this confidential issue:
`https://gitlab.com/gitlab-org/gitlab/-/issues/<issue_number>`
```
GitLab team members can view more information in this internal handbook page:
`https://internal.gitlab.com/handbook/<link>`
```markdown
Users with the Maintainer role for the project can use the pipeline editor:
`https://gitlab.com/gitlab-org/gitlab/-/ci/editor`

View File

@ -49,6 +49,16 @@ The following feature is in Beta:
[Experiment](../policy/experiment-beta-support.md#experiment) AI features require
[Experiment features to be enabled](group/manage.md#enable-experiment-features) as well as [third-party AI services to be enabled](group/manage.md#enable-third-party-ai-features).
The following features are in Experiment:
- [Fill in merge request templates](project/merge_requests/ai_in_merge_requests.md#fill-in-merge-request-templates)
- [Summarize merge request changes](project/merge_requests/ai_in_merge_requests.md#summarize-merge-request-changes)
- [Summarize my merge request review](project/merge_requests/ai_in_merge_requests.md#summarize-my-merge-request-review)
- [Suggested merge or squash commit message](project/merge_requests/ai_in_merge_requests.md#suggested-merge-or-squash-commit-message)
- [Generate suggested tests in merge requests](project/merge_requests/ai_in_merge_requests.md#generate-suggested-tests-in-merge-requests)
The rest of the features described on this page are also in the Experiment phase.
### Explain Selected Code in the Web UI **(ULTIMATE SAAS)**
> Introduced in GitLab 15.11 as an [Experiment](../policy/experiment-beta-support.md#experiment) on GitLab.com.
@ -177,66 +187,6 @@ Or, you can add a comment in the [feedback issue](https://gitlab.com/gitlab-org/
NOTE:
Only the last 50 messages are retained in the chat history. The chat history expires 3 days after last use.
### Summarize merge request changes **(ULTIMATE SAAS)**
> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/10401) in GitLab 16.2 as an [Experiment](../policy/experiment-beta-support.md#experiment).
This feature is an [Experiment](../policy/experiment-beta-support.md) on GitLab.com that is powered by OpenAI's GPT-3. It requires the [group-level third-party AI features setting](group/manage.md#enable-third-party-ai-features) to be enabled.
These summaries are automatically generated. They are available on the merge request page in the **Merge request summaries** dialog, the To-Do list, and in email notifications.
Provide feedback on this experimental feature in [issue 408726](https://gitlab.com/gitlab-org/gitlab/-/issues/408726).
**Data usage**: When using this quick action, the diff of changes between the source branch's head and the target branch is sent to the large language model.
### Summarize my merge request review **(ULTIMATE SAAS)**
> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/10466) in GitLab 16.0 as an [Experiment](../policy/experiment-beta-support.md#experiment).
This feature is an [Experiment](../policy/experiment-beta-support.md) on GitLab.com that is powered by OpenAI's GPT-3. It requires the [group-level third-party AI features setting](group/manage.md#enable-third-party-ai-features) to be enabled.
When you've completed your review of a merge request and are ready to [submit your review](project/merge_requests/reviews/index.md#submit-a-review), you can have a summary generated for you.
To generate the summary:
1. When you are ready to submit your review, select **Finish review**.
1. Select **AI Actions** (**{tanuki}**).
1. Select **Summarize my code review**.
The summary is displayed in the comment box. You can edit and refine the summary prior to submitting your review.
Provide feedback on this experimental feature in [issue 408991](https://gitlab.com/gitlab-org/gitlab/-/issues/408991).
**Data usage**: When you use this feature, the following data is sent to the large language model referenced above:
- Draft comment's text
- File path of the commented files
### Generate suggested tests in merge requests **(ULTIMATE SAAS)**
> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/10366) in GitLab 16.0 as an [Experiment](../policy/experiment-beta-support.md#experiment).
This feature is an [Experiment](../policy/experiment-beta-support.md) on GitLab.com that is powered by OpenAI's GPT-3. It requires the [group-level third-party AI features setting](group/manage.md#enable-third-party-ai-features) to be enabled.
In a merge request, you can get a list of suggested tests for the file you are reviewing. This functionality can help determine if appropriate test coverage has been provided, or if you need more coverage for your project.
View a [click-through demo](https://go.gitlab.com/Xfp0l4).
To generate a test suggestion:
1. In a merge request, select the **Changes** tab.
1. On the header for the file, in the upper-right corner, select **Options** (**{ellipsis_v}**).
1. Select **Suggest test cases**.
The test suggestion is generated in a sidebar. You can copy the suggestion to your editor and use it as the start of your tests.
Feedback on this experimental feature can be provided in [issue 408995](https://gitlab.com/gitlab-org/gitlab/-/issues/408995).
**Data usage**: When you use this feature, the following data is sent to the large language model referenced above:
- Contents of the file
- The filename
### Summarize issue discussions **(ULTIMATE SAAS)**
> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/10344) in GitLab 16.0 as an [Experiment](../policy/experiment-beta-support.md#experiment).

View File

@ -0,0 +1,120 @@
---
stage: Create
group: Code Review
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments
---
# AI/ML powered features in merge requests
AI-assisted features in merge requests are designed to provide contextually relevant information during the lifecycle of a merge request.
Additional information on enabling these features and maturity can be found in our [AI/ML Overview](../../ai_features.md).
## Fill in merge request templates **(ULTIMATE SAAS)**
> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/10591) in GitLab 16.3 as an [Experiment](../../../policy/experiment-beta-support.md#experiment).
This feature is an [Experiment](../../../policy/experiment-beta-support.md) on GitLab.com that is using Google's Vertex service and the `text-bison` model. It requires the [group-level third-party AI features setting](../../group/manage.md#enable-third-party-ai-features) to be enabled.
Merge requests in projects often have [templates](../description_templates.md#create-a-merge-request-template) defined that need to be filled out. This helps reviewers and other users understand the purpose and changes a merge request might propose.
When creating a merge request you can now choose to generate a description for the merge request based on the contents of the template. This fills in the template and replaces the current contents of the description.
To generate the description:
1. Create a new merge request, go to the **Description** field.
1. Select **AI Actions** (**{tanuki}**).
1. Select **Fill in merge request template**.
The updated description is applied to the box. You can edit or revise this description before you finish creating your merge request.
Provide feedback on this experimental feature in [issue 416537](https://gitlab.com/gitlab-org/gitlab/-/issues/416537).
**Data usage**: When you use this feature, the following data is sent to the large language model referenced above:
- Title of the merge request
- Contents of the description
- Source branch name
- Target branch name
## Summarize merge request changes **(ULTIMATE SAAS)**
> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/10401) in GitLab 16.2 as an [Experiment](../../../policy/experiment-beta-support.md#experiment).
This feature is an [Experiment](../../../policy/experiment-beta-support.md) on GitLab.com that is using Google's Vertex service and the `text-bison` model. It requires the [group-level third-party AI features setting](../../group/manage.md#enable-third-party-ai-features) to be enabled.
These summaries are automatically generated. They are available on the merge request page in the **Merge request summaries** dialog, the To-Do list, and in email notifications.
Provide feedback on this experimental feature in [issue 408726](https://gitlab.com/gitlab-org/gitlab/-/issues/408726).
**Data usage**: The diff of changes between the source branch's head and the target branch is sent to the large language model.
## Summarize my merge request review **(ULTIMATE SAAS)**
> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/10466) in GitLab 16.0 as an [Experiment](../../../policy/experiment-beta-support.md#experiment).
This feature is an [Experiment](../../../policy/experiment-beta-support.md) on GitLab.com that is using Google's Vertex service and the `text-bison` model. It requires the [group-level third-party AI features setting](../../group/manage.md#enable-third-party-ai-features) to be enabled.
When you've completed your review of a merge request and are ready to [submit your review](reviews/index.md#submit-a-review), you can have a summary generated for you.
To generate the summary:
1. When you are ready to submit your review, select **Finish review**.
1. Select **AI Actions** (**{tanuki}**).
1. Select **Summarize my code review**.
The summary is displayed in the comment box. You can edit and refine the summary prior to submitting your review.
Merge request review summaries are also automatically generated when you submit your review. These automatically generated summaries are available on the merge request page in the **Merge request summaries** dialog, the To-Do list, and in email notifications.
Provide feedback on this experimental feature in [issue 408991](https://gitlab.com/gitlab-org/gitlab/-/issues/408991).
**Data usage**: When you use this feature, the following data is sent to the large language model referenced above:
- Draft comment's text
## Suggested merge or squash commit message **(ULTIMATE SAAS)**
> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/10453) in GitLab 16.2 as an [Experiment](../../../policy/experiment-beta-support.md#experiment).
This feature is an [Experiment](../../../policy/experiment-beta-support.md) on GitLab.com that is using Google's Vertex service and the `text-bison` model. It requires the [group-level third-party AI features setting](../../group/manage.md#enable-third-party-ai-features) to be enabled.
When preparing to merge your merge request you may wish to edit the squash or merge commit message that will be used.
To generate a commit message:
1. Select the **Edit commit message** checkbox on the merge widget.
1. Select **Create AI-generated commit message**.
1. Review the commit message provide and choose **Insert** to add it to the commit.
Provide feedback on this experimental feature in [issue 408994](https://gitlab.com/gitlab-org/gitlab/-/issues/408994).
**Data usage**: When you use this feature, the following data is sent to the large language model referenced above:
- Contents of the file
- The filename
## Generate suggested tests in merge requests **(ULTIMATE SAAS)**
> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/10366) in GitLab 16.0 as an [Experiment](../../../policy/experiment-beta-support.md#experiment).
This feature is an [Experiment](../../../policy/experiment-beta-support.md) on GitLab.com that is using Google's Vertex service and the `text-bison` model. It requires the [group-level third-party AI features setting](../../group/manage.md#enable-third-party-ai-features) to be enabled.
In a merge request, you can get a list of suggested tests for the file you are reviewing. This functionality can help determine if appropriate test coverage has been provided, or if you need more coverage for your project.
View a [click-through demo](https://go.gitlab.com/Xfp0l4).
To generate a test suggestion:
1. In a merge request, select the **Changes** tab.
1. On the header for the file, in the upper-right corner, select **Options** (**{ellipsis_v}**).
1. Select **Suggest test cases**.
The test suggestion is generated in a sidebar. You can copy the suggestion to your editor and use it as the start of your tests.
Feedback on this experimental feature can be provided in [issue 408995](https://gitlab.com/gitlab-org/gitlab/-/issues/408995).
**Data usage**: When you use this feature, the following data is sent to the large language model referenced above:
- Contents of the file
- The filename

View File

@ -28,17 +28,7 @@ module ClickHouse
# Executes a SELECT database query
def self.select(query, database, configuration = self.configuration)
db = lookup_database(configuration, database)
ActiveSupport::Notifications.instrument('sql.click_house', { query: query, database: database }) do |instrument|
response = configuration.http_post_proc.call(
db.uri.to_s,
db.headers,
"#{query} FORMAT JSON" # always return JSON
)
raise DatabaseError, response.body unless response.success?
instrumented_execute(query, database, configuration) do |response, instrument|
parsed_response = configuration.json_parser.parse(response.body)
instrument[:statistics] = parsed_response['statistics']&.symbolize_keys
@ -49,17 +39,7 @@ module ClickHouse
# Executes any kinds of database query without returning any data (INSERT, DELETE)
def self.execute(query, database, configuration = self.configuration)
db = lookup_database(configuration, database)
ActiveSupport::Notifications.instrument('sql.click_house', { query: query, database: database }) do |instrument|
response = configuration.http_post_proc.call(
db.uri.to_s,
db.headers,
query
)
raise DatabaseError, response.body unless response.success?
instrumented_execute(query, database, configuration) do |response, instrument|
if response.headers['x-clickhouse-summary']
instrument[:statistics] =
Gitlab::Json.parse(response.headers['x-clickhouse-summary']).symbolize_keys
@ -74,5 +54,21 @@ module ClickHouse
raise ConfigurationError, "The database '#{database}' is not configured" unless db
end
end
private_class_method def self.instrumented_execute(query, database, configuration)
db = lookup_database(configuration, database)
ActiveSupport::Notifications.instrument('sql.click_house', { query: query, database: database }) do |instrument|
response = configuration.http_post_proc.call(
db.uri.to_s,
db.headers,
query
)
raise DatabaseError, response.body unless response.success?
yield response, instrument
end
end
end
end

View File

@ -10,7 +10,10 @@ module ClickHouse
@url = url
@username = username
@password = password
@variables = variables.merge(database: database).freeze
@variables = {
database: database,
enable_http_compression: 1 # enable HTTP compression by default
}.merge(variables).freeze
end
def uri
@ -24,7 +27,9 @@ module ClickHouse
def headers
@headers ||= {
'X-ClickHouse-User' => @username,
'X-ClickHouse-Key' => @password
'X-ClickHouse-Key' => @password,
'X-ClickHouse-Format' => 'JSON', # always return JSON data
'Content-Encoding' => 'gzip' # tell the server that we send compressed data
}.freeze
end
end

View File

@ -29,7 +29,7 @@ RSpec.describe ClickHouse::Client::Configuration do
expect(configuration.databases.size).to eq(1)
database = configuration.databases[:my_db]
expect(database.uri.to_s).to eq('http://localhost:3333?database=test_db&join_use_nulls=1')
expect(database.uri.to_s).to eq('http://localhost:3333?database=test_db&enable_http_compression=1&join_use_nulls=1')
end
context 'when adding the same DB multiple times' do

View File

@ -17,13 +17,15 @@ RSpec.describe ClickHouse::Client::Database do
describe '#uri' do
it 'builds the correct URL' do
expect(database.uri.to_s).to eq('http://localhost:3333?database=test_db&join_use_nulls=1')
expect(database.uri.to_s).to eq('http://localhost:3333?database=test_db&enable_http_compression=1&join_use_nulls=1')
end
end
describe '#headers' do
it 'returns the correct headers' do
expect(database.headers).to eq({
"Content-Encoding" => "gzip",
"X-ClickHouse-Format" => "JSON",
'X-ClickHouse-User' => 'user',
'X-ClickHouse-Key' => 'pass'
})

View File

@ -11,16 +11,9 @@ spec:
default: "gems/"
---
workflow:
name: '$PIPELINE_NAME'
name: '[$[[inputs.gem_name]] gem] Ruby $RUBY_VERSION pipeline'
rules:
- if: '$CI_MERGE_REQUEST_EVENT_TYPE == "merged_result" || $CI_MERGE_REQUEST_EVENT_TYPE == "detached"'
variables:
PIPELINE_NAME: '[$[[inputs.gem_name]] gem] Ruby $RUBY_VERSION $CI_MERGE_REQUEST_EVENT_TYPE MR pipeline'
# CI_PIPELINE_SOURCE will always be "parent_pipeline" since this is a child pipeline
# document this here to avoid confusion and to define the default value for PIPELINE_NAME
- if: '$CI_PIPELINE_SOURCE == "parent_pipeline"'
variables:
PIPELINE_NAME: '[$[[inputs.gem_name]] gem] Ruby $RUBY_VERSION default pipeline'
- when: always
variables:
BUNDLE_PATH: "vendor"

View File

@ -40,23 +40,7 @@ module API
end
post ':id/metrics_dashboard/annotations' do
not_found! if Feature.enabled?(:remove_monitor_metrics)
annotations_source_object = annotations_source[:class].find(params[:id])
forbidden! unless can?(current_user, :admin_metrics_dashboard_annotation, annotations_source_object)
create_service_params = declared(params).merge(
annotations_source[:create_service_param_key] => annotations_source_object
)
result = ::Metrics::Dashboard::Annotations::CreateService.new(current_user, create_service_params).execute
if result[:status] == :success
present result[:annotation], with: Entities::Metrics::Dashboard::Annotation
else
error!(result, 400)
end
not_found!
end
end
end

View File

@ -11512,7 +11512,7 @@ msgstr ""
msgid "CodeSuggestions|Enable Code Suggestions"
msgstr ""
msgid "CodeSuggestions|Get code suggestions as you write code in your IDE. %{link_start}Learn more.%{link_end}"
msgid "CodeSuggestions|Get code suggestions as you write code in your IDE. %{link_start}Learn more%{link_end}."
msgstr ""
msgid "CodeSuggestions|Projects in this group can use Code Suggestions"

View File

@ -14,7 +14,6 @@ RSpec.describe 'Database schema', feature_category: :database do
# but in Search::NamespaceIndexAssignment model, only `search_index_id` is used as foreign key and indexed
search_namespace_index_assignments: [%w[search_index_id index_type]],
slack_integrations_scopes: [%w[slack_api_scope_id]],
namespaces: %w[organization_id], # this index is added in an async manner, hence it needs to be ignored in the first phase.
notes: %w[namespace_id] # this index is added in an async manner, hence it needs to be ignored in the first phase.
}.with_indifferent_access.freeze

View File

@ -174,7 +174,7 @@ RSpec.describe 'User adds pages domain', :js, feature_category: :pages do
expect(domain.key).to be_nil
end
it 'shows the DNS ALIAS record' do
it 'shows the DNS ALIAS record', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/419686' do
visit project_pages_path(project)
within('#content-body') { click_link 'Edit' }

View File

@ -43,9 +43,6 @@ RSpec.describe Mutations::Metrics::Dashboard::Annotations::Create, feature_categ
project.add_reporter(current_user)
end
it_behaves_like 'a mutation that returns top-level errors',
errors: [Gitlab::Graphql::Authorize::AuthorizeResource::RESOURCE_ACCESS_ERROR]
it 'does not create the annotation' do
expect do
post_graphql_mutation(mutation, current_user: current_user)
@ -58,25 +55,6 @@ RSpec.describe Mutations::Metrics::Dashboard::Annotations::Create, feature_categ
project.add_developer(current_user)
end
it 'creates the annotation' do
expect do
post_graphql_mutation(mutation, current_user: current_user)
end.to change { Metrics::Dashboard::Annotation.count }.by(1)
end
it 'returns the created annotation' do
post_graphql_mutation(mutation, current_user: current_user)
annotation = Metrics::Dashboard::Annotation.first
annotation_id = GitlabSchema.id_from_object(annotation).to_s
expect(mutation_response['annotation']['description']).to match(description)
expect(mutation_response['annotation']['startingAt'].to_time).to match(starting_at.to_time)
expect(mutation_response['annotation']['endingAt'].to_time).to match(ending_at.to_time)
expect(mutation_response['annotation']['id']).to match(annotation_id)
expect(annotation.environment_id).to eq(environment.id)
end
context 'when environment_id is missing' do
let(:mutation) do
variables = {
@ -137,25 +115,6 @@ RSpec.describe Mutations::Metrics::Dashboard::Annotations::Create, feature_categ
project.add_developer(current_user)
end
it 'creates the annotation' do
expect do
post_graphql_mutation(mutation, current_user: current_user)
end.to change { Metrics::Dashboard::Annotation.count }.by(1)
end
it 'returns the created annotation' do
post_graphql_mutation(mutation, current_user: current_user)
annotation = Metrics::Dashboard::Annotation.first
annotation_id = GitlabSchema.id_from_object(annotation).to_s
expect(mutation_response['annotation']['description']).to match(description)
expect(mutation_response['annotation']['startingAt'].to_time).to match(starting_at.to_time)
expect(mutation_response['annotation']['endingAt'].to_time).to match(ending_at.to_time)
expect(mutation_response['annotation']['id']).to match(annotation_id)
expect(annotation.cluster_id).to eq(cluster.id)
end
context 'when cluster_id is missing' do
let(:mutation) do
variables = {
@ -177,9 +136,6 @@ RSpec.describe Mutations::Metrics::Dashboard::Annotations::Create, feature_categ
project.add_guest(current_user)
end
it_behaves_like 'a mutation that returns top-level errors',
errors: [Gitlab::Graphql::Authorize::AuthorizeResource::RESOURCE_ACCESS_ERROR]
it 'does not create the annotation' do
expect do
post_graphql_mutation(mutation, current_user: current_user)

View File

@ -21,77 +21,6 @@ RSpec.describe API::Metrics::Dashboard::Annotations, feature_category: :metrics
end
context "with :source_type == #{source_type.pluralize}" do
context 'with correct permissions' do
context 'with valid parameters' do
it 'creates a new annotation', :aggregate_failures do
post api(url, user), params: params
expect(response).to have_gitlab_http_status(:created)
expect(json_response["#{source_type}_id"]).to eq(source.id)
expect(json_response['starting_at'].to_time).to eq(starting_at.to_time)
expect(json_response['ending_at'].to_time).to eq(ending_at.to_time)
expect(json_response['description']).to eq(params[:description])
expect(json_response['dashboard_path']).to eq(dashboard)
end
end
context 'with invalid parameters' do
it 'returns error message' do
post api(url, user), params: { dashboard_path: '', starting_at: nil, description: nil }
expect(response).to have_gitlab_http_status(:bad_request)
expect(json_response['message']).to include({ "starting_at" => ["can't be blank"], "description" => ["can't be blank"], "dashboard_path" => ["can't be blank"] })
end
end
context 'with undeclared params' do
before do
params[:undeclared_param] = 'xyz'
end
it 'filters out undeclared params' do
expect(::Metrics::Dashboard::Annotations::CreateService).to receive(:new).with(user, hash_excluding(:undeclared_param))
post api(url, user), params: params
end
end
context 'with special characers in dashboard_path in request body' do
let(:dashboard_escaped) { 'config/prometheus/common_metrics%26copy.yml' }
let(:dashboard_unescaped) { 'config/prometheus/common_metrics&copy.yml' }
shared_examples 'special characters unescaped' do
let(:expected_params) do
{
'starting_at' => starting_at.to_time,
'ending_at' => ending_at.to_time,
source_type.to_s => source,
'dashboard_path' => dashboard_unescaped,
'description' => params[:description]
}
end
it 'unescapes the dashboard_path', :aggregate_failures do
expect(::Metrics::Dashboard::Annotations::CreateService).to receive(:new).with(user, expected_params)
post api(url, user), params: params
end
end
context 'with escaped characters' do
it_behaves_like 'special characters unescaped' do
let(:dashboard) { dashboard_escaped }
end
end
context 'with unescaped characers' do
it_behaves_like 'special characters unescaped' do
let(:dashboard) { dashboard_unescaped }
end
end
end
end
context 'without correct permissions' do
let_it_be(:guest) { create(:user) }
@ -102,7 +31,7 @@ RSpec.describe API::Metrics::Dashboard::Annotations, feature_category: :metrics
it 'returns error message' do
post api(url, guest), params: params
expect(response).to have_gitlab_http_status(:forbidden)
expect(response).to have_gitlab_http_status(:not_found)
end
end

View File

@ -1,147 +0,0 @@
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Metrics::Dashboard::Annotations::CreateService, feature_category: :metrics do
let_it_be(:user) { create(:user) }
let(:description) { 'test annotation' }
let(:dashboard_path) { 'config/prometheus/common_metrics.yml' }
let(:starting_at) { 15.minutes.ago }
let(:ending_at) { nil }
let(:service_instance) { described_class.new(user, annotation_params) }
let(:annotation_params) do
{
environment: environment,
cluster: cluster,
description: description,
dashboard_path: dashboard_path,
starting_at: starting_at,
ending_at: ending_at
}
end
shared_examples 'executed annotation creation' do
it 'returns success response', :aggregate_failures do
annotation = instance_double(::Metrics::Dashboard::Annotation)
allow(::Metrics::Dashboard::Annotation).to receive(:new).and_return(annotation)
allow(annotation).to receive(:save).and_return(true)
response = service_instance.execute
expect(response[:status]).to be :success
expect(response[:annotation]).to be annotation
end
it 'creates annotation', :aggregate_failures do
annotation = instance_double(::Metrics::Dashboard::Annotation)
expect(::Metrics::Dashboard::Annotation)
.to receive(:new).with(annotation_params).and_return(annotation)
expect(annotation).to receive(:save).and_return(true)
service_instance.execute
end
end
shared_examples 'prevented annotation creation' do |message|
it 'returns error response', :aggregate_failures do
response = service_instance.execute
expect(response[:status]).to be :error
expect(response[:message]).to eql message
end
it 'does not change db state' do
expect(::Metrics::Dashboard::Annotation).not_to receive(:new)
service_instance.execute
end
end
shared_examples 'annotation creation failure' do
it 'returns error response', :aggregate_failures do
annotation = instance_double(::Metrics::Dashboard::Annotation)
expect(annotation).to receive(:errors).and_return('Model validation error')
expect(::Metrics::Dashboard::Annotation)
.to receive(:new).with(annotation_params).and_return(annotation)
expect(annotation).to receive(:save).and_return(false)
response = service_instance.execute
expect(response[:status]).to be :error
expect(response[:message]).to eql 'Model validation error'
end
end
describe '.execute' do
context 'with environment' do
let(:environment) { create(:environment) }
let(:cluster) { nil }
context 'with anonymous user' do
it_behaves_like 'prevented annotation creation', 'You are not authorized to create annotation for selected environment'
end
context 'with maintainer user' do
before do
environment.project.add_maintainer(user)
end
it_behaves_like 'executed annotation creation'
end
end
context 'with cluster' do
let(:environment) { nil }
context 'with anonymous user' do
let(:cluster) { create(:cluster, :project) }
it_behaves_like 'prevented annotation creation', 'You are not authorized to create annotation for selected cluster'
end
context 'with maintainer user' do
let(:cluster) { create(:cluster, :project) }
before do
cluster.project.add_maintainer(user)
end
it_behaves_like 'executed annotation creation'
end
context 'with owner user' do
let(:cluster) { create(:cluster, :group) }
before do
cluster.group.add_owner(user)
end
it_behaves_like 'executed annotation creation'
end
end
context 'non cluster nor environment is supplied' do
let(:environment) { nil }
let(:cluster) { nil }
it_behaves_like 'annotation creation failure'
end
context 'missing dashboard_path' do
let(:cluster) { create(:cluster, :project) }
let(:environment) { nil }
let(:dashboard_path) { nil }
context 'with maintainer user' do
before do
cluster.project.add_maintainer(user)
end
it_behaves_like 'annotation creation failure'
end
end
end
end