Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
cb48c93abf
commit
a70e2c0418
|
@ -336,6 +336,15 @@ Graphql/AuthorizeTypes:
|
|||
- 'spec/**/*.rb'
|
||||
- 'ee/spec/**/*.rb'
|
||||
|
||||
Graphql/JSONType:
|
||||
Enabled: true
|
||||
Include:
|
||||
- 'app/graphql/types/**/*'
|
||||
- 'ee/app/graphql/types/**/*'
|
||||
Exclude:
|
||||
- 'spec/**/*.rb'
|
||||
- 'ee/spec/**/*.rb'
|
||||
|
||||
RSpec/EnvAssignment:
|
||||
Enable: true
|
||||
Include:
|
||||
|
|
|
@ -1249,24 +1249,6 @@ Rails/SaveBang:
|
|||
Exclude:
|
||||
- 'ee/spec/controllers/projects/merge_requests_controller_spec.rb'
|
||||
- 'ee/spec/controllers/subscriptions_controller_spec.rb'
|
||||
- 'ee/spec/features/admin/admin_users_spec.rb'
|
||||
- 'ee/spec/features/admin/geo/admin_geo_nodes_spec.rb'
|
||||
- 'ee/spec/features/admin/licenses/admin_views_license_spec.rb'
|
||||
- 'ee/spec/features/boards/scoped_issue_board_spec.rb'
|
||||
- 'ee/spec/features/ci_shared_runner_warnings_spec.rb'
|
||||
- 'ee/spec/features/dashboards/operations_spec.rb'
|
||||
- 'ee/spec/features/issues/gfm_autocomplete_ee_spec.rb'
|
||||
- 'ee/spec/features/merge_request/user_approves_spec.rb'
|
||||
- 'ee/spec/features/merge_requests/user_views_all_merge_requests_spec.rb'
|
||||
- 'ee/spec/features/projects/members/invite_group_and_members_spec.rb'
|
||||
- 'ee/spec/features/projects/merge_requests/user_approves_merge_request_spec.rb'
|
||||
- 'ee/spec/features/projects/mirror_spec.rb'
|
||||
- 'ee/spec/features/projects/new_project_spec.rb'
|
||||
- 'ee/spec/features/projects/settings/user_manages_approval_settings_spec.rb'
|
||||
- 'ee/spec/features/projects/settings/user_manages_members_spec.rb'
|
||||
- 'ee/spec/features/search/elastic/global_search_spec.rb'
|
||||
- 'ee/spec/features/security/project/internal_access_spec.rb'
|
||||
- 'ee/spec/features/security/project/public_access_spec.rb'
|
||||
- 'ee/spec/finders/epics_finder_spec.rb'
|
||||
- 'ee/spec/finders/security/vulnerabilities_finder_spec.rb'
|
||||
- 'ee/spec/frontend/fixtures/analytics.rb'
|
||||
|
|
|
@ -71,7 +71,7 @@ module Types
|
|||
description: 'Number of events of this alert',
|
||||
method: :events
|
||||
|
||||
field :details,
|
||||
field :details, # rubocop:disable Graphql/JSONType
|
||||
GraphQL::Types::JSON,
|
||||
null: true,
|
||||
description: 'Alert details'
|
||||
|
|
|
@ -56,7 +56,7 @@ class Service < ApplicationRecord
|
|||
validates :instance, uniqueness: { scope: :type }, if: -> { instance? }
|
||||
validate :validate_is_instance_or_template
|
||||
|
||||
scope :issue_trackers, -> { where(category: 'issue_tracker') }
|
||||
scope :external_issue_trackers, -> { where(category: 'issue_tracker').active }
|
||||
scope :external_wikis, -> { where(type: 'ExternalWikiService').active }
|
||||
scope :active, -> { where(active: true) }
|
||||
scope :by_type, -> (type) { where(type: type) }
|
||||
|
@ -76,7 +76,6 @@ class Service < ApplicationRecord
|
|||
scope :wiki_page_hooks, -> { where(wiki_page_events: true, active: true) }
|
||||
scope :deployment_hooks, -> { where(deployment_events: true, active: true) }
|
||||
scope :alert_hooks, -> { where(alert_events: true, active: true) }
|
||||
scope :external_issue_trackers, -> { issue_trackers.active }
|
||||
scope :deployment, -> { where(category: 'deployment') }
|
||||
|
||||
default_value_for :category, 'common'
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Refactor ee/spec/features/* to fix SaveBang Cop
|
||||
merge_request: 38289
|
||||
author: Rajendra Kadam
|
||||
type: fixed
|
|
@ -325,9 +325,11 @@ Example response:
|
|||
"design_repositories_failed_count": nil,
|
||||
"design_repositories_synced_in_percentage": "0.00%",
|
||||
"projects_count": 41,
|
||||
"repositories_count": 41,
|
||||
"repositories_failed_count": nil,
|
||||
"repositories_synced_count": nil,
|
||||
"repositories_synced_in_percentage": "0.00%",
|
||||
"wikis_count": 41,
|
||||
"wikis_failed_count": nil,
|
||||
"wikis_synced_count": nil,
|
||||
"wikis_synced_in_percentage": "0.00%",
|
||||
|
@ -402,9 +404,11 @@ Example response:
|
|||
"design_repositories_failed_count": nil,
|
||||
"design_repositories_synced_in_percentage": "0.00%",
|
||||
"projects_count": 41,
|
||||
"repositories_count": 41,
|
||||
"repositories_failed_count": 1,
|
||||
"repositories_synced_count": 40,
|
||||
"repositories_synced_in_percentage": "97.56%",
|
||||
"wikis_count": 41,
|
||||
"wikis_failed_count": 0,
|
||||
"wikis_synced_count": 41,
|
||||
"wikis_synced_in_percentage": "100.00%",
|
||||
|
@ -448,9 +452,6 @@ Example response:
|
|||
]
|
||||
```
|
||||
|
||||
NOTE: **Note:**
|
||||
In GitLab 12.0, deprecated fields `wikis_count` and `repositories_count` were removed. Use `projects_count` instead.
|
||||
|
||||
## Retrieve status about a specific Geo node
|
||||
|
||||
```plaintext
|
||||
|
@ -495,9 +496,11 @@ Example response:
|
|||
"design_repositories_failed_count": nil,
|
||||
"design_repositories_synced_in_percentage": "0.00%",
|
||||
"projects_count": 41,
|
||||
"repositories_count": 41,
|
||||
"repositories_failed_count": 1,
|
||||
"repositories_synced_count": 40,
|
||||
"repositories_synced_in_percentage": "97.56%",
|
||||
"wikis_count": 41,
|
||||
"wikis_failed_count": 0,
|
||||
"wikis_synced_count": 41,
|
||||
"wikis_synced_in_percentage": "100.00%",
|
||||
|
@ -517,9 +520,6 @@ Example response:
|
|||
|
||||
Note: The `health_status` parameter can only be in an "Healthy" or "Unhealthy" state, while the `health` parameter can be empty, "Healthy", or contain the actual error message.
|
||||
|
||||
NOTE: **Note:**
|
||||
In GitLab 12.0, deprecated fields `wikis_count` and `repositories_count` were removed. Use `projects_count` instead.
|
||||
|
||||
## Retrieve project sync or verification failures that occurred on the current node
|
||||
|
||||
This only works on a secondary node.
|
||||
|
|
|
@ -1964,7 +1964,12 @@ input CreateIterationInput {
|
|||
"""
|
||||
The target group for the iteration
|
||||
"""
|
||||
groupPath: ID!
|
||||
groupPath: ID
|
||||
|
||||
"""
|
||||
The target project for the iteration
|
||||
"""
|
||||
projectPath: ID
|
||||
|
||||
"""
|
||||
The start date of the iteration
|
||||
|
@ -9714,6 +9719,68 @@ type Project {
|
|||
"""
|
||||
issuesEnabled: Boolean
|
||||
|
||||
"""
|
||||
Find iterations
|
||||
"""
|
||||
iterations(
|
||||
"""
|
||||
Returns the elements in the list that come after the specified cursor.
|
||||
"""
|
||||
after: String
|
||||
|
||||
"""
|
||||
Returns the elements in the list that come before the specified cursor.
|
||||
"""
|
||||
before: String
|
||||
|
||||
"""
|
||||
List items within a time frame where items.end_date is between startDate and
|
||||
endDate parameters (startDate parameter must be present)
|
||||
"""
|
||||
endDate: Time
|
||||
|
||||
"""
|
||||
Returns the first _n_ elements from the list.
|
||||
"""
|
||||
first: Int
|
||||
|
||||
"""
|
||||
The ID of the Iteration to look up
|
||||
"""
|
||||
id: ID
|
||||
|
||||
"""
|
||||
The internal ID of the Iteration to look up
|
||||
"""
|
||||
iid: ID
|
||||
|
||||
"""
|
||||
Whether to include ancestor iterations. Defaults to true
|
||||
"""
|
||||
includeAncestors: Boolean
|
||||
|
||||
"""
|
||||
Returns the last _n_ elements from the list.
|
||||
"""
|
||||
last: Int
|
||||
|
||||
"""
|
||||
List items within a time frame where items.start_date is between startDate
|
||||
and endDate parameters (endDate parameter must be present)
|
||||
"""
|
||||
startDate: Time
|
||||
|
||||
"""
|
||||
Filter iterations by state
|
||||
"""
|
||||
state: IterationState
|
||||
|
||||
"""
|
||||
Fuzzy search by title
|
||||
"""
|
||||
title: String
|
||||
): IterationConnection
|
||||
|
||||
"""
|
||||
Status of Jira import background job of the project
|
||||
"""
|
||||
|
|
|
@ -5202,13 +5202,19 @@
|
|||
"name": "groupPath",
|
||||
"description": "The target group for the iteration",
|
||||
"type": {
|
||||
"kind": "NON_NULL",
|
||||
"name": null,
|
||||
"ofType": {
|
||||
"kind": "SCALAR",
|
||||
"name": "ID",
|
||||
"ofType": null
|
||||
}
|
||||
"kind": "SCALAR",
|
||||
"name": "ID",
|
||||
"ofType": null
|
||||
},
|
||||
"defaultValue": null
|
||||
},
|
||||
{
|
||||
"name": "projectPath",
|
||||
"description": "The target project for the iteration",
|
||||
"type": {
|
||||
"kind": "SCALAR",
|
||||
"name": "ID",
|
||||
"ofType": null
|
||||
},
|
||||
"defaultValue": null
|
||||
},
|
||||
|
@ -28960,6 +28966,129 @@
|
|||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "iterations",
|
||||
"description": "Find iterations",
|
||||
"args": [
|
||||
{
|
||||
"name": "startDate",
|
||||
"description": "List items within a time frame where items.start_date is between startDate and endDate parameters (endDate parameter must be present)",
|
||||
"type": {
|
||||
"kind": "SCALAR",
|
||||
"name": "Time",
|
||||
"ofType": null
|
||||
},
|
||||
"defaultValue": null
|
||||
},
|
||||
{
|
||||
"name": "endDate",
|
||||
"description": "List items within a time frame where items.end_date is between startDate and endDate parameters (startDate parameter must be present)",
|
||||
"type": {
|
||||
"kind": "SCALAR",
|
||||
"name": "Time",
|
||||
"ofType": null
|
||||
},
|
||||
"defaultValue": null
|
||||
},
|
||||
{
|
||||
"name": "state",
|
||||
"description": "Filter iterations by state",
|
||||
"type": {
|
||||
"kind": "ENUM",
|
||||
"name": "IterationState",
|
||||
"ofType": null
|
||||
},
|
||||
"defaultValue": null
|
||||
},
|
||||
{
|
||||
"name": "title",
|
||||
"description": "Fuzzy search by title",
|
||||
"type": {
|
||||
"kind": "SCALAR",
|
||||
"name": "String",
|
||||
"ofType": null
|
||||
},
|
||||
"defaultValue": null
|
||||
},
|
||||
{
|
||||
"name": "id",
|
||||
"description": "The ID of the Iteration to look up",
|
||||
"type": {
|
||||
"kind": "SCALAR",
|
||||
"name": "ID",
|
||||
"ofType": null
|
||||
},
|
||||
"defaultValue": null
|
||||
},
|
||||
{
|
||||
"name": "iid",
|
||||
"description": "The internal ID of the Iteration to look up",
|
||||
"type": {
|
||||
"kind": "SCALAR",
|
||||
"name": "ID",
|
||||
"ofType": null
|
||||
},
|
||||
"defaultValue": null
|
||||
},
|
||||
{
|
||||
"name": "includeAncestors",
|
||||
"description": "Whether to include ancestor iterations. Defaults to true",
|
||||
"type": {
|
||||
"kind": "SCALAR",
|
||||
"name": "Boolean",
|
||||
"ofType": null
|
||||
},
|
||||
"defaultValue": null
|
||||
},
|
||||
{
|
||||
"name": "after",
|
||||
"description": "Returns the elements in the list that come after the specified cursor.",
|
||||
"type": {
|
||||
"kind": "SCALAR",
|
||||
"name": "String",
|
||||
"ofType": null
|
||||
},
|
||||
"defaultValue": null
|
||||
},
|
||||
{
|
||||
"name": "before",
|
||||
"description": "Returns the elements in the list that come before the specified cursor.",
|
||||
"type": {
|
||||
"kind": "SCALAR",
|
||||
"name": "String",
|
||||
"ofType": null
|
||||
},
|
||||
"defaultValue": null
|
||||
},
|
||||
{
|
||||
"name": "first",
|
||||
"description": "Returns the first _n_ elements from the list.",
|
||||
"type": {
|
||||
"kind": "SCALAR",
|
||||
"name": "Int",
|
||||
"ofType": null
|
||||
},
|
||||
"defaultValue": null
|
||||
},
|
||||
{
|
||||
"name": "last",
|
||||
"description": "Returns the last _n_ elements from the list.",
|
||||
"type": {
|
||||
"kind": "SCALAR",
|
||||
"name": "Int",
|
||||
"ofType": null
|
||||
},
|
||||
"defaultValue": null
|
||||
}
|
||||
],
|
||||
"type": {
|
||||
"kind": "OBJECT",
|
||||
"name": "IterationConnection",
|
||||
"ofType": null
|
||||
},
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "jiraImportStatus",
|
||||
"description": "Status of Jira import background job of the project",
|
||||
|
|
|
@ -9,6 +9,11 @@ You can only restore a backup to **exactly the same version and type (CE/EE)**
|
|||
of GitLab on which it was created. The best way to migrate your repositories
|
||||
from one server to another is through backup restore.
|
||||
|
||||
CAUTION: **Warning:**
|
||||
GitLab will not backup items that are not stored on the
|
||||
filesystem. If using [object storage](../administration/object_storage.md),
|
||||
remember to enable backups with your object storage provider if desired.
|
||||
|
||||
## Requirements
|
||||
|
||||
In order to be able to backup and restore, you need two essential tools
|
||||
|
|
|
@ -271,6 +271,7 @@ The following issue metadata will be copied to the epic:
|
|||
- Upvotes/downvotes.
|
||||
- Participants.
|
||||
- Group labels that the issue already has.
|
||||
- Parent epic. **(ULTIMATE)**
|
||||
|
||||
## Manage multi-level child epics **(ULTIMATE)**
|
||||
|
||||
|
|
|
@ -10,6 +10,23 @@ module API
|
|||
requires :ref, type: String, desc: 'The name of branch, tag or commit'
|
||||
end
|
||||
|
||||
params :create_file_params do
|
||||
optional :files, type: Array, desc: 'An array of files' do
|
||||
requires :file_path, type: String, file_path: true, allow_blank: false, desc: 'The path of a snippet file'
|
||||
requires :content, type: String, allow_blank: false, desc: 'The content of a snippet file'
|
||||
end
|
||||
|
||||
optional :content, type: String, allow_blank: false, desc: 'The content of a snippet'
|
||||
|
||||
given :content do
|
||||
requires :file_name, type: String, desc: 'The name of a snippet file'
|
||||
end
|
||||
|
||||
mutually_exclusive :files, :content
|
||||
|
||||
exactly_one_of :files, :content
|
||||
end
|
||||
|
||||
def content_for(snippet)
|
||||
if snippet.empty_repo?
|
||||
env['api.format'] = :txt
|
||||
|
@ -35,5 +52,12 @@ module API
|
|||
send_git_blob(repo, blob)
|
||||
end
|
||||
end
|
||||
|
||||
def process_file_args(args)
|
||||
args[:snippet_actions] = args.delete(:files)&.map do |file|
|
||||
file[:action] = :create
|
||||
file.symbolize_keys
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -66,18 +66,23 @@ module API
|
|||
end
|
||||
params do
|
||||
requires :title, type: String, allow_blank: false, desc: 'The title of a snippet'
|
||||
requires :file_name, type: String, desc: 'The name of a snippet file'
|
||||
requires :content, type: String, allow_blank: false, desc: 'The content of a snippet'
|
||||
optional :description, type: String, desc: 'The description of a snippet'
|
||||
optional :visibility, type: String,
|
||||
values: Gitlab::VisibilityLevel.string_values,
|
||||
default: 'internal',
|
||||
desc: 'The visibility of the snippet'
|
||||
use :create_file_params
|
||||
end
|
||||
post do
|
||||
authorize! :create_snippet
|
||||
|
||||
attrs = declared_params(include_missing: false).merge(request: request, api: true)
|
||||
attrs = declared_params(include_missing: false).tap do |create_args|
|
||||
create_args[:request] = request
|
||||
create_args[:api] = true
|
||||
|
||||
process_file_args(create_args)
|
||||
end
|
||||
|
||||
service_response = ::Snippets::CreateService.new(nil, current_user, attrs).execute
|
||||
snippet = service_response.payload[:snippet]
|
||||
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# This cop checks for use of GraphQL::Types::JSON types in GraphQL fields
|
||||
# and arguments.
|
||||
#
|
||||
# @example
|
||||
#
|
||||
# # bad
|
||||
# class AwfulClass
|
||||
# field :some_field, GraphQL::Types::JSON
|
||||
# end
|
||||
#
|
||||
# # good
|
||||
# class GreatClass
|
||||
# field :some_field, GraphQL::STRING_TYPE
|
||||
# end
|
||||
|
||||
module RuboCop
|
||||
module Cop
|
||||
module Graphql
|
||||
class JSONType < RuboCop::Cop::Cop
|
||||
MSG = 'Avoid using GraphQL::Types::JSON. See: ' \
|
||||
'https://docs.gitlab.com/ee/development/api_graphql_styleguide.html#json'.freeze
|
||||
|
||||
def_node_matcher :has_json_type?, <<~PATTERN
|
||||
(send nil? {:field :argument}
|
||||
(sym _)
|
||||
(const
|
||||
(const
|
||||
(const nil? :GraphQL) :Types) :JSON)
|
||||
(...)?)
|
||||
PATTERN
|
||||
|
||||
def on_send(node)
|
||||
add_offense(node, location: :expression) if has_json_type?(node)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -217,7 +217,7 @@ RSpec.describe 'GitLab Markdown', :aggregate_failures do
|
|||
|
||||
it_behaves_like 'all pipelines'
|
||||
|
||||
it 'includes custom filters', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/233077' do
|
||||
it 'includes custom filters' do
|
||||
aggregate_failures 'UploadLinkFilter' do
|
||||
expect(doc).to parse_upload_links
|
||||
end
|
||||
|
@ -282,7 +282,7 @@ RSpec.describe 'GitLab Markdown', :aggregate_failures do
|
|||
|
||||
it_behaves_like 'all pipelines'
|
||||
|
||||
it 'includes custom filters', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/233077' do
|
||||
it 'includes custom filters' do
|
||||
aggregate_failures 'UploadLinkFilter' do
|
||||
expect(doc).to parse_upload_links
|
||||
end
|
||||
|
|
|
@ -229,13 +229,15 @@ RSpec.describe API::Snippets do
|
|||
let(:base_params) do
|
||||
{
|
||||
title: 'Test Title',
|
||||
file_name: 'test.rb',
|
||||
description: 'test description',
|
||||
content: 'puts "hello world"',
|
||||
visibility: 'public'
|
||||
}
|
||||
end
|
||||
let(:params) { base_params.merge(extra_params) }
|
||||
let(:file_path) { 'file_1.rb' }
|
||||
let(:file_content) { 'puts "hello world"' }
|
||||
|
||||
let(:params) { base_params.merge(file_params, extra_params) }
|
||||
let(:file_params) { { files: [{ file_path: file_path, content: file_content }] } }
|
||||
let(:extra_params) { {} }
|
||||
|
||||
subject { post api("/snippets/", user), params: params }
|
||||
|
@ -251,7 +253,7 @@ RSpec.describe API::Snippets do
|
|||
expect(response).to have_gitlab_http_status(:created)
|
||||
expect(json_response['title']).to eq(params[:title])
|
||||
expect(json_response['description']).to eq(params[:description])
|
||||
expect(json_response['file_name']).to eq(params[:file_name])
|
||||
expect(json_response['file_name']).to eq(file_path)
|
||||
expect(json_response['files']).to eq(snippet.blobs.map { |blob| snippet_blob_file(blob) })
|
||||
expect(json_response['visibility']).to eq(params[:visibility])
|
||||
end
|
||||
|
@ -265,9 +267,90 @@ RSpec.describe API::Snippets do
|
|||
it 'commit the files to the repository' do
|
||||
subject
|
||||
|
||||
blob = snippet.repository.blob_at('master', params[:file_name])
|
||||
blob = snippet.repository.blob_at('master', file_path)
|
||||
|
||||
expect(blob.data).to eq params[:content]
|
||||
expect(blob.data).to eq file_content
|
||||
end
|
||||
end
|
||||
|
||||
context 'with files parameter' do
|
||||
using RSpec::Parameterized::TableSyntax
|
||||
|
||||
where(:path, :content, :status, :error) do
|
||||
'.gitattributes' | 'file content' | :created | nil
|
||||
'valid/path/file.rb' | 'file content' | :created | nil
|
||||
|
||||
'.gitattributes' | nil | :bad_request | 'files[0][content] is empty'
|
||||
'.gitattributes' | '' | :bad_request | 'files[0][content] is empty'
|
||||
|
||||
'' | 'file content' | :bad_request | 'files[0][file_path] is empty'
|
||||
nil | 'file content' | :bad_request | 'files[0][file_path] should be a valid file path, files[0][file_path] is empty'
|
||||
'../../etc/passwd' | 'file content' | :bad_request | 'files[0][file_path] should be a valid file path'
|
||||
end
|
||||
|
||||
with_them do
|
||||
let(:file_path) { path }
|
||||
let(:file_content) { content }
|
||||
|
||||
before do
|
||||
subject
|
||||
end
|
||||
|
||||
it 'responds correctly' do
|
||||
expect(response).to have_gitlab_http_status(status)
|
||||
expect(json_response['error']).to eq(error)
|
||||
end
|
||||
end
|
||||
|
||||
it 'returns 400 if both files and content are provided' do
|
||||
params[:file_name] = 'foo.rb'
|
||||
params[:content] = 'bar'
|
||||
|
||||
subject
|
||||
|
||||
expect(response).to have_gitlab_http_status(:bad_request)
|
||||
expect(json_response['error']).to eq 'files, content are mutually exclusive'
|
||||
end
|
||||
|
||||
it 'returns 400 when neither files or content are provided' do
|
||||
params.delete(:files)
|
||||
|
||||
subject
|
||||
|
||||
expect(response).to have_gitlab_http_status(:bad_request)
|
||||
expect(json_response['error']).to eq 'files, content are missing, exactly one parameter must be provided'
|
||||
end
|
||||
|
||||
context 'with multiple files' do
|
||||
let(:file_params) do
|
||||
{
|
||||
files: [
|
||||
{ file_path: 'file_1.rb', content: 'puts "hello world"' },
|
||||
{ file_path: 'file_2.rb', content: 'puts "hello world 2"' }
|
||||
]
|
||||
}
|
||||
end
|
||||
|
||||
it_behaves_like 'snippet creation'
|
||||
end
|
||||
end
|
||||
|
||||
context 'without files parameter' do
|
||||
let(:file_params) { { file_name: 'testing.rb', content: 'snippet content' } }
|
||||
|
||||
it 'allows file_name and content parameters' do
|
||||
subject
|
||||
|
||||
expect(response).to have_gitlab_http_status(:created)
|
||||
end
|
||||
|
||||
it 'returns 400 if file_name and content are not both provided' do
|
||||
params.delete(:file_name)
|
||||
|
||||
subject
|
||||
|
||||
expect(response).to have_gitlab_http_status(:bad_request)
|
||||
expect(json_response['error']).to eq 'file_name is missing'
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -305,15 +388,6 @@ RSpec.describe API::Snippets do
|
|||
expect(response).to have_gitlab_http_status(:bad_request)
|
||||
end
|
||||
|
||||
it 'returns 400 if content is blank' do
|
||||
params[:content] = ''
|
||||
|
||||
subject
|
||||
|
||||
expect(response).to have_gitlab_http_status(:bad_request)
|
||||
expect(json_response['error']).to eq 'content is empty'
|
||||
end
|
||||
|
||||
it 'returns 400 if title is blank' do
|
||||
params[:title] = ''
|
||||
|
||||
|
|
|
@ -0,0 +1,79 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'fast_spec_helper'
|
||||
require 'rubocop'
|
||||
require_relative '../../../../rubocop/cop/graphql/json_type'
|
||||
|
||||
RSpec.describe RuboCop::Cop::Graphql::JSONType, type: :rubocop do
|
||||
include CopHelper
|
||||
|
||||
subject(:cop) { described_class.new }
|
||||
|
||||
context 'fields' do
|
||||
it 'adds an offense when GraphQL::Types::JSON is used' do
|
||||
inspect_source(<<~RUBY.strip)
|
||||
class MyType
|
||||
field :some_field, GraphQL::Types::JSON
|
||||
end
|
||||
RUBY
|
||||
|
||||
expect(cop.offenses.size).to eq(1)
|
||||
end
|
||||
|
||||
it 'adds an offense when GraphQL::Types::JSON is used with other keywords' do
|
||||
inspect_source(<<~RUBY.strip)
|
||||
class MyType
|
||||
field :some_field, GraphQL::Types::JSON, null: true, description: 'My description'
|
||||
end
|
||||
RUBY
|
||||
|
||||
expect(cop.offenses.size).to eq(1)
|
||||
end
|
||||
|
||||
it 'does not add an offense for other types' do
|
||||
expect_no_offenses(<<~RUBY.strip)
|
||||
class MyType
|
||||
field :some_field, GraphQL::STRING_TYPE
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
end
|
||||
|
||||
context 'arguments' do
|
||||
it 'adds an offense when GraphQL::Types::JSON is used' do
|
||||
inspect_source(<<~RUBY.strip)
|
||||
class MyType
|
||||
argument :some_arg, GraphQL::Types::JSON
|
||||
end
|
||||
RUBY
|
||||
|
||||
expect(cop.offenses.size).to eq(1)
|
||||
end
|
||||
|
||||
it 'adds an offense when GraphQL::Types::JSON is used with other keywords' do
|
||||
inspect_source(<<~RUBY.strip)
|
||||
class MyType
|
||||
argument :some_arg, GraphQL::Types::JSON, null: true, description: 'My description'
|
||||
end
|
||||
RUBY
|
||||
|
||||
expect(cop.offenses.size).to eq(1)
|
||||
end
|
||||
|
||||
it 'does not add an offense for other types' do
|
||||
expect_no_offenses(<<~RUBY.strip)
|
||||
class MyType
|
||||
argument :some_arg, GraphQL::STRING_TYPE
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
end
|
||||
|
||||
it 'does not add an offense for uses outside of field or argument' do
|
||||
expect_no_offenses(<<~RUBY.strip)
|
||||
class MyType
|
||||
foo :some_field, GraphQL::Types::JSON
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue