Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2022-10-31 21:11:07 +00:00
parent 30b8ea126f
commit 16776d7f4f
60 changed files with 406 additions and 208 deletions

View File

@ -351,10 +351,25 @@ Dangerfile @gl-quality/eng-prod
/spec/frontend/batch_comments/ @viktomas @jboyson @iamphill @thomasrandolph /spec/frontend/batch_comments/ @viktomas @jboyson @iamphill @thomasrandolph
^[Product Intelligence] ^[Product Intelligence]
/ee/lib/gitlab/usage_data_counters/ @gitlab-org/growth/product-intelligence/engineers /ee/lib/gitlab/usage_data_counters/ @gitlab-org/analytics-section/product-intelligence/engineers
/ee/lib/ee/gitlab/usage_data.rb @gitlab-org/growth/product-intelligence/engineers /ee/lib/ee/gitlab/usage_data.rb @gitlab-org/analytics-section/product-intelligence/engineers
/lib/gitlab/usage_data.rb @gitlab-org/growth/product_intelligence/engineers /lib/gitlab/usage_data.rb @gitlab-org/analytics-section/product-intelligence/engineers
/lib/gitlab/usage_data_counters/ @gitlab-org/growth/product-intelligence/engineers /lib/gitlab/usage_data_counters/ @gitlab-org/analytics-section/product-intelligence/engineers
/lib/gitlab/usage/ @gitlab-org/analytics-section/product-intelligence/engineers
/ee/lib/ee/gitlab/usage_data_counters/ @gitlab-org/analytics-section/product-intelligence/engineers
/ee/lib/ee/gitlab/usage/ @gitlab-org/analytics-section/product-intelligence/engineers
/config/metrics/ @gitlab-org/analytics-section/product-intelligence/engineers
/ee/config/metrics/ @gitlab-org/analytics-section/product-intelligence/engineers
/app/workers/gitlab_service_ping_worker.rb @gitlab-org/analytics-section/product-intelligence/engineers
/spec/workers/gitlab_service_ping_worker_spec.rb @gitlab-org/analytics-section/product-intelligence/engineers
/ee/spec/lib/gitlab/usage_data_counters/ @gitlab-org/analytics-section/product-intelligence/engineers
/ee/spec/lib/ee/gitlab/usage_data_spec.rb @gitlab-org/analytics-section/product-intelligence/engineers
/spec/lib/gitlab/usage_data_spec.rb @gitlab-org/analytics-section/product-intelligence/engineers
/spec/lib/gitlab/usage_data_counters/ @gitlab-org/analytics-section/product-intelligence/engineers
/spec/lib/gitlab/usage/ @gitlab-org/analytics-section/product-intelligence/engineers
/ee/spec/lib/ee/gitlab/usage_data_counters/ @gitlab-org/analytics-section/product-intelligence/engineers
/ee/spec/lib/ee/gitlab/usage/ @gitlab-org/analytics-section/product-intelligence/engineers
/ee/spec/config/metrics/ @gitlab-org/analytics-section/product-intelligence/engineers
^[Growth Experiments] ^[Growth Experiments]
/app/experiments/ @gitlab-org/growth/experiment-devs /app/experiments/ @gitlab-org/growth/experiment-devs

View File

@ -398,5 +398,5 @@ compile-storybook as-if-foss:
- .as-if-foss - .as-if-foss
- .frontend:rules:default-frontend-jobs-as-if-foss - .frontend:rules:default-frontend-jobs-as-if-foss
needs: needs:
- !reference [.compile-storybook-base, needs] - job: "graphql-schema-dump as-if-foss"
- job: "rspec-all frontend_fixture as-if-foss" - job: "rspec-all frontend_fixture as-if-foss"

View File

@ -278,7 +278,7 @@
- "Dockerfile.assets" - "Dockerfile.assets"
- "config/**/*.js" - "config/**/*.js"
- "vendor/assets/**/*" - "vendor/assets/**/*"
- "{app/assets,app/components,app/helpers,app/presenters,app/views,locale,public,spec/frontend,symbol}/**/*" - "{app/assets,app/components,app/helpers,app/presenters,app/views,locale,public,spec/frontend,storybook,symbol}/**/*"
.controllers-patterns: &controllers-patterns .controllers-patterns: &controllers-patterns
- "{,ee/,jh/}{app/controllers}/**/*" - "{,ee/,jh/}{app/controllers}/**/*"
@ -393,7 +393,7 @@
- "Rakefile" - "Rakefile"
- "tests.yml" - "tests.yml"
- "config.ru" - "config.ru"
- "{,ee/,jh/}{app,bin,config,db,generator_templates,haml_lint,lib,locale,public,scripts,symbol,vendor}/**/*" - "{,ee/,jh/}{app,bin,config,db,generator_templates,haml_lint,lib,locale,public,scripts,storybook,symbol,vendor}/**/*"
- "doc/api/graphql/reference/*" # Files in this folder are auto-generated - "doc/api/graphql/reference/*" # Files in this folder are auto-generated
# CI changes # CI changes
- ".gitlab-ci.yml" - ".gitlab-ci.yml"
@ -450,7 +450,7 @@
- "Rakefile" - "Rakefile"
- "tests.yml" - "tests.yml"
- "config.ru" - "config.ru"
- "{,ee/,jh/}{app,bin,config,db,generator_templates,haml_lint,lib,locale,public,scripts,symbol,vendor}/**/*" - "{,ee/,jh/}{app,bin,config,db,generator_templates,haml_lint,lib,locale,public,scripts,storybook,symbol,vendor}/**/*"
- "doc/api/graphql/reference/*" # Files in this folder are auto-generated - "doc/api/graphql/reference/*" # Files in this folder are auto-generated
# CI changes # CI changes
- ".gitlab-ci.yml" - ".gitlab-ci.yml"
@ -487,7 +487,7 @@
- "Rakefile" - "Rakefile"
- "tests.yml" - "tests.yml"
- "config.ru" - "config.ru"
- "{,ee/,jh/}{app,bin,config,db,generator_templates,haml_lint,lib,locale,public,scripts,symbol,vendor}/**/*" - "{,ee/,jh/}{app,bin,config,db,generator_templates,haml_lint,lib,locale,public,scripts,storybook,symbol,vendor}/**/*"
- "doc/api/graphql/reference/*" # Files in this folder are auto-generated - "doc/api/graphql/reference/*" # Files in this folder are auto-generated
- "data/whats_new/*.yml" - "data/whats_new/*.yml"
# CI changes # CI changes
@ -877,6 +877,8 @@
- <<: *if-merge-request-labels-run-all-rspec - <<: *if-merge-request-labels-run-all-rspec
- <<: *if-merge-request - <<: *if-merge-request
changes: *startup-css-patterns changes: *startup-css-patterns
- <<: *if-merge-request
changes: *frontend-patterns-for-as-if-foss
.frontend:rules:frontend_fixture-as-if-foss: .frontend:rules:frontend_fixture-as-if-foss:
rules: rules:

View File

@ -198,31 +198,6 @@ Layout/SpaceInsideParens:
- 'spec/policies/clusters/agent_policy_spec.rb' - 'spec/policies/clusters/agent_policy_spec.rb'
- 'spec/presenters/ci/build_presenter_spec.rb' - 'spec/presenters/ci/build_presenter_spec.rb'
- 'spec/presenters/packages/conan/package_presenter_spec.rb' - 'spec/presenters/packages/conan/package_presenter_spec.rb'
- 'spec/requests/api/boards_spec.rb'
- 'spec/requests/api/ci/runner/jobs_artifacts_spec.rb'
- 'spec/requests/api/ci/runner/jobs_request_post_spec.rb'
- 'spec/requests/api/ci/runners_reset_registration_token_spec.rb'
- 'spec/requests/api/ci/runners_spec.rb'
- 'spec/requests/api/dependency_proxy_spec.rb'
- 'spec/requests/api/deployments_spec.rb'
- 'spec/requests/api/files_spec.rb'
- 'spec/requests/api/go_proxy_spec.rb'
- 'spec/requests/api/graphql/boards/board_list_issues_query_spec.rb'
- 'spec/requests/api/graphql/ci/jobs_spec.rb'
- 'spec/requests/api/graphql/ci/pipelines_spec.rb'
- 'spec/requests/api/graphql/mutations/award_emojis/remove_spec.rb'
- 'spec/requests/api/graphql/mutations/award_emojis/toggle_spec.rb'
- 'spec/requests/api/graphql/mutations/ci/runners_registration_token/reset_spec.rb'
- 'spec/requests/api/group_boards_spec.rb'
- 'spec/requests/api/issues/issues_spec.rb'
- 'spec/requests/api/issues/post_projects_issues_spec.rb'
- 'spec/requests/api/labels_spec.rb'
- 'spec/requests/api/merge_requests_spec.rb'
- 'spec/requests/api/pages/pages_spec.rb'
- 'spec/requests/api/project_milestones_spec.rb'
- 'spec/requests/api/project_snippets_spec.rb'
- 'spec/requests/api/snippets_spec.rb'
- 'spec/requests/api/submodules_spec.rb'
- 'spec/requests/jwt_controller_spec.rb' - 'spec/requests/jwt_controller_spec.rb'
- 'spec/requests/projects/merge_requests/diffs_spec.rb' - 'spec/requests/projects/merge_requests/diffs_spec.rb'
- 'spec/requests/projects/merge_requests_spec.rb' - 'spec/requests/projects/merge_requests_spec.rb'

View File

@ -57,7 +57,9 @@ export const config = {
return incoming; return incoming;
} }
return existing.map((existingWidget) => { return existing.map((existingWidget) => {
const incomingWidget = incoming.find((w) => w.type === existingWidget.type); const incomingWidget = incoming.find(
(w) => w.type && w.type === existingWidget.type,
);
return incomingWidget || existingWidget; return incomingWidget || existingWidget;
}); });
}, },

View File

@ -190,7 +190,8 @@ class GraphqlController < ApplicationController
current_user: current_user, current_user: current_user,
is_sessionless_user: api_user, is_sessionless_user: api_user,
request: request, request: request,
scope_validator: ::Gitlab::Auth::ScopeValidator.new(api_user, request_authenticator) scope_validator: ::Gitlab::Auth::ScopeValidator.new(api_user, request_authenticator),
remove_deprecated: Gitlab::Utils.to_boolean(params[:remove_deprecated], default: false)
} }
end end

View File

@ -34,14 +34,14 @@ class RegistrationsController < Devise::RegistrationsController
def create def create
set_user_state set_user_state
token = set_custom_confirmation_token set_custom_confirmation_token
super do |new_user| super do |new_user|
accept_pending_invitations if new_user.persisted? accept_pending_invitations if new_user.persisted?
persist_accepted_terms_if_required(new_user) persist_accepted_terms_if_required(new_user)
set_role_required(new_user) set_role_required(new_user)
send_custom_confirmation_instructions(new_user, token) send_custom_confirmation_instructions
track_weak_password_error(new_user, self.class.name, 'create') track_weak_password_error(new_user, self.class.name, 'create')
if pending_approval? if pending_approval?
@ -128,7 +128,7 @@ class RegistrationsController < Devise::RegistrationsController
# after user confirms and comes back, he will be redirected # after user confirms and comes back, he will be redirected
store_location_for(:redirect, users_sign_up_welcome_path(glm_tracking_params)) store_location_for(:redirect, users_sign_up_welcome_path(glm_tracking_params))
return identity_verification_redirect_path if custom_confirmation_enabled?(resource) return identity_verification_redirect_path if custom_confirmation_enabled?
users_almost_there_path(email: resource.email) users_almost_there_path(email: resource.email)
end end
@ -244,7 +244,7 @@ class RegistrationsController < Devise::RegistrationsController
# overridden by EE module # overridden by EE module
end end
def custom_confirmation_enabled?(resource) def custom_confirmation_enabled?
# overridden by EE module # overridden by EE module
end end
@ -252,7 +252,7 @@ class RegistrationsController < Devise::RegistrationsController
# overridden by EE module # overridden by EE module
end end
def send_custom_confirmation_instructions(user, token) def send_custom_confirmation_instructions
# overridden by EE module # overridden by EE module
end end
end end

View File

@ -4,10 +4,10 @@ module Types
class BaseArgument < GraphQL::Schema::Argument class BaseArgument < GraphQL::Schema::Argument
include GitlabStyleDeprecations include GitlabStyleDeprecations
attr_reader :deprecation, :doc_reference attr_reader :doc_reference
def initialize(*args, **kwargs, &block) def initialize(*args, **kwargs, &block)
@deprecation = gitlab_deprecation(kwargs) init_gitlab_deprecation(kwargs)
@doc_reference = kwargs.delete(:see) @doc_reference = kwargs.delete(:see)
# our custom addition `nullable` which allows us to declare # our custom addition `nullable` which allows us to declare

View File

@ -6,10 +6,8 @@ module Types
class CustomValue < GraphQL::Schema::EnumValue class CustomValue < GraphQL::Schema::EnumValue
include ::GitlabStyleDeprecations include ::GitlabStyleDeprecations
attr_reader :deprecation
def initialize(name, desc = nil, **kwargs) def initialize(name, desc = nil, **kwargs)
@deprecation = gitlab_deprecation(kwargs) init_gitlab_deprecation(kwargs)
super(name, desc, **kwargs) super(name, desc, **kwargs)
end end

View File

@ -8,16 +8,16 @@ module Types
DEFAULT_COMPLEXITY = 1 DEFAULT_COMPLEXITY = 1
attr_reader :deprecation, :doc_reference attr_reader :doc_reference
def initialize(**kwargs, &block) def initialize(**kwargs, &block)
init_gitlab_deprecation(kwargs)
@calls_gitaly = !!kwargs.delete(:calls_gitaly) @calls_gitaly = !!kwargs.delete(:calls_gitaly)
@doc_reference = kwargs.delete(:see) @doc_reference = kwargs.delete(:see)
@constant_complexity = kwargs[:complexity].is_a?(Integer) && kwargs[:complexity] > 0 @constant_complexity = kwargs[:complexity].is_a?(Integer) && kwargs[:complexity] > 0
@requires_argument = !!kwargs.delete(:requires_argument) @requires_argument = !!kwargs.delete(:requires_argument)
@authorize = Array.wrap(kwargs.delete(:authorize)) @authorize = Array.wrap(kwargs.delete(:authorize))
kwargs[:complexity] = field_complexity(kwargs[:resolver_class], kwargs[:complexity]) kwargs[:complexity] = field_complexity(kwargs[:resolver_class], kwargs[:complexity])
@deprecation = gitlab_deprecation(kwargs)
after_connection_extensions = kwargs.delete(:late_extensions) || [] after_connection_extensions = kwargs.delete(:late_extensions) || []
super(**kwargs, &block) super(**kwargs, &block)

View File

@ -1,14 +1,22 @@
# frozen_string_literal: true # frozen_string_literal: true
# Concern for handling deprecation arguments. # Concern for handling GraphQL deprecations.
# https://docs.gitlab.com/ee/development/api_graphql_styleguide.html#deprecating-schema-items # https://docs.gitlab.com/ee/development/api_graphql_styleguide.html#deprecating-schema-items
module GitlabStyleDeprecations module GitlabStyleDeprecations
extend ActiveSupport::Concern extend ActiveSupport::Concern
included do
attr_accessor :deprecation
end
def visible?(ctx)
super && ctx[:remove_deprecated] == true ? deprecation.nil? : true
end
private private
# Mutate the arguments, returns the deprecation # Set deprecation, mutate the arguments
def gitlab_deprecation(kwargs) def init_gitlab_deprecation(kwargs)
if kwargs[:deprecation_reason].present? if kwargs[:deprecation_reason].present?
raise ArgumentError, 'Use `deprecated` property instead of `deprecation_reason`. ' \ raise ArgumentError, 'Use `deprecated` property instead of `deprecation_reason`. ' \
'See https://docs.gitlab.com/ee/development/api_graphql_styleguide.html#deprecating-schema-items' 'See https://docs.gitlab.com/ee/development/api_graphql_styleguide.html#deprecating-schema-items'
@ -17,14 +25,12 @@ module GitlabStyleDeprecations
# GitLab allows items to be marked as "alpha", which leverages GraphQL deprecations. # GitLab allows items to be marked as "alpha", which leverages GraphQL deprecations.
deprecation_args = kwargs.extract!(:alpha, :deprecated) deprecation_args = kwargs.extract!(:alpha, :deprecated)
deprecation = ::Gitlab::Graphql::Deprecation.parse(**deprecation_args) self.deprecation = ::Gitlab::Graphql::Deprecation.parse(**deprecation_args)
return unless deprecation return unless deprecation
raise ArgumentError, "Bad deprecation. #{deprecation.errors.full_messages.to_sentence}" unless deprecation.valid? raise ArgumentError, "Bad deprecation. #{deprecation.errors.full_messages.to_sentence}" unless deprecation.valid?
kwargs[:deprecation_reason] = deprecation.deprecation_reason kwargs[:deprecation_reason] = deprecation.deprecation_reason
kwargs[:description] = deprecation.edit_description(kwargs[:description]) kwargs[:description] = deprecation.edit_description(kwargs[:description])
deprecation
end end
end end

View File

@ -1706,7 +1706,11 @@ class Project < ApplicationRecord
end end
def has_active_integrations?(hooks_scope = :push_hooks) def has_active_integrations?(hooks_scope = :push_hooks)
integrations.public_send(hooks_scope).any? # rubocop:disable GitlabSecurity/PublicSend @has_active_integrations ||= {} # rubocop: disable Gitlab/PredicateMemoization
return @has_active_integrations[hooks_scope] if @has_active_integrations.key?(hooks_scope)
@has_active_integrations[hooks_scope] = integrations.public_send(hooks_scope).any? # rubocop:disable GitlabSecurity/PublicSend
end end
def feature_usage def feature_usage

View File

@ -9,7 +9,7 @@
%tr %tr
%td{ style: "#{default_font}vertical-align:middle;color:#ffffff;text-align:center;" } %td{ style: "#{default_font}vertical-align:middle;color:#ffffff;text-align:center;" }
%span %span
= _("Your %{host} account was signed in to from a new location") % { host: Gitlab.config.gitlab.host } = _("Someone signed in to your %{host} account from a new location") % { host: Gitlab.config.gitlab.host }
%tr.spacer %tr.spacer
%td{ style: spacer_style } %td{ style: spacer_style }
&nbsp; &nbsp;

View File

@ -32,3 +32,5 @@ metadata:
description: Operations related to deploy freeze periods description: Operations related to deploy freeze periods
- name: release_links - name: release_links
description: Operations related to release assets (links) description: Operations related to release assets (links)
- name: cluster_agents
description: Operations related to the GitLab agent for Kubernetes

View File

@ -102,6 +102,8 @@ Items are marked as deprecated in:
NOTE: NOTE:
If you use the GraphQL API, we recommend you remove the deprecated schema from your GraphQL If you use the GraphQL API, we recommend you remove the deprecated schema from your GraphQL
API calls as soon as possible to avoid experiencing breaking changes. API calls as soon as possible to avoid experiencing breaking changes.
To verify your API calls against the schema without the deprecated schema items, you can add a
`?remove_deprecated=true` query parameter. You should only use this parameter for verification purposes.
The deprecation message provides an alternative for the deprecated schema item, The deprecation message provides an alternative for the deprecated schema item,
if applicable. if applicable.

View File

@ -198,18 +198,11 @@ The response is `404 Not Found` if the vulnerability export is not finished yet
Example response: Example response:
```csv ```csv
Group Name,Project Name,Tool,Scanner Name,Status,Vulnerability,Details,Additional Info,Severity,CVE,CWE,Other Identifiers Group Name,Project Name,Tool,Scanner Name,Status,Vulnerability,Details,Additional Info,Severity,CVE,CWE,Other Identifiers,Detected At,Location,Activity,
Gitlab.org,Defend,container_scanning,Trivy,detected,CVE-2017-16997 in glibc,,CVE-2017-16997 in glibc,critical,CVE-2017-16997 Gitlab.org,Defend,container_scanning,Trivy,detected,CVE-2019-14697 in musl-utils-1.1.20-r4,"musl libc through 1.1.23 has an x87 floating-point stack adjustment imbalance, related to the math/i386/ directory. In some cases, use of this library could introduce out-of-bounds writes that are not present in an application's source code.",CVE-2019-14697 in musl-utils-1.1.20-r4,critical,CVE-2019-14697,,"",2022-10-07 13:34:41 UTC,"{""image""=>""python:3.4-alpine"", ""dependency""=>{""package""=>{""name""=>""musl-utils""}, ""version""=>""1.1.20-r4""}, ""operating_system""=>""alpine 3.9.2""}",true,
Gitlab.org,Defend,container_scanning,Trivy,detected,CVE-2017-18269 in glibc,,CVE-2017-18269 in glibc,critical,CVE-2017-18269 Gitlab.org,Defend,container_scanning,Trivy,detected,CVE-2019-19242 in sqlite-libs-3.26.0-r3,"SQLite 3.30.1 mishandles pExpr->y.pTab, as demonstrated by the TK_COLUMN case in sqlite3ExprCodeTarget in expr.c.",CVE-2019-19242 in sqlite-libs-3.26.0-r3,medium,CVE-2019-19242,,"",2022-10-07 13:34:41 UTC,"{""image""=>""python:3.4-alpine"", ""dependency""=>{""package""=>{""name""=>""sqlite-libs""}, ""version""=>""3.26.0-r3""}, ""operating_system""=>""alpine 3.9.2""}",true,
Gitlab.org,Defend,container_scanning,Trivy,detected,CVE-2018-1000001 in glibc,,CVE-2018-1000001 in glibc,high,CVE-2018-1000001 Gitlab.org,Defend,container_scanning,Trivy,detected,CVE-2020-28928 in musl-1.1.20-r4,"In musl libc through 1.2.1, wcsnrtombs mishandles particular combinations of destination buffer size and source character limit, as demonstrated by an invalid write access (buffer overflow).",CVE-2020-28928 in musl-1.1.20-r4,medium,CVE-2020-28928,,"",2022-10-07 13:34:41 UTC,"{""image""=>""python:3.4-alpine"", ""dependency""=>{""package""=>{""name""=>""musl""}, ""version""=>""1.1.20-r4""}, ""operating_system""=>""alpine 3.9.2""}",true,
Gitlab.org,Defend,container_scanning,Trivy,detected,CVE-2016-10228 in glibc,,CVE-2016-10228 in glibc,medium,CVE-2016-10228 Gitlab.org,Defend,dependency_scanning,Gemnasium,detected,Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection') in rack,Carefully crafted requests can cause shell escape sequences to be written to the terminal via Rack's Lint middleware and CommonLogger middleware. These escape sequences can be leveraged to possibly execute commands in the victim's terminal.,Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection') in rack,unknown,Gemfile.lock:rack:gemnasium:60b5a27f-4e4d-4ab4-8ae7-74b4b212e177,,Gemnasium-60b5a27f-4e4d-4ab4-8ae7-74b4b212e177; GHSA-wq4h-7r42-5hrr,2022-10-14 13:16:00 UTC,"{""file""=>""Gemfile.lock"", ""dependency""=>{""package""=>{""name""=>""rack""}, ""version""=>""2.2.3""}}",false,
Gitlab.org,Defend,container_scanning,Trivy,detected,CVE-2010-4052 in glibc,,CVE-2010-4052 in glibc,low,CVE-2010-4052 Gitlab.org,Defend,dependency_scanning,Gemnasium,detected,Denial of Service Vulnerability in Rack Multipart Parsing in rack,"Carefully crafted multipart POST requests can cause Rack's multipart parser to take much longer than expected, leading to a possible denial of service vulnerability. Impacted code will use Rack's multipart parser to parse multipart posts.",Denial of Service Vulnerability in Rack Multipart Parsing in rack,unknown,Gemfile.lock:rack:gemnasium:20daa17a-47b5-4f79-80c2-cd8f2db9805c,,Gemnasium-20daa17a-47b5-4f79-80c2-cd8f2db9805c; GHSA-hxqx-xwvh-44m2,2022-10-14 13:16:00 UTC,"{""file""=>""Gemfile.lock"", ""dependency""=>{""package""=>{""name""=>""rack""}, ""version""=>""2.2.3""}}",false,
Gitlab.org,Defend,container_scanning,Trivy,detected,CVE-2018-18520 in elfutils,,CVE-2018-18520 in elfutils,low,CVE-2018-18520 Gitlab.org,Defend,sast,Brakeman,detected,Possible SQL injection,,Possible SQL injection,medium,e52f23a259cd489168b4313317ac94a3f13bffde57b9635171c1a44a9f329e9a,,"""Brakeman Warning Code 0""",2022-10-13 15:16:36 UTC,"{""file""=>""main.rb"", ""class""=>""User"", ""method""=>""index"", ""start_line""=>3}",false
Gitlab.org,Defend,container_scanning,Trivy,detected,CVE-2018-16869 in nettle,,CVE-2018-16869 in nettle,unknown,CVE-2018-16869,CWE-1
Gitlab.org,Defend,dependency_scanning,Gemnasium,detected,Regular Expression Denial of Service in debug,,Regular Expression Denial of Service in debug,unknown,CVE-2021-1234,CWE-2,"""yarn.lock:debug:gemnasium:37283ed4-0380-40d7-ada7-2d994afcc62a"""
Gitlab.org,Defend,dependency_scanning,Gemnasium,detected,Authentication bypass via incorrect DOM traversal and canonicalization in saml2-js,,Authentication bypass via incorrect DOM traversal and canonicalization in saml2-js,unknown,,,"""yarn.lock:saml2-js:gemnasium:9952e574-7b5b-46fa-a270-aeb694198a98"""
Gitlab.org,Defend,sast,Find Security Bugs,detected,Predictable pseudorandom number generator,,Predictable pseudorandom number generator,medium,,,"""818bf5dacb291e15d9e6dc3c5ac32178:PREDICTABLE_RANDOM:src/main/java/com/gitlab/security_products/tests/App.java:47"""
Gitlab.org,Defend,sast,Find Security Bugs,detected,Cipher with no integrity,,Cipher with no integrity,medium,,,"""e6449b89335daf53c0db4c0219bc1634:CIPHER_INTEGRITY:src/main/java/com/gitlab/security_products/tests/App.java:29"""
Gitlab.org,Defend,sast,Find Security Bugs,detected,Predictable pseudorandom number generator,,Predictable pseudorandom number generator,medium,,,"""e8ff1d01f74cd372f78da8f5247d3e73:PREDICTABLE_RANDOM:src/main/java/com/gitlab/security_products/tests/App.java:41"""
Gitlab.org,Defend,sast,Find Security Bugs,detected,ECB mode is insecure,,ECB mode is insecure,medium,,,"""ea0f905fc76f2739d5f10a1fd1e37a10:ECB_MODE:src/main/java/com/gitlab/security_products/tests/App.java:29"""
``` ```

View File

@ -3255,7 +3255,8 @@ Use `rules:if` clauses to specify when to add a job to a pipeline:
- If no `if` statements are true, do not add the job to the pipeline. - If no `if` statements are true, do not add the job to the pipeline.
`if` clauses are evaluated based on the values of [predefined CI/CD variables](../variables/predefined_variables.md) `if` clauses are evaluated based on the values of [predefined CI/CD variables](../variables/predefined_variables.md)
or [custom CI/CD variables](../variables/index.md#custom-cicd-variables). or [custom CI/CD variables](../variables/index.md#custom-cicd-variables), with
[some exceptions](../variables/where_variables_can_be_used.md#gitlab-ciyml-file).
**Keyword type**: Job-specific and pipeline-specific. You can use it as part of a job **Keyword type**: Job-specific and pipeline-specific. You can use it as part of a job
to configure the job behavior, or with [`workflow`](#workflow) to configure the pipeline behavior. to configure the job behavior, or with [`workflow`](#workflow) to configure the pipeline behavior.

View File

@ -20,11 +20,10 @@ The acronym refers to the first letter of each topic type.
In general, each page in the GitLab documentation contains multiple topics. In general, each page in the GitLab documentation contains multiple topics.
Each topic on a page should be recognizable as a specific topic type. Each topic on a page should be recognizable as a specific topic type.
## Other topic types In addition to the four primary topic types, we also have a page type for
[Tutorials](tutorial.md) and [Get started](#get-started).
In addition to the four primary topic types, we have a few other types. ## Related topics
### Related topics
If inline links are not sufficient, you can create a topic called **Related topics** If inline links are not sufficient, you can create a topic called **Related topics**
and include an unordered list of related topics. This topic should be above the Troubleshooting section. and include an unordered list of related topics. This topic should be above the Troubleshooting section.
@ -36,57 +35,7 @@ and include an unordered list of related topics. This topic should be above the
- [Trigger a pipeline manually](link-to-topic). - [Trigger a pipeline manually](link-to-topic).
``` ```
### Tutorials ## Get started
A tutorial is page that contains an end-to-end walkthrough of a complex workflow or scenario.
In general, you might consider using a tutorial when:
- The workflow requires a number of sequential steps where each step consists
of sub-steps.
- The steps cover a variety of GitLab features or third-party tools.
Tutorials are learning aids that complement our core documentation.
They do not introduce new features.
Always use the primary [topic types](#documentation-topic-types-ctrt) to document new features.
Tutorials should be in this format:
```markdown
# Title (starts with "Tutorial:" followed by an active verb, like "Tutorial: Create a website")
A paragraph that explains what the tutorial does, and the expected outcome.
To create a website:
1. [Do the first task](#do-the-first-task)
1. [Do the second task](#do-the-second-task)
Prerequisites (optional):
- Thing 1
- Thing 2
- Thing 3
## Do the first task
To do step 1:
1. First step.
1. Another step.
1. Another step.
## Do the second task
Before you begin, make sure you have [done the first task](#do-the-first-task).
To do step 2:
1. First step.
1. Another step.
1. Another step.
```
### Get started
A get started page is a set of steps to help a user get set up A get started page is a set of steps to help a user get set up
quickly to use a single GitLab feature or tool. quickly to use a single GitLab feature or tool.
@ -110,7 +59,7 @@ consider using subsections for each distinct task.
In the left nav, use `Get started` as the text. On the page itself, spell out In the left nav, use `Get started` as the text. On the page itself, spell out
the full name. For example, `Get started with application security`. the full name. For example, `Get started with application security`.
### Topics and resources ## Topics and resources
Some pages are solely a list of links to other documentation. Some pages are solely a list of links to other documentation.

View File

@ -0,0 +1,79 @@
---
stage: none
group: Style Guide
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
---
# Tutorial topic type
A tutorial is page that contains an end-to-end walkthrough of a complex workflow or scenario.
In general, you might consider using a tutorial when:
- The workflow requires a number of sequential steps where each step consists
of sub-steps.
- The steps cover a variety of GitLab features or third-party tools.
Tutorials are learning aids that complement our core documentation.
They do not introduce new features.
Always use the primary [topic types](index.md) to document new features.
Tutorials should be in this format:
```markdown
# Title (starts with "Tutorial:" followed by an active verb, like "Tutorial: Create a website")
A paragraph that explains what the tutorial does, and the expected outcome.
To create a website:
1. [Do the first task](#do-the-first-task)
1. [Do the second task](#do-the-second-task)
Prerequisites (optional):
- Thing 1
- Thing 2
- Thing 3
## Do the first task
To do step 1:
1. First step.
1. Another step.
1. Another step.
## Do the second task
Before you begin, make sure you have [done the first task](#do-the-first-task).
To do step 2:
1. First step.
1. Another step.
1. Another step.
```
## Tutorial headings
Start with `Tutorial:` followed by an active verb, like `Tutorial: Create a website`.
## Screenshots
You can include screenshots in a tutorial to illustrate important steps in the process.
In the core product documentation, you should [use screenshots sparingly](../styleguide/index.md#images).
However, in tutorials, screenshots can help users understand where they are in a complex process.
Try to balance the number of screenshots in the tutorial so they don't disrupt
the narrative flow. For example, do not put one large screenshot in the middle of the tutorial.
Instead, put multiple, smaller screenshots throughout.
## Tutorial voice
Use a friendlier tone than you would for other topic types. For example,
you can:
- Add encouraging or congratulatory phrases after tasks.
- Use future tense from time to time, especially when you're introducing
steps. For example, `Next, you will associate your issues with your epics`.
- Be more conversational. For example, `This task might take a while to complete`.

View File

@ -216,6 +216,9 @@ Fields included are:
- [CVE](https://cve.mitre.org/) (Common Vulnerabilities and Exposures) - [CVE](https://cve.mitre.org/) (Common Vulnerabilities and Exposures)
- [CWE](https://cwe.mitre.org/) (Common Weakness Enumeration) - [CWE](https://cwe.mitre.org/) (Common Weakness Enumeration)
- Other identifiers - Other identifiers
- Detected At
- Location
- Activity
NOTE: NOTE:
Full details are available through our Full details are available through our

View File

@ -115,6 +115,14 @@ a test request to re-enable a [disabled webhook](#re-enable-disabled-webhooks).
For example, to test `push events`, your project should have at least one commit. The webhook uses this commit in the webhook. For example, to test `push events`, your project should have at least one commit. The webhook uses this commit in the webhook.
NOTE:
Testing is not supported for some types of events for project and groups webhooks.
Read more in [issue 379201](https://gitlab.com/gitlab-org/gitlab/-/issues/379201).
Prerequisite:
- To test group webhooks, you must have administrator access for your instance.
To test a webhook: To test a webhook:
1. In your project or group, on the left sidebar, select **Settings > Webhooks**. 1. In your project or group, on the left sidebar, select **Settings > Webhooks**.
@ -237,6 +245,10 @@ Webhook requests to your endpoint include the following headers:
GitLab records the history of each webhook request. GitLab records the history of each webhook request.
You can view requests made in the last 2 days in the **Recent events** table. You can view requests made in the last 2 days in the **Recent events** table.
Prerequisite:
- To troubleshoot group webhooks, you must have administrator access for your instance.
To view the table: To view the table:
1. In your project or group, on the left sidebar, select **Settings > Webhooks**. 1. In your project or group, on the left sidebar, select **Settings > Webhooks**.

View File

@ -171,6 +171,8 @@ module API
namespace do namespace do
mount ::API::AccessRequests mount ::API::AccessRequests
mount ::API::Appearance mount ::API::Appearance
mount ::API::Clusters::Agents
mount ::API::Clusters::AgentTokens
mount ::API::DeployKeys mount ::API::DeployKeys
mount ::API::DeployTokens mount ::API::DeployTokens
mount ::API::Deployments mount ::API::Deployments
@ -212,8 +214,6 @@ module API
mount ::API::Ci::SecureFiles mount ::API::Ci::SecureFiles
mount ::API::Ci::Triggers mount ::API::Ci::Triggers
mount ::API::Ci::Variables mount ::API::Ci::Variables
mount ::API::Clusters::Agents
mount ::API::Clusters::AgentTokens
mount ::API::CommitStatuses mount ::API::CommitStatuses
mount ::API::Commits mount ::API::Commits
mount ::API::ComposerPackages mount ::API::ComposerPackages

View File

@ -18,9 +18,10 @@ module API
end end
resource ':id/cluster_agents/:agent_id' do resource ':id/cluster_agents/:agent_id' do
resource :tokens do resource :tokens do
desc 'List agent tokens' do desc 'List tokens for an agent' do
detail 'This feature was introduced in GitLab 15.0.' detail 'This feature was introduced in GitLab 15.0. Returns a list of tokens for an agent.'
success Entities::Clusters::AgentTokenBasic success Entities::Clusters::AgentTokenBasic
tags %w[cluster_agents]
end end
params do params do
use :pagination use :pagination
@ -32,8 +33,9 @@ module API
end end
desc 'Get a single agent token' do desc 'Get a single agent token' do
detail 'This feature was introduced in GitLab 15.0.' detail 'This feature was introduced in GitLab 15.0. Gets a single agent token.'
success Entities::Clusters::AgentToken success Entities::Clusters::AgentToken
tags %w[cluster_agents]
end end
params do params do
requires :token_id, type: Integer, desc: 'The ID of the agent token' requires :token_id, type: Integer, desc: 'The ID of the agent token'
@ -47,8 +49,9 @@ module API
end end
desc 'Create an agent token' do desc 'Create an agent token' do
detail 'This feature was introduced in GitLab 15.0.' detail 'This feature was introduced in GitLab 15.0. Creates a new token for an agent.'
success Entities::Clusters::AgentTokenWithToken success Entities::Clusters::AgentTokenWithToken
tags %w[cluster_agents]
end end
params do params do
requires :name, type: String, desc: 'The name for the token' requires :name, type: String, desc: 'The name for the token'
@ -71,7 +74,8 @@ module API
end end
desc 'Revoke an agent token' do desc 'Revoke an agent token' do
detail 'This feature was introduced in GitLab 15.0.' detail 'This feature was introduced in GitLab 15.0. Revokes an agent token.'
tags %w[cluster_agents]
end end
params do params do
requires :token_id, type: Integer, desc: 'The ID of the agent token' requires :token_id, type: Integer, desc: 'The ID of the agent token'

View File

@ -14,9 +14,10 @@ module API
requires :id, type: String, desc: 'The ID of a project' requires :id, type: String, desc: 'The ID of a project'
end end
resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
desc 'List agents' do desc 'List the agents for a project' do
detail 'This feature was introduced in GitLab 14.10.' detail 'This feature was introduced in GitLab 14.10. Returns the list of agents registered for the project.'
success Entities::Clusters::Agent success Entities::Clusters::Agent
tags %w[cluster_agents]
end end
params do params do
use :pagination use :pagination
@ -29,9 +30,10 @@ module API
present paginate(agents), with: Entities::Clusters::Agent present paginate(agents), with: Entities::Clusters::Agent
end end
desc 'Get single agent' do desc 'Get details about an agent' do
detail 'This feature was introduced in GitLab 14.10.' detail 'This feature was introduced in GitLab 14.10. Gets a single agent details.'
success Entities::Clusters::Agent success Entities::Clusters::Agent
tags %w[cluster_agents]
end end
params do params do
requires :agent_id, type: Integer, desc: 'The ID of an agent' requires :agent_id, type: Integer, desc: 'The ID of an agent'
@ -42,9 +44,10 @@ module API
present agent, with: Entities::Clusters::Agent present agent, with: Entities::Clusters::Agent
end end
desc 'Add an agent to a project' do desc 'Register an agent with a project' do
detail 'This feature was introduced in GitLab 14.10.' detail 'This feature was introduced in GitLab 14.10. Registers an agent to the project.'
success Entities::Clusters::Agent success Entities::Clusters::Agent
tags %w[cluster_agents]
end end
params do params do
requires :name, type: String, desc: 'The name of the agent' requires :name, type: String, desc: 'The name of the agent'
@ -61,8 +64,9 @@ module API
present result[:cluster_agent], with: Entities::Clusters::Agent present result[:cluster_agent], with: Entities::Clusters::Agent
end end
desc 'Delete an agent' do desc 'Delete a registered agent' do
detail 'This feature was introduced in GitLab 14.10.' detail 'This feature was introduced in GitLab 14.10. Deletes an existing agent registration.'
tags %w[cluster_agents]
end end
params do params do
requires :agent_id, type: Integer, desc: 'The ID of an agent' requires :agent_id, type: Integer, desc: 'The ID of an agent'

View File

@ -11,8 +11,8 @@ module API
->(obj, opts) { Ability.allowed?(opts[:user], "destroy_#{attr}".to_sym, yield(obj)) } ->(obj, opts) { Ability.allowed?(opts[:user], "destroy_#{attr}".to_sym, yield(obj)) }
end end
def expose_restricted(attr, &block) def expose_restricted(attr, documentation: {}, &block)
expose attr, if: can_read(attr, &block) expose attr, documentation: documentation, if: can_read(attr, &block)
end end
end end
end end

View File

@ -38095,6 +38095,9 @@ msgstr ""
msgid "Someone edited this test case at the same time you did. The description has been updated and you will need to make your changes again." msgid "Someone edited this test case at the same time you did. The description has been updated and you will need to make your changes again."
msgstr "" msgstr ""
msgid "Someone signed in to your %{host} account from a new location"
msgstr ""
msgid "Someone, hopefully you, has requested to reset the password for your GitLab account on %{link_to_gitlab}." msgid "Someone, hopefully you, has requested to reset the password for your GitLab account on %{link_to_gitlab}."
msgstr "" msgstr ""
@ -46227,6 +46230,9 @@ msgstr ""
msgid "You are not allowed to create this tag as it is protected." msgid "You are not allowed to create this tag as it is protected."
msgstr "" msgstr ""
msgid "You are not allowed to download code from this project."
msgstr ""
msgid "You are not allowed to log in using password" msgid "You are not allowed to log in using password"
msgstr "" msgstr ""
@ -46849,9 +46855,6 @@ msgstr ""
msgid "Your %{group} membership will now expire in %{days}." msgid "Your %{group} membership will now expire in %{days}."
msgstr "" msgstr ""
msgid "Your %{host} account was signed in to from a new location"
msgstr ""
msgid "Your %{spammable_entity_type} has been recognized as spam and has been discarded." msgid "Your %{spammable_entity_type} has been recognized as spam and has been discarded."
msgstr "" msgstr ""

View File

@ -2,7 +2,7 @@
source 'https://rubygems.org' source 'https://rubygems.org'
gem 'gitlab-qa', '~> 8', '>= 8.10.0', require: 'gitlab/qa' gem 'gitlab-qa', '~> 8', '>= 8.10.1', require: 'gitlab/qa'
gem 'activesupport', '~> 6.1.4.7' # This should stay in sync with the root's Gemfile gem 'activesupport', '~> 6.1.4.7' # This should stay in sync with the root's Gemfile
gem 'allure-rspec', '~> 2.18.0' gem 'allure-rspec', '~> 2.18.0'
gem 'capybara', '~> 3.37.1' gem 'capybara', '~> 3.37.1'

View File

@ -100,7 +100,7 @@ GEM
gitlab (4.18.0) gitlab (4.18.0)
httparty (~> 0.18) httparty (~> 0.18)
terminal-table (>= 1.5.1) terminal-table (>= 1.5.1)
gitlab-qa (8.10.0) gitlab-qa (8.10.1)
activesupport (~> 6.1) activesupport (~> 6.1)
gitlab (~> 4.18.0) gitlab (~> 4.18.0)
http (~> 5.0) http (~> 5.0)
@ -312,7 +312,7 @@ DEPENDENCIES
faraday-retry (~> 2.0) faraday-retry (~> 2.0)
fog-core (= 2.1.0) fog-core (= 2.1.0)
fog-google (~> 1.19) fog-google (~> 1.19)
gitlab-qa (~> 8, >= 8.10.0) gitlab-qa (~> 8, >= 8.10.1)
influxdb-client (~> 2.8) influxdb-client (~> 2.8)
knapsack (~> 4.0) knapsack (~> 4.0)
nokogiri (~> 1.13, >= 1.13.9) nokogiri (~> 1.13, >= 1.13.9)

View File

@ -414,4 +414,114 @@ RSpec.describe GraphqlController do
expect(log_payload.dig(:exception_object)).to eq(exception) expect(log_payload.dig(:exception_object)).to eq(exception)
end end
end end
describe 'removal of deprecated items' do
let(:mock_schema) do
Class.new(GraphQL::Schema) do
lazy_resolve ::Gitlab::Graphql::Lazy, :force
query(Class.new(::Types::BaseObject) do
graphql_name 'Query'
field :foo, GraphQL::Types::Boolean,
deprecated: { milestone: '0.1', reason: :renamed }
field :bar, (Class.new(::Types::BaseEnum) do
graphql_name 'BarEnum'
value 'FOOBAR', value: 'foobar', deprecated: { milestone: '0.1', reason: :renamed }
end)
field :baz, GraphQL::Types::Boolean do
argument :arg, String, required: false, deprecated: { milestone: '0.1', reason: :renamed }
end
def foo
false
end
def bar
'foobar'
end
def baz(arg:)
false
end
end)
end
end
before do
allow(GitlabSchema).to receive(:execute).and_wrap_original do |method, *args|
mock_schema.execute(*args)
end
end
context 'without `remove_deprecated` param' do
let(:params) { { query: '{ foo bar baz(arg: "test") }' } }
subject { post :execute, params: params }
it "sets context's `remove_deprecated` value to false" do
subject
expect(assigns(:context)[:remove_deprecated]).to be false
end
it 'returns deprecated items in response' do
subject
expect(json_response).to include('data' => { 'foo' => false, 'bar' => 'FOOBAR', 'baz' => false })
end
end
context 'with `remove_deprecated` param' do
let(:params) { { remove_deprecated: 'true' } }
subject { post :execute, params: params }
it "sets context's `remove_deprecated` value to true" do
subject
expect(assigns(:context)[:remove_deprecated]).to be true
end
it 'does not allow deprecated field' do
params[:query] = '{ foo }'
subject
expect(json_response).not_to include('data' => { 'foo' => false })
expect(json_response).to include(
'errors' => include(a_hash_including('message' => /Field 'foo' doesn't exist on type 'Query'/))
)
end
it 'does not allow deprecated enum value' do
params[:query] = '{ bar }'
subject
expect(json_response).not_to include('data' => { 'bar' => 'FOOBAR' })
expect(json_response).to include(
'errors' => include(
a_hash_including(
'message' => /`Query.bar` returned `"foobar"` at `bar`, but this isn't a valid value for `BarEnum`/
)
)
)
end
it 'does not allow deprecated argument' do
params[:query] = '{ baz(arg: "test") }'
subject
expect(json_response).not_to include('data' => { 'bar' => 'FOOBAR' })
expect(json_response).to include(
'errors' => include(a_hash_including('message' => /Field 'baz' doesn't accept argument 'arg'/))
)
end
end
end
end end

View File

@ -400,9 +400,7 @@ RSpec.describe 'Merge request > User sees merge widget', :js do
it 'updates the MR widget', :sidekiq_might_not_need_inline do it 'updates the MR widget', :sidekiq_might_not_need_inline do
click_button 'Merge' click_button 'Merge'
page.within('.mr-widget-body') do expect(page).to have_content('An error occurred while merging')
expect(page).to have_content('An error occurred while merging')
end
end end
end end

View File

@ -9,7 +9,7 @@ RSpec.describe Mutations::ResolvesGroup do
end end
end end
let(:context) { double } let(:context) { {} }
subject(:mutation) { mutation_class.new(object: nil, context: context, field: nil) } subject(:mutation) { mutation_class.new(object: nil, context: context, field: nil) }

View File

@ -5799,7 +5799,7 @@ RSpec.describe Project, factory_default: :keep do
end end
describe '#has_active_integrations?' do describe '#has_active_integrations?' do
let_it_be(:project) { create(:project) } let_it_be_with_refind(:project) { create(:project) }
it { expect(project.has_active_integrations?).to eq(false) } it { expect(project.has_active_integrations?).to eq(false) }
@ -5809,6 +5809,20 @@ RSpec.describe Project, factory_default: :keep do
expect(project.has_active_integrations?(:merge_request_hooks)).to eq(false) expect(project.has_active_integrations?(:merge_request_hooks)).to eq(false)
expect(project.has_active_integrations?).to eq(true) expect(project.has_active_integrations?).to eq(true)
end end
it 'caches matching integrations' do
create(:custom_issue_tracker_integration, push_events: true, merge_requests_events: false, project: project)
expect(project.has_active_integrations?(:merge_request_hooks)).to eq(false)
expect(project.has_active_integrations?).to eq(true)
count = ActiveRecord::QueryRecorder.new do
expect(project.has_active_integrations?(:merge_request_hooks)).to eq(false)
expect(project.has_active_integrations?).to eq(true)
end.count
expect(count).to eq(0)
end
end end
describe '#badges' do describe '#badges' do

View File

@ -7,7 +7,7 @@ RSpec.describe API::Boards do
let_it_be(:non_member) { create(:user) } let_it_be(:non_member) { create(:user) }
let_it_be(:guest) { create(:user) } let_it_be(:guest) { create(:user) }
let_it_be(:admin) { create(:user, :admin) } let_it_be(:admin) { create(:user, :admin) }
let_it_be(:board_parent, reload: true) { create(:project, :public, creator_id: user.id, namespace: user.namespace ) } let_it_be(:board_parent, reload: true) { create(:project, :public, creator_id: user.id, namespace: user.namespace) }
let_it_be(:dev_label) do let_it_be(:dev_label) do
create(:label, title: 'Development', color: '#FFAABB', project: board_parent) create(:label, title: 'Development', color: '#FFAABB', project: board_parent)
@ -97,7 +97,7 @@ RSpec.describe API::Boards do
describe "POST /groups/:id/boards/:board_id/lists" do describe "POST /groups/:id/boards/:board_id/lists" do
let_it_be(:group) { create(:group) } let_it_be(:group) { create(:group) }
let_it_be(:board_parent) { create(:group, parent: group ) } let_it_be(:board_parent) { create(:group, parent: group) }
let(:url) { "/groups/#{board_parent.id}/boards/#{board.id}/lists" } let(:url) { "/groups/#{board_parent.id}/boards/#{board.id}/lists" }
let_it_be(:board) { create(:board, group: board_parent) } let_it_be(:board) { create(:board, group: board_parent) }

View File

@ -238,7 +238,7 @@ RSpec.describe API::Ci::Runner, :clean_gitlab_redis_shared_state do
context 'authorization token is invalid' do context 'authorization token is invalid' do
it 'responds with forbidden' do it 'responds with forbidden' do
authorize_artifacts(token: 'invalid', filesize: 100 ) authorize_artifacts(token: 'invalid', filesize: 100)
expect(response).to have_gitlab_http_status(:forbidden) expect(response).to have_gitlab_http_status(:forbidden)
end end

View File

@ -462,7 +462,7 @@ RSpec.describe API::Ci::Runner, :clean_gitlab_redis_shared_state do
request_job info: { 'config' => { 'gpus' => 'all', 'ignored' => 'hello' } } request_job info: { 'config' => { 'gpus' => 'all', 'ignored' => 'hello' } }
expect(response).to have_gitlab_http_status(:created) expect(response).to have_gitlab_http_status(:created)
expect(runner.reload.config).to eq( { 'gpus' => 'all' } ) expect(runner.reload.config).to eq({ 'gpus' => 'all' })
end end
it "sets the runner's ip_address" do it "sets the runner's ip_address" do

View File

@ -118,7 +118,7 @@ RSpec.describe API::Ci::Runners do
end end
include_context 'when authorized', 'group' do include_context 'when authorized', 'group' do
let_it_be(:user) { create_default(:group_member, :owner, user: create(:user), group: group ).user } let_it_be(:user) { create_default(:group_member, :owner, user: create(:user), group: group).user }
def get_token def get_token
group.reload.runners_token group.reload.runners_token

View File

@ -399,7 +399,7 @@ RSpec.describe API::Ci::Runners do
it 'unrelated runner attribute on an existing runner with too many tags' do it 'unrelated runner attribute on an existing runner with too many tags' do
# This test ensures that it is possible to update any attribute on a runner that currently fails the # This test ensures that it is possible to update any attribute on a runner that currently fails the
# validation that ensures that there aren't too many tags associated with a runner # validation that ensures that there aren't too many tags associated with a runner
existing_invalid_shared_runner = build(:ci_runner, :instance, tag_list: (1..::Ci::Runner::TAG_LIST_MAX_LENGTH + 1).map { |i| "tag#{i}" } ) existing_invalid_shared_runner = build(:ci_runner, :instance, tag_list: (1..::Ci::Runner::TAG_LIST_MAX_LENGTH + 1).map { |i| "tag#{i}" })
existing_invalid_shared_runner.save!(validate: false) existing_invalid_shared_runner.save!(validate: false)
active = existing_invalid_shared_runner.active active = existing_invalid_shared_runner.active

View File

@ -4,7 +4,7 @@ require 'spec_helper'
RSpec.describe API::DependencyProxy, api: true do RSpec.describe API::DependencyProxy, api: true do
let_it_be(:user) { create(:user) } let_it_be(:user) { create(:user) }
let_it_be(:blob) { create(:dependency_proxy_blob ) } let_it_be(:blob) { create(:dependency_proxy_blob) }
let_it_be(:group, reload: true) { blob.group } let_it_be(:group, reload: true) { blob.group }
before do before do

View File

@ -325,7 +325,7 @@ RSpec.describe API::Deployments do
context 'as non member' do context 'as non member' do
it 'returns a 404 status code' do it 'returns a 404 status code' do
post( post(
api( "/projects/#{project.id}/deployments", non_member), api("/projects/#{project.id}/deployments", non_member),
params: { params: {
environment: 'production', environment: 'production',
sha: '123', sha: '123',

View File

@ -11,7 +11,7 @@ RSpec.describe API::Files do
let_it_be(:inherited_reporter) { create(:user) } let_it_be(:inherited_reporter) { create(:user) }
let_it_be(:inherited_developer) { create(:user) } let_it_be(:inherited_developer) { create(:user) }
let!(:project) { create(:project, :repository, namespace: user.namespace ) } let!(:project) { create(:project, :repository, namespace: user.namespace) }
let(:guest) { create(:user) { |u| project.add_guest(u) } } let(:guest) { create(:user) { |u| project.add_guest(u) } }
let(:file_path) { 'files%2Fruby%2Fpopen%2Erb' } let(:file_path) { 'files%2Fruby%2Fpopen%2Erb' }
let(:file_name) { 'popen.rb' } let(:file_name) { 'popen.rb' }
@ -935,7 +935,7 @@ RSpec.describe API::Files do
end end
context 'and the repo is empty' do context 'and the repo is empty' do
let!(:project) { create(:project_empty_repo, namespace: user.namespace ) } let!(:project) { create(:project_empty_repo, namespace: user.namespace) }
it_behaves_like 'creates a new file in the project repo' do it_behaves_like 'creates a new file in the project repo' do
let(:current_user) { user } let(:current_user) { user }

View File

@ -16,12 +16,12 @@ RSpec.describe API::GoProxy do
let_it_be(:modules) do let_it_be(:modules) do
commits = [ commits = [
create(:go_module_commit, :files, project: project, tag: 'v1.0.0', files: { 'README.md' => 'Hi' } ), create(:go_module_commit, :files, project: project, tag: 'v1.0.0', files: { 'README.md' => 'Hi' }),
create(:go_module_commit, :module, project: project, tag: 'v1.0.1' ), create(:go_module_commit, :module, project: project, tag: 'v1.0.1'),
create(:go_module_commit, :package, project: project, tag: 'v1.0.2', path: 'pkg' ), create(:go_module_commit, :package, project: project, tag: 'v1.0.2', path: 'pkg'),
create(:go_module_commit, :module, project: project, tag: 'v1.0.3', name: 'mod' ), create(:go_module_commit, :module, project: project, tag: 'v1.0.3', name: 'mod'),
create(:go_module_commit, :files, project: project, files: { 'y.go' => "package a\n" } ), create(:go_module_commit, :files, project: project, files: { 'y.go' => "package a\n" }),
create(:go_module_commit, :module, project: project, name: 'v2' ), create(:go_module_commit, :module, project: project, name: 'v2'),
create(:go_module_commit, :files, project: project, tag: 'v2.0.0', files: { 'v2/x.go' => "package a\n" }) create(:go_module_commit, :files, project: project, tag: 'v2.0.0', files: { 'v2/x.go' => "package a\n" })
] ]
@ -288,10 +288,10 @@ RSpec.describe API::GoProxy do
let_it_be(:base) { "#{Settings.build_gitlab_go_url}/#{project.full_path}" } let_it_be(:base) { "#{Settings.build_gitlab_go_url}/#{project.full_path}" }
let_it_be(:modules) do let_it_be(:modules) do
create(:go_module_commit, :files, project: project, files: { 'a.go' => "package\a" } ) create(:go_module_commit, :files, project: project, files: { 'a.go' => "package\a" })
create(:go_module_commit, :files, project: project, tag: 'v1.0.0', files: { 'go.mod' => "module not/a/real/module\n" }) create(:go_module_commit, :files, project: project, tag: 'v1.0.0', files: { 'go.mod' => "module not/a/real/module\n" })
create(:go_module_commit, :files, project: project, files: { 'v2/a.go' => "package a\n" } ) create(:go_module_commit, :files, project: project, files: { 'v2/a.go' => "package a\n" })
create(:go_module_commit, :files, project: project, tag: 'v2.0.0', files: { 'v2/go.mod' => "module #{base}\n" } ) create(:go_module_commit, :files, project: project, tag: 'v2.0.0', files: { 'v2/go.mod' => "module #{base}\n" })
end end
describe 'GET /projects/:id/packages/go/*module_name/@v/list' do describe 'GET /projects/:id/packages/go/*module_name/@v/list' do

View File

@ -7,7 +7,7 @@ RSpec.describe 'get board lists' do
let_it_be(:user) { create(:user) } let_it_be(:user) { create(:user) }
let_it_be(:unauth_user) { create(:user) } let_it_be(:unauth_user) { create(:user) }
let_it_be(:project) { create(:project, creator_id: user.id, namespace: user.namespace ) } let_it_be(:project) { create(:project, creator_id: user.id, namespace: user.namespace) }
let_it_be(:group) { create(:group, :private) } let_it_be(:group) { create(:group, :private) }
let_it_be(:project_label) { create(:label, project: project, name: 'Development') } let_it_be(:project_label) { create(:label, project: project, name: 'Development') }
let_it_be(:project_label2) { create(:label, project: project, name: 'Testing') } let_it_be(:project_label2) { create(:label, project: project, name: 'Testing') }

View File

@ -109,7 +109,7 @@ RSpec.describe 'Query.project.pipeline' do
'name' => 'docker 1 2', 'name' => 'docker 1 2',
'needs' => { 'nodes' => [] }, 'needs' => { 'nodes' => [] },
'previousStageJobsOrNeeds' => { 'nodes' => [ 'previousStageJobsOrNeeds' => { 'nodes' => [
a_hash_including( 'name' => 'my test job' ) a_hash_including('name' => 'my test job')
] } ] }
), ),
a_hash_including( a_hash_including(
@ -129,7 +129,7 @@ RSpec.describe 'Query.project.pipeline' do
'name' => 'rspec 2 2', 'name' => 'rspec 2 2',
'needs' => { 'nodes' => [a_hash_including('name' => 'my test job')] }, 'needs' => { 'nodes' => [a_hash_including('name' => 'my test job')] },
'previousStageJobsOrNeeds' => { 'nodes' => [ 'previousStageJobsOrNeeds' => { 'nodes' => [
a_hash_including('name' => 'my test job' ) a_hash_including('name' => 'my test job')
] } ] }
) )
) )

View File

@ -419,7 +419,7 @@ RSpec.describe 'Query.project(fullPath).pipelines' do
end end
before do before do
create(:ci_sources_pipeline, source_pipeline: upstream_pipeline, pipeline: pipeline ) create(:ci_sources_pipeline, source_pipeline: upstream_pipeline, pipeline: pipeline)
post_graphql(query, current_user: user) post_graphql(query, current_user: user)
end end
@ -441,10 +441,10 @@ RSpec.describe 'Query.project(fullPath).pipelines' do
pipeline_2 = create(:ci_pipeline, project: project, user: user) pipeline_2 = create(:ci_pipeline, project: project, user: user)
upstream_pipeline_2 = create(:ci_pipeline, project: upstream_project, user: user) upstream_pipeline_2 = create(:ci_pipeline, project: upstream_project, user: user)
create(:ci_sources_pipeline, source_pipeline: upstream_pipeline_2, pipeline: pipeline_2 ) create(:ci_sources_pipeline, source_pipeline: upstream_pipeline_2, pipeline: pipeline_2)
pipeline_3 = create(:ci_pipeline, project: project, user: user) pipeline_3 = create(:ci_pipeline, project: project, user: user)
upstream_pipeline_3 = create(:ci_pipeline, project: upstream_project, user: user) upstream_pipeline_3 = create(:ci_pipeline, project: upstream_project, user: user)
create(:ci_sources_pipeline, source_pipeline: upstream_pipeline_3, pipeline: pipeline_3 ) create(:ci_sources_pipeline, source_pipeline: upstream_pipeline_3, pipeline: pipeline_3)
expect do expect do
post_graphql(query, current_user: second_user) post_graphql(query, current_user: second_user)

View File

@ -20,7 +20,7 @@ RSpec.describe 'Removing an AwardEmoji' do
end end
def create_award_emoji(user) def create_award_emoji(user)
create(:award_emoji, name: emoji_name, awardable: awardable, user: user ) create(:award_emoji, name: emoji_name, awardable: awardable, user: user)
end end
shared_examples 'a mutation that does not destroy an AwardEmoji' do shared_examples 'a mutation that does not destroy an AwardEmoji' do

View File

@ -32,7 +32,7 @@ RSpec.describe 'Toggling an AwardEmoji' do
end end
def create_award_emoji(user) def create_award_emoji(user)
create(:award_emoji, name: emoji_name, awardable: awardable, user: user ) create(:award_emoji, name: emoji_name, awardable: awardable, user: user)
end end
context 'when the user has permission' do context 'when the user has permission' do

View File

@ -87,7 +87,7 @@ RSpec.describe 'RunnersRegistrationTokenReset' do
include_context('when unauthorized', 'group') include_context('when unauthorized', 'group')
include_context 'when authorized', 'group' do include_context 'when authorized', 'group' do
let_it_be(:user) { create_default(:group_member, :owner, user: create(:user), group: group ).user } let_it_be(:user) { create_default(:group_member, :owner, user: create(:user), group: group).user }
def get_token def get_token
group.reload.runners_token group.reload.runners_token

View File

@ -13,7 +13,7 @@ RSpec.describe API::GroupBoards do
board_parent.add_owner(user) board_parent.add_owner(user)
end end
let_it_be(:project) { create(:project, :public, namespace: board_parent ) } let_it_be(:project) { create(:project, :public, namespace: board_parent) }
let_it_be(:dev_label) do let_it_be(:dev_label) do
create(:group_label, title: 'Development', color: '#FFAABB', group: board_parent) create(:group_label, title: 'Development', color: '#FFAABB', group: board_parent)

View File

@ -92,7 +92,7 @@ RSpec.describe API::Issues do
describe 'GET /issues/:id' do describe 'GET /issues/:id' do
context 'when unauthorized' do context 'when unauthorized' do
it 'returns unauthorized' do it 'returns unauthorized' do
get api("/issues/#{issue.id}" ) get api("/issues/#{issue.id}")
expect(response).to have_gitlab_http_status(:unauthorized) expect(response).to have_gitlab_http_status(:unauthorized)
end end
@ -101,7 +101,7 @@ RSpec.describe API::Issues do
context 'when authorized' do context 'when authorized' do
context 'as a normal user' do context 'as a normal user' do
it 'returns forbidden' do it 'returns forbidden' do
get api("/issues/#{issue.id}", user ) get api("/issues/#{issue.id}", user)
expect(response).to have_gitlab_http_status(:forbidden) expect(response).to have_gitlab_http_status(:forbidden)
end end

View File

@ -473,8 +473,8 @@ RSpec.describe API::Issues do
end end
describe '/projects/:id/issues/:issue_iid/move' do describe '/projects/:id/issues/:issue_iid/move' do
let!(:target_project) { create(:project, creator_id: user.id, namespace: user.namespace ) } let!(:target_project) { create(:project, creator_id: user.id, namespace: user.namespace) }
let!(:target_project2) { create(:project, creator_id: non_member.id, namespace: non_member.namespace ) } let!(:target_project2) { create(:project, creator_id: non_member.id, namespace: non_member.namespace) }
it 'moves an issue' do it 'moves an issue' do
post api("/projects/#{project.id}/issues/#{issue.iid}/move", user), post api("/projects/#{project.id}/issues/#{issue.iid}/move", user),

View File

@ -234,7 +234,7 @@ RSpec.describe API::Labels do
before do before do
create(:labeled_issue, project: project, labels: [group_label], author: user) create(:labeled_issue, project: project, labels: [group_label], author: user)
create(:labeled_issue, project: project, labels: [label1], author: user, state: :closed) create(:labeled_issue, project: project, labels: [label1], author: user, state: :closed)
create(:labeled_merge_request, labels: [priority_label], author: user, source_project: project ) create(:labeled_merge_request, labels: [priority_label], author: user, source_project: project)
end end
it 'includes counts in the response' do it 'includes counts in the response' do

View File

@ -3022,7 +3022,7 @@ RSpec.describe API::MergeRequests do
describe "PUT /projects/:id/merge_requests/:merge_request_iid" do describe "PUT /projects/:id/merge_requests/:merge_request_iid" do
context 'updates force_remove_source_branch properly' do context 'updates force_remove_source_branch properly' do
it 'sets to false' do it 'sets to false' do
merge_request.update!(merge_params: { 'force_remove_source_branch' => true } ) merge_request.update!(merge_params: { 'force_remove_source_branch' => true })
expect(merge_request.force_remove_source_branch?).to be_truthy expect(merge_request.force_remove_source_branch?).to be_truthy
@ -3034,7 +3034,7 @@ RSpec.describe API::MergeRequests do
end end
it 'sets to true' do it 'sets to true' do
merge_request.update!(merge_params: { 'force_remove_source_branch' => false } ) merge_request.update!(merge_params: { 'force_remove_source_branch' => false })
expect(merge_request.force_remove_source_branch?).to be false expect(merge_request.force_remove_source_branch?).to be false

View File

@ -253,7 +253,7 @@ RSpec.describe API::Ml::Mlflow do
it 'creates the experiment', :aggregate_failures do it 'creates the experiment', :aggregate_failures do
expect(response).to have_gitlab_http_status(:ok) expect(response).to have_gitlab_http_status(:ok)
expect(json_response).to include('experiment_id' ) expect(json_response).to include('experiment_id')
end end
describe 'Error States' do describe 'Error States' do

View File

@ -36,7 +36,7 @@ RSpec.describe API::Pages do
end end
it 'removes the pages' do it 'removes the pages' do
delete api("/projects/#{project.id}/pages", admin ) delete api("/projects/#{project.id}/pages", admin)
expect(project.reload.pages_metadatum.deployed?).to be(false) expect(project.reload.pages_metadatum.deployed?).to be(false)
end end

View File

@ -87,7 +87,7 @@ RSpec.describe API::PersonalAccessTokens do
end end
context 'filter with created parameter' do context 'filter with created parameter' do
let_it_be(:token1) { create(:personal_access_token, created_at: DateTime.new(2022, 01, 01, 12, 30, 25) ) } let_it_be(:token1) { create(:personal_access_token, created_at: DateTime.new(2022, 01, 01, 12, 30, 25)) }
context 'test created_before' do context 'test created_before' do
where(:created_at, :status, :result_count, :result) do where(:created_at, :status, :result_count, :result) do
@ -121,7 +121,7 @@ RSpec.describe API::PersonalAccessTokens do
end end
context 'filter with last_used parameter' do context 'filter with last_used parameter' do
let_it_be(:token1) { create(:personal_access_token, last_used_at: DateTime.new(2022, 01, 01, 12, 30, 25) ) } let_it_be(:token1) { create(:personal_access_token, last_used_at: DateTime.new(2022, 01, 01, 12, 30, 25)) }
let_it_be(:never_used_token) { create(:personal_access_token) } let_it_be(:never_used_token) { create(:personal_access_token) }
context 'test last_used_before' do context 'test last_used_before' do
@ -209,13 +209,13 @@ RSpec.describe API::PersonalAccessTokens do
expect(response).to have_gitlab_http_status(status) expect(response).to have_gitlab_http_status(status)
expect(json_response.map { |pat| pat['id'] } ).to include(*result) if status == :ok expect(json_response.map { |pat| pat['id'] }).to include(*result) if status == :ok
end end
end end
end end
context 'filter last_used_before and last_used_after combined is valid' do context 'filter last_used_before and last_used_after combined is valid' do
let_it_be(:token1) { create(:personal_access_token, last_used_at: DateTime.new(2022, 01, 02) ) } let_it_be(:token1) { create(:personal_access_token, last_used_at: DateTime.new(2022, 01, 02)) }
where(:last_used_before, :last_used_after, :status, :result) do where(:last_used_before, :last_used_after, :status, :result) do
'2022-01-02' | '2022-01-02' | :ok | lazy { [token1.id] } '2022-01-02' | '2022-01-02' | :ok | lazy { [token1.id] }
@ -232,7 +232,7 @@ RSpec.describe API::PersonalAccessTokens do
expect(response).to have_gitlab_http_status(status) expect(response).to have_gitlab_http_status(status)
expect(json_response.map { |pat| pat['id'] } ).to include(*result) if status == :ok expect(json_response.map { |pat| pat['id'] }).to include(*result) if status == :ok
end end
end end
end end
@ -304,7 +304,7 @@ RSpec.describe API::PersonalAccessTokens do
# Here it is only tested whether PATs to which the user has no access right are excluded from the filter function. # Here it is only tested whether PATs to which the user has no access right are excluded from the filter function.
context 'filter with created parameter' do context 'filter with created parameter' do
let_it_be(:token1) do let_it_be(:token1) do
create(:personal_access_token, created_at: DateTime.new(2022, 01, 02, 12, 30, 25), user: current_user ) create(:personal_access_token, created_at: DateTime.new(2022, 01, 02, 12, 30, 25), user: current_user)
end end
let_it_be(:token2) { create(:personal_access_token, created_at: DateTime.new(2022, 01, 02, 12, 30, 25)) } let_it_be(:token2) { create(:personal_access_token, created_at: DateTime.new(2022, 01, 02, 12, 30, 25)) }
@ -332,7 +332,7 @@ RSpec.describe API::PersonalAccessTokens do
create(:personal_access_token, last_used_at: DateTime.new(2022, 01, 01, 12, 30, 25), user: current_user) create(:personal_access_token, last_used_at: DateTime.new(2022, 01, 01, 12, 30, 25), user: current_user)
end end
let_it_be(:token2) { create(:personal_access_token, last_used_at: DateTime.new(2022, 01, 01, 12, 30, 25) ) } let_it_be(:token2) { create(:personal_access_token, last_used_at: DateTime.new(2022, 01, 01, 12, 30, 25)) }
let_it_be(:never_used_token) { create(:personal_access_token) } let_it_be(:never_used_token) { create(:personal_access_token) }
let_it_be(:status) { :ok } let_it_be(:status) { :ok }

View File

@ -4,7 +4,7 @@ require 'spec_helper'
RSpec.describe API::ProjectMilestones do RSpec.describe API::ProjectMilestones do
let_it_be(:user) { create(:user) } let_it_be(:user) { create(:user) }
let_it_be_with_reload(:project) { create(:project, namespace: user.namespace ) } let_it_be_with_reload(:project) { create(:project, namespace: user.namespace) }
let_it_be(:closed_milestone) { create(:closed_milestone, project: project, title: 'version1', description: 'closed milestone') } let_it_be(:closed_milestone) { create(:closed_milestone, project: project, title: 'version1', description: 'closed milestone') }
let_it_be(:milestone) { create(:milestone, project: project, title: 'version2', description: 'open milestone') } let_it_be(:milestone) { create(:milestone, project: project, title: 'version2', description: 'open milestone') }
let_it_be(:route) { "/projects/#{project.id}/milestones" } let_it_be(:route) { "/projects/#{project.id}/milestones" }

View File

@ -89,7 +89,7 @@ RSpec.describe API::ProjectSnippets do
expect(json_response['title']).to eq(snippet.title) expect(json_response['title']).to eq(snippet.title)
expect(json_response['description']).to eq(snippet.description) expect(json_response['description']).to eq(snippet.description)
expect(json_response['file_name']).to eq(snippet.file_name_on_repo) expect(json_response['file_name']).to eq(snippet.file_name_on_repo)
expect(json_response['files']).to eq(snippet.blobs.map { |blob| snippet_blob_file(blob) } ) expect(json_response['files']).to eq(snippet.blobs.map { |blob| snippet_blob_file(blob) })
expect(json_response['ssh_url_to_repo']).to eq(snippet.ssh_url_to_repo) expect(json_response['ssh_url_to_repo']).to eq(snippet.ssh_url_to_repo)
expect(json_response['http_url_to_repo']).to eq(snippet.http_url_to_repo) expect(json_response['http_url_to_repo']).to eq(snippet.http_url_to_repo)
end end

View File

@ -28,7 +28,7 @@ RSpec.describe API::Snippets, factory_default: :keep do
expect(response).to have_gitlab_http_status(:ok) expect(response).to have_gitlab_http_status(:ok)
expect(response).to include_pagination_headers expect(response).to include_pagination_headers
expect(json_response).to be_an Array expect(json_response).to be_an Array
expect(json_response.map { |snippet| snippet['id'] } ).to contain_exactly( expect(json_response.map { |snippet| snippet['id'] }).to contain_exactly(
public_snippet.id, public_snippet.id,
internal_snippet.id, internal_snippet.id,
private_snippet.id) private_snippet.id)
@ -75,7 +75,7 @@ RSpec.describe API::Snippets, factory_default: :keep do
it 'returns snippets available for user in given time range' do it 'returns snippets available for user in given time range' do
get api(path, personal_access_token: user_token) get api(path, personal_access_token: user_token)
expect(json_response.map { |snippet| snippet['id'] } ).to contain_exactly( expect(json_response.map { |snippet| snippet['id'] }).to contain_exactly(
private_snippet_in_time_range1.id, private_snippet_in_time_range1.id,
private_snippet_in_time_range2.id) private_snippet_in_time_range2.id)
end end
@ -99,10 +99,10 @@ RSpec.describe API::Snippets, factory_default: :keep do
expect(response).to have_gitlab_http_status(:ok) expect(response).to have_gitlab_http_status(:ok)
expect(response).to include_pagination_headers expect(response).to include_pagination_headers
expect(json_response).to be_an Array expect(json_response).to be_an Array
expect(json_response.map { |snippet| snippet['id'] } ).to contain_exactly( expect(json_response.map { |snippet| snippet['id'] }).to contain_exactly(
public_snippet.id, public_snippet.id,
public_snippet_other.id) public_snippet_other.id)
expect(json_response.map { |snippet| snippet['web_url'] } ).to contain_exactly( expect(json_response.map { |snippet| snippet['web_url'] }).to contain_exactly(
"http://localhost/-/snippets/#{public_snippet.id}", "http://localhost/-/snippets/#{public_snippet.id}",
"http://localhost/-/snippets/#{public_snippet_other.id}") "http://localhost/-/snippets/#{public_snippet_other.id}")
expect(json_response[0]['files'].first).to eq snippet_blob_file(public_snippet_other.blobs.first) expect(json_response[0]['files'].first).to eq snippet_blob_file(public_snippet_other.blobs.first)
@ -126,7 +126,7 @@ RSpec.describe API::Snippets, factory_default: :keep do
it 'returns public snippets available to user in given time range' do it 'returns public snippets available to user in given time range' do
get api(path, personal_access_token: user_token) get api(path, personal_access_token: user_token)
expect(json_response.map { |snippet| snippet['id'] } ).to contain_exactly( expect(json_response.map { |snippet| snippet['id'] }).to contain_exactly(
public_snippet_in_time_range.id) public_snippet_in_time_range.id)
end end
end end

View File

@ -4,7 +4,7 @@ require 'spec_helper'
RSpec.describe API::Submodules do RSpec.describe API::Submodules do
let(:user) { create(:user) } let(:user) { create(:user) }
let!(:project) { create(:project, :repository, namespace: user.namespace ) } let!(:project) { create(:project, :repository, namespace: user.namespace) }
let(:guest) { create(:user) { |u| project.add_guest(u) } } let(:guest) { create(:user) { |u| project.add_guest(u) } }
let(:submodule) { 'six' } let(:submodule) { 'six' }
let(:commit_sha) { 'e25eda1fece24ac7a03624ed1320f82396f35bd8' } let(:commit_sha) { 'e25eda1fece24ac7a03624ed1320f82396f35bd8' }

View File

@ -86,4 +86,25 @@ RSpec.shared_examples 'Gitlab-style deprecations' do
eq("`alpha` and `deprecated` arguments cannot be passed at the same time") eq("`alpha` and `deprecated` arguments cannot be passed at the same time")
) )
end end
describe 'visible?' do
let(:ctx) { {} }
it 'defaults to true' do
expect(subject).to be_visible(ctx)
end
context 'when subject is deprecated' do
let(:arguments) { { deprecated: { milestone: '1.10', reason: :renamed } } }
it 'defaults to true' do
expect(subject(arguments)).to be_visible(ctx)
end
it 'returns false if `remove_deprecated` is true in context' do
ctx = { remove_deprecated: true }
expect(subject(arguments)).not_to be_visible(ctx)
end
end
end
end end