Commit 5bfb8d1f authored by GitLab Bot's avatar GitLab Bot

Add latest changes from gitlab-org/gitlab@master

parent aaf59610
......@@ -204,8 +204,25 @@ gitlab:setup:
rspec:coverage:
extends:
- .rails-job-base
- .rails:rules:ee-and-foss
- .rails:rules:ee-only
stage: post-test
# We cannot use needs since it would mean needing 84 jobs (since most are parallelized)
# so we use `dependencies` here.
dependencies:
- setup-test-env
- rspec migration pg9
- rspec unit pg9
- rspec integration pg9
- rspec system pg9
- rspec-ee migration pg9
- rspec-ee unit pg9
- rspec-ee integration pg9
- rspec-ee system pg9
- rspec-ee unit pg9 geo
- rspec-ee integration pg9 geo
- rspec-ee system pg9 geo
- memory-static
- memory-on-boot
variables:
SETUP_DB: "false"
cache:
......
......@@ -291,6 +291,8 @@
###############
.pages:rules:
rules:
- <<: *if-not-ee
when: never
- <<: *if-dot-com-gitlab-org-master
changes: *code-backstage-qa-patterns
when: on_success
......
......@@ -21,7 +21,7 @@ Set the title to: `Description of the original issue`
- [ ] Create a merge request targeting `master` on `gitlab.com/gitlab-org/security` and use the [Security Release merge request template].
- [ ] Follow the same [code review process]: Assign to a reviewer, then to a maintainer.
After your merge request has being approved according to our [approval guidelines], you're ready to prepare the backports
After your merge request has been approved according to our [approval guidelines], you're ready to prepare the backports
## Backports
......
......@@ -87,7 +87,7 @@ gem 'grape-entity', '~> 0.7.1'
gem 'rack-cors', '~> 1.0.6', require: 'rack/cors'
# GraphQL API
gem 'graphql', '~> 1.9.19'
gem 'graphql', '~> 1.10.5'
# NOTE: graphiql-rails v1.5+ doesn't work: https://gitlab.com/gitlab-org/gitlab/issues/31771
# TODO: remove app/views/graphiql/rails/editors/show.html.erb when https://github.com/rmosolgo/graphiql-rails/pull/71 is released:
# https://gitlab.com/gitlab-org/gitlab/issues/31747
......
......@@ -456,7 +456,7 @@ GEM
graphiql-rails (1.4.10)
railties
sprockets-rails
graphql (1.9.19)
graphql (1.10.5)
graphql-docs (1.6.0)
commonmarker (~> 0.16)
escape_utils (~> 1.2)
......@@ -1252,7 +1252,7 @@ DEPENDENCIES
grape-path-helpers (~> 1.2)
grape_logging (~> 1.7)
graphiql-rails (~> 1.4.10)
graphql (~> 1.9.19)
graphql (~> 1.10.5)
graphql-docs (~> 1.6.0)
grpc (~> 1.24.0)
gssapi
......
......@@ -13,11 +13,18 @@ class AuditEvent < ApplicationRecord
scope :by_entity_type, -> (entity_type) { where(entity_type: entity_type) }
scope :by_entity_id, -> (entity_id) { where(entity_id: entity_id) }
scope :order_by_id_desc, -> { order(id: :desc) }
scope :order_by_id_asc, -> { order(id: :asc) }
after_initialize :initialize_details
def self.order_by(method)
case method.to_s
when 'created_asc'
order(id: :asc)
else
order(id: :desc)
end
end
def initialize_details
self.details = {} if details.nil?
end
......
---
title: Index issues on sent_notifications table
merge_request: 27034
author:
type: performance
---
title: Move feature flag list into process cache
merge_request: 27511
author:
type: performance
......@@ -14,14 +14,18 @@ class AddStatusToDeployments < ActiveRecord::Migration[4.2]
# Ideally, `status` column should not have default value because it should be leveraged by state machine (i.e. application level).
# However, we have to use the default value for avoiding `NOT NULL` violation during the transition period.
# The default value should be removed in the future release.
# rubocop:disable Migration/AddColumnWithDefault
# rubocop:disable Migration/UpdateLargeTable
def up
add_column_with_default(:deployments, # rubocop:disable Migration/AddColumnWithDefault
add_column_with_default(:deployments,
:status,
:integer,
limit: 2,
default: DEPLOYMENT_STATUS_SUCCESS,
allow_null: false)
end
# rubocop:enable Migration/AddColumnWithDefault
# rubocop:enable Migration/UpdateLargeTable
def down
remove_column(:deployments, :status)
......
......@@ -7,10 +7,12 @@ class AddMergeTrainEnabledToCiCdSettings < ActiveRecord::Migration[5.1]
disable_ddl_transaction!
# rubocop:disable Migration/AddColumnWithDefault
# rubocop:disable Migration/UpdateLargeTable
def up
add_column_with_default :project_ci_cd_settings, :merge_trains_enabled, :boolean, default: false, allow_null: false
end
# rubocop:enable Migration/AddColumnWithDefault
# rubocop:enable Migration/UpdateLargeTable
def down
......
......@@ -7,9 +7,13 @@ class AddVariableTypeToCiPipelineVariables < ActiveRecord::Migration[5.0]
DOWNTIME = false
ENV_VAR_VARIABLE_TYPE = 1
# rubocop:disable Migration/AddColumnWithDefault
# rubocop:disable Migration/UpdateLargeTable
def up
add_column_with_default(:ci_pipeline_variables, :variable_type, :smallint, default: ENV_VAR_VARIABLE_TYPE) # rubocop:disable Migration/AddColumnWithDefault
add_column_with_default(:ci_pipeline_variables, :variable_type, :smallint, default: ENV_VAR_VARIABLE_TYPE)
end
# rubocop:enable Migration/AddColumnWithDefault
# rubocop:enable Migration/UpdateLargeTable
def down
remove_column(:ci_pipeline_variables, :variable_type)
......
......@@ -7,9 +7,13 @@ class AddDeploymentEventsToServices < ActiveRecord::Migration[5.0]
disable_ddl_transaction!
# rubocop:disable Migration/AddColumnWithDefault
# rubocop:disable Migration/UpdateLargeTable
def up
add_column_with_default(:services, :deployment_events, :boolean, default: false, allow_null: false)
end
# rubocop:enable Migration/AddColumnWithDefault
# rubocop:enable Migration/UpdateLargeTable
def down
remove_column(:services, :deployment_events)
......
......@@ -7,9 +7,13 @@ class AddCommentActionsToServices < ActiveRecord::Migration[5.2]
disable_ddl_transaction!
# rubocop:disable Migration/AddColumnWithDefault
# rubocop:disable Migration/UpdateLargeTable
def up
add_column_with_default(:services, :comment_on_event_enabled, :boolean, default: true)
end
# rubocop:enable Migration/AddColumnWithDefault
# rubocop:enable Migration/UpdateLargeTable
def down
remove_column(:services, :comment_on_event_enabled)
......
......@@ -7,9 +7,13 @@ class AddInstanceToServices < ActiveRecord::Migration[6.0]
disable_ddl_transaction!
# rubocop:disable Migration/AddColumnWithDefault
# rubocop:disable Migration/UpdateLargeTable
def up
add_column_with_default(:services, :instance, :boolean, default: false)
end
# rubocop:enable Migration/AddColumnWithDefault
# rubocop:enable Migration/UpdateLargeTable
def down
remove_column(:services, :instance)
......
......@@ -7,6 +7,7 @@ class ReaddTemplateColumnToServices < ActiveRecord::Migration[6.0]
disable_ddl_transaction!
# rubocop:disable Migration/UpdateLargeTable
def up
return if column_exists? :services, :template
......@@ -16,6 +17,7 @@ class ReaddTemplateColumnToServices < ActiveRecord::Migration[6.0]
# of `template`, we would look for entries with `project_id IS NULL`.
add_column_with_default :services, :template, :boolean, default: false, allow_null: true
end
# rubocop:enable Migration/UpdateLargeTable
def down
# NOP since the column is expected to exist
......
# frozen_string_literal: true
class AddIndexOnNoteableTypeAndNoteableIdToSentNotifications < ActiveRecord::Migration[6.0]
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
INDEX_NAME = 'index_sent_notifications_on_noteable_type_noteable_id'
disable_ddl_transaction!
def up
add_concurrent_index :sent_notifications,
[:noteable_id],
name: INDEX_NAME,
where: "noteable_type = 'Issue'"
end
def down
remove_concurrent_index_by_name :sent_notifications, INDEX_NAME
end
end
......@@ -3919,6 +3919,7 @@ ActiveRecord::Schema.define(version: 2020_03_13_123934) do
t.string "note_type"
t.text "position"
t.string "in_reply_to_discussion_id"
t.index ["noteable_id"], name: "index_sent_notifications_on_noteable_type_noteable_id", where: "((noteable_type)::text = 'Issue'::text)"
t.index ["reply_key"], name: "index_sent_notifications_on_reply_key", unique: true
end
......
This diff is collapsed.
......@@ -11,6 +11,12 @@ to access them as we do in Rails views), local variables are fine.
Always use an [Entity] to present the endpoint's payload.
## Documentation
API endpoints must come with [documentation](documentation/styleguide.md#api), unless it is internal or behind a feature flag.
The docs should be in the same merge request, or, if strictly necessary,
in a follow-up with the same milestone as the original merge request.
## Methods and parameters description
Every method must be described using the [Grape DSL](https://github.com/ruby-grape/grape#describing-methods)
......
......@@ -7,9 +7,11 @@ type: reference, howto
GitLab can check your application for security vulnerabilities that may lead to unauthorized access,
data leaks, denial of services, and more. GitLab reports vulnerabilities in the merge request so you
can fix them before merging. The [Security Dashboard](security_dashboard/index.md) provides a
high-level view of vulnerabilities detected in your projects, pipeline, and groups. With the
information provided, you can immediately begin risk analysis and remediation.
high-level view of vulnerabilities detected in your projects, pipeline, and groups. The [Threat Monitoring](threat_monitoring/index.md)
page provides runtime security metrics for application environments. With the information provided,
you can immediately begin risk analysis and remediation.
<i class="fa fa-youtube-play youtube" aria-hidden="true"></i>
For an overview of application security with GitLab, see
[Security Deep Dive](https://www.youtube.com/watch?v=k4vEJnGYy84).
......
......@@ -13,7 +13,7 @@ connected to the internet, in what is sometimes known as an offline,
limited connectivity, Local Area Network (LAN), Intranet, or "air-gap"
environment.
In this situation, the GitLab instance can be one, or more, servers and services running in a network that can talk to one another, but have zero, or perhaps very restricted access to the internet. Assume anything within the GitLab instance and supporting infrastrusture (private maven repository for example) can be accessed via local network connection. Assume any files from the internet must come in via physical media (USB drive, hard drive).
In this situation, the GitLab instance can be one, or more, servers and services running in a network that can talk to one another, but have zero, or perhaps very restricted access to the internet. Assume anything within the GitLab instance and supporting infrastructure (private Maven repository for example) can be accessed via local network connection. Assume any files from the internet must come in via physical media (USB drive, hard drive).
GitLab scanners generally will connect to the internet to download the
latest sets of signatures, rules, and patches. A few extra steps are necessary
......
---
type: reference, howto
---
# Threat Monitoring **(ULTIMATE)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/14707) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 12.9.
The **Threat Monitoring** page provides metrics for the GitLab
application runtime security features. You can access these metrics by
navigating to your project's **Security & Compliance > Threat Monitoring** page.
GitLab supports statistics for the following security features:
- [Web Application Firewall](../../clusters/applications.md#web-application-firewall-modsecurity)
## Web Application Firewall
The Web Application Firewall section provides metrics for the NGINX
Ingress controller and ModSecurity firewall. This section has the
following prerequisites:
- Project has to have at least one [environment](../../../ci/environments.md).
- [Web Application Firewall](../../clusters/applications.md#web-application-firewall-modsecurity) has to be enabled.
- [Elastic Stack](../../clusters/applications.md#web-application-firewall-modsecurity) has to be installed.
If you are using custom Helm values for the Elastic Stack you have to
configure Filebeat similarly to the [vendored values](https://gitlab.com/gitlab-org/gitlab/-/blob/f610a080b1ccc106270f588a50cb3c07c08bdd5a/vendor/elastic_stack/values.yaml).
The **Web Application Firewall** section displays the following information
about your Ingress traffic:
- The total amount of requests to your application
- The proportion of traffic that is considered anomalous according to
the configured rules
- The request breakdown graph for the selected time interval
If a significant percentage of traffic is anomalous, you should
investigate it for potential threats by
[examining the application logs](../../clusters/applications.md#web-application-firewall-modsecurity).
This diff is collapsed.
......@@ -93,6 +93,11 @@ To edit a page, simply click on the **Edit** button. From there on, you can
change its content. When done, click **Save changes** for the changes to take
effect.
### Adding a table of contents
To generate a table of contents from the headings in a Wiki page, use the `[[_TOC_]]` tag.
For an example, see [Table of contents](../../markdown.md#table-of-contents).
## Deleting a wiki page
NOTE: **Note:**
......
......@@ -38,7 +38,7 @@ class Feature
begin
# We saw on GitLab.com, this database request was called 2300
# times/s. Let's cache it for a minute to avoid that load.
Gitlab::ThreadMemoryCache.cache_backend.fetch('flipper:persisted_names', expires_in: 1.minute) do
Gitlab::ProcessMemoryCache.cache_backend.fetch('flipper:persisted_names', expires_in: 1.minute) do
FlipperFeature.feature_names
end
end
......
......@@ -21,7 +21,7 @@ module Gitlab
process_commits do |commit|
validate_once(commit) do
commit.raw_deltas.each do |diff|
file_paths << (diff.new_path || diff.old_path)
file_paths.concat([diff.new_path, diff.old_path].compact)
validate_diff(diff)
end
......
......@@ -8,11 +8,6 @@ module RuboCop
class AddColumn < RuboCop::Cop::Cop
include MigrationHelpers
WHITELISTED_TABLES = %i[
application_settings
plan_limits
].freeze
MSG = '`add_column` with a default value requires downtime, ' \
'use `add_column_with_default` instead'.freeze
......
......@@ -10,38 +10,6 @@ module RuboCop
class AddColumnWithDefault < RuboCop::Cop::Cop
include MigrationHelpers
# Tables >= 10 GB on GitLab.com as of 02/2020
BLACKLISTED_TABLES = %i[
audit_events
ci_build_trace_sections
ci_builds
ci_builds_metadata
ci_job_artifacts
ci_pipeline_variables
ci_pipelines
ci_stages
deployments
events
issues
merge_request_diff_commits
merge_request_diff_files
merge_request_diffs
merge_request_metrics
merge_requests
note_diff_files
notes
project_authorizations
projects
push_event_payloads
resource_label_events
sent_notifications
system_note_metadata
taggings
todos
users
web_hook_logs
].freeze
MSG = '`add_column_with_default` without `allow_null: true` may cause prolonged lock situations and downtime, ' \
'see https://gitlab.com/gitlab-org/gitlab/issues/38060'.freeze
......
......@@ -23,10 +23,6 @@ module RuboCop
NULL_OFFENSE = 'Boolean columns on the `%s` table should disallow nulls.'.freeze
DEFAULT_AND_NULL_OFFENSE = 'Boolean columns on the `%s` table should have a default and should disallow nulls. You may wish to use `add_column_with_default`.'.freeze
SMALL_TABLES = %i[
application_settings
].freeze
def_node_matcher :add_column?, <<~PATTERN
(send nil? :add_column $...)
PATTERN
......@@ -41,7 +37,7 @@ module RuboCop
table, _, type = matched.to_a.take(3).map(&:children).map(&:first)
opts = matched[3]
return unless SMALL_TABLES.include?(table) && type == :boolean
return unless WHITELISTED_TABLES.include?(table) && type == :boolean
no_default = no_default?(opts)
nulls_allowed = nulls_allowed?(opts)
......
......@@ -19,26 +19,6 @@ module RuboCop
'complete, and should be avoided unless absolutely ' \
'necessary'.freeze
LARGE_TABLES = %i[
ci_build_trace_sections
ci_builds
ci_job_artifacts
ci_pipelines
ci_stages
events
issues
merge_request_diff_commits
merge_request_diff_files
merge_request_diffs
merge_requests
namespaces
notes
projects
project_ci_cd_settings
routes
users
].freeze
BATCH_UPDATE_METHODS = %w[
:add_column_with_default
:change_column_type_concurrently
......@@ -59,7 +39,7 @@ module RuboCop
update_method = matches.first
table = matches.last.to_a.first
return unless LARGE_TABLES.include?(table)
return unless BLACKLISTED_TABLES.include?(table)
add_offense(node, location: :expression, message: format(MSG, update_method, table))
end
......
module RuboCop
# Module containing helper methods for writing migration cops.
module MigrationHelpers
WHITELISTED_TABLES = %i[
application_settings
plan_limits
].freeze
# Blacklisted table due to:
# - size in GB (>= 10 GB on GitLab.com as of 02/2020)
# - number of records
BLACKLISTED_TABLES = %i[
audit_events
ci_build_trace_sections
ci_builds
ci_builds_metadata
ci_job_artifacts
ci_pipeline_variables
ci_pipelines
ci_stages
deployments
events
issues
merge_request_diff_commits
merge_request_diff_files
merge_request_diffs
merge_request_metrics
merge_requests
namespaces
note_diff_files
notes
project_authorizations
projects
project_ci_cd_settings
push_event_payloads
resource_label_events
routes
sent_notifications
services
system_note_metadata
taggings
todos
users
web_hook_logs
].freeze
# Returns true if the given node originated from the db/migrate directory.
def in_migration?(node)
dirname(node).end_with?('db/migrate', 'db/geo/migrate') || in_post_deployment_migration?(node)
......
......@@ -9,7 +9,7 @@ describe 'Gitlab::Graphql::Authorization' do
let(:permission_single) { :foo }
let(:permission_collection) { [:foo, :bar] }
let(:test_object) { double(name: 'My name') }
let(:query_string) { '{ item() { name } }' }
let(:query_string) { '{ item { name } }' }
let(:result) { execute_query(query_type)['data'] }
subject { result['item'] }
......@@ -177,7 +177,7 @@ describe 'Gitlab::Graphql::Authorization' do
end
describe 'type authorizations when applied to a relay connection' do
let(:query_string) { '{ item() { edges { node { name } } } }' }
let(:query_string) { '{ item { edges { node { name } } } }' }
let(:second_test_object) { double(name: 'Second thing') }
let(:type) do
......
......@@ -9,7 +9,7 @@ describe 'Graphql Field feature flags' do
let(:feature_flag) { 'test_feature' }
let(:test_object) { double(name: 'My name') }
let(:query_string) { '{ item() { name } }' }
let(:query_string) { '{ item { name } }' }
let(:result) { execute_query(query_type)['data'] }
subject { result }
......
......@@ -27,11 +27,11 @@ describe GitlabSchema do
end
it 'has the base mutation' do
expect(described_class.mutation).to eq(::Types::MutationType.to_graphql)
expect(described_class.mutation).to eq(::Types::MutationType)
end
it 'has the base query' do
expect(described_class.query).to eq(::Types::QueryType.to_graphql)
expect(described_class.query).to eq(::Types::QueryType)
end
it 'paginates active record relations using `Connections::Keyset::Connection`' do
......
......@@ -5,7 +5,7 @@ require 'spec_helper'
describe GitlabSchema.types['AwardEmoji'] do
it { expect(described_class.graphql_name).to eq('AwardEmoji') }
it { is_expected.to require_graphql_authorizations(:read_emoji) }
it { expect(described_class).to require_graphql_authorizations(:read_emoji) }
it { expect(described_class).to have_graphql_fields(:description, :unicode_version, :emoji, :name, :unicode, :user) }
end
......@@ -10,6 +10,6 @@ describe GitlabSchema.types['Board'] do
it 'has specific fields' do
expected_fields = %w[id name]
is_expected.to include_graphql_fields(*expected_fields)
expect(described_class).to include_graphql_fields(*expected_fields)
end
end
......@@ -5,7 +5,7 @@ require 'spec_helper'
describe GitlabSchema.types['DiffRefs'] do
it { expect(described_class.graphql_name).to eq('DiffRefs') }
it { is_expected.to have_graphql_fields(:head_sha, :base_sha, :start_sha).only }
it { expect(described_class).to have_graphql_fields(:head_sha, :base_sha, :start_sha).only }
it { expect(described_class.fields['headSha'].type).to be_non_null }
it { expect(described_class.fields['baseSha'].type).not_to be_non_null }
......
......@@ -10,8 +10,8 @@ describe GitlabSchema.types['Environment'] do
name id
]
is_expected.to have_graphql_fields(*expected_fields)
expect(described_class).to have_graphql_fields(*expected_fields)
end
it { is_expected.to require_graphql_authorizations(:read_environment) }
it { expect(described_class).to require_graphql_authorizations(:read_environment) }
end
......@@ -37,6 +37,6 @@ describe GitlabSchema.types['SentryDetailedError'] do
tags
]
is_expected.to have_graphql_fields(*expected_fields)
expect(described_class).to have_graphql_fields(*expected_fields)
end
end
......@@ -15,7 +15,7 @@ describe GitlabSchema.types['SentryErrorCollection'] do
error_stack_trace
]
is_expected.to have_graphql_fields(*expected_fields)
expect(described_class).to have_graphql_fields(*expected_fields)
end
describe 'errors field' do
......
......@@ -14,6 +14,6 @@ describe GitlabSchema.types['SentryErrorStackTraceEntry'] do
trace_context
]
is_expected.to have_graphql_fields(*expected_fields)
expect(described_class).to have_graphql_fields(*expected_fields)
end
end
......@@ -14,6 +14,6 @@ describe GitlabSchema.types['SentryErrorStackTrace'] do
stack_trace_entries
]
is_expected.to have_graphql_fields(*expected_fields)
expect(described_class).to have_graphql_fields(*expected_fields)
end
end
......@@ -26,6 +26,6 @@ describe GitlabSchema.types['SentryError'] do
frequency
]
is_expected.to have_graphql_fields(*expected_fields)
expect(described_class).to have_graphql_fields(*expected_fields)
end
end
......@@ -18,5 +18,5 @@ describe GitlabSchema.types['GrafanaIntegration'] do
it { expect(described_class).to require_graphql_authorizations(:admin_operations) }
it { is_expected.to have_graphql_fields(*expected_fields) }
it { expect(described_class).to have_graphql_fields(*expected_fields) }
end
......@@ -19,7 +19,7 @@ describe GitlabSchema.types['Group'] do
mentions_disabled parent boards
]
is_expected.to include_graphql_fields(*expected_fields)
expect(described_class).to include_graphql_fields(*expected_fields)
end
describe 'boards field' do
......
......@@ -9,7 +9,7 @@ describe GitlabSchema.types['Issue'] do
it { expect(described_class).to require_graphql_authorizations(:read_issue) }
it { expect(described_class.interfaces).to include(Types::Notes::NoteableType.to_graphql) }
it { expect(described_class.interfaces).to include(Types::Notes::NoteableType) }
it 'has specific fields' do
fields = %i[iid title description state reference author assignees participants labels milestone due_date
......
......@@ -5,8 +5,8 @@ describe GitlabSchema.types['Label'] do
it 'has the correct fields' do
expected_fields = [:id, :description, :description_html, :title, :color, :text_color]
is_expected.to have_graphql_fields(*expected_fields)
expect(described_class).to have_graphql_fields(*expected_fields)
end
it { is_expected.to require_graphql_authorizations(:read_label) }
it { expect(described_class).to require_graphql_authorizations(:read_label) }
end
......@@ -7,7 +7,7 @@ describe GitlabSchema.types['MergeRequest'] do
it { expect(described_class).to require_graphql_authorizations(:read_merge_request) }
it { expect(described_class.interfaces).to include(Types::Notes::NoteableType.to_graphql) }
it { expect(described_class.interfaces).to include(Types::Notes::NoteableType) }
it 'has the expected fields' do
expected_fields = %w[
......@@ -25,6 +25,6 @@ describe GitlabSchema.types['MergeRequest'] do
total_time_spent reference
]
is_expected.to have_graphql_fields(*expected_fields)
expect(described_class).to have_graphql_fields(*expected_fields)
end
end
......@@ -4,5 +4,5 @@ require 'spec_helper'
describe GitlabSchema.types['Metadata'] do
it { expect(described_class.graphql_name).to eq('Metadata') }
it { is_expected.to require_graphql_authorizations(:read_instance_metadata) }
it { expect(described_class).to require_graphql_authorizations(:read_instance_metadata) }
end
......@@ -11,8 +11,8 @@ describe GitlabSchema.types['Namespace'] do
lfs_enabled request_access_enabled projects root_storage_statistics
]
is_expected.to have_graphql_fields(*expected_fields)
expect(described_class).to have_graphql_fields(*expected_fields)
end
it { is_expected.to require_graphql_authorizations(:read_namespace) }
it { expect(described_class).to require_graphql_authorizations(:read_namespace) }
end
......@@ -7,6 +7,6 @@ describe GitlabSchema.types['DiffPosition'] do
:new_path, :position_type, :old_line, :new_line, :x, :y,
:width, :height]
is_expected.to have_graphql_fields(*expected_fields)
expect(described_class).to have_graphql_fields(*expected_fields)
end
end
......@@ -2,7 +2,7 @@
require 'spec_helper'
describe GitlabSchema.types['Discussion'] do
it { is_expected.to have_graphql_fields(:id, :created_at, :notes, :reply_id) }
it { expect(described_class).to have_graphql_fields(:id, :created_at, :notes, :reply_id) }
it { is_expected.to require_graphql_authorizations(:read_note) }
it { expect(described_class).to require_graphql_authorizations(:read_note) }
end
......@@ -7,9 +7,9 @@ describe GitlabSchema.types['Note'] do
:updated_at, :discussion, :resolvable, :position, :user_permissions,
:resolved_by, :resolved_at, :system, :body_html]
is_expected.to have_graphql_fields(*expected_fields)
expect(described_class).to have_graphql_fields(*expected_fields)
end
it { is_expected.to expose_permissions_using(Types::PermissionTypes::Note) }
it { is_expected.to require_graphql_authorizations(:read_note) }
it { expect(described_class).to expose_permissions_using(Types::PermissionTypes::Note) }
it { expect(described_class).to require_graphql_authorizations(:read_note) }
end
......@@ -2,7 +2,7 @@
require 'spec_helper'
describe Types::Notes::NoteableType do
it { is_expected.to have_graphql_fields(:notes, :discussions) }
it { expect(described_class).to have_graphql_fields(:notes, :discussions) }
describe ".resolve_type" do
it 'knows the correct type for objects' do
......
......@@ -19,13 +19,13 @@ describe Types::PermissionTypes::BasePermissionType do
describe '.permission_field' do
it 'adds a field for the required permission' do
is_expected.to have_graphql_field(:do_stuff)
expect(test_type).to have_graphql_field(:do_stuff)
end
end
describe '.ability_field' do
it 'adds a field for the required permission' do
is_expected.to have_graphql_field(:read_issue)
expect(test_type).to have_graphql_field(:read_issue)
end
it 'does not add a resolver block if another resolving param is passed' do
......@@ -44,7 +44,7 @@ describe Types::PermissionTypes::BasePermissionType do
describe '.abilities' do
it 'adds a field for the passed permissions' do
is_expected.to have_graphql_field(:admin_issue)
expect(test_type).to have_graphql_field(:admin_issue)
end
end
end
......@@ -8,6 +8,6 @@ describe GitlabSchema.types['NotePermissions'] do
:read_note, :create_note, :admin_note, :resolve_note, :award_emoji
]
is_expected.to have_graphql_fields(expected_permissions)
expect(described_class).to have_graphql_fields(expected_permissions)
end
end
......@@ -4,7 +4,7 @@ require 'spec_helper'
describe GitlabSchema.types['ProjectStatistics'] do
it "has all the required fields" do
is_expected.to have_graphql_fields(:storage_size, :repository_size, :lfs_objects_size,
expect(described_class).to have_graphql_fields(:storage_size, :repository_size, :lfs_objects_size,
:build_artifacts_size, :packages_size, :commit_count,
:wiki_size)
end
......
......@@ -27,7 +27,7 @@ describe GitlabSchema.types['Project'] do
boards
]
is_expected.to include_graphql_fields(*expected_fields)
expect(described_class).to include_graphql_fields(*expected_fields)
end
describe 'issue field' do
......
......@@ -7,7 +7,7 @@ describe GitlabSchema.types['Repository'] do
it { expect(described_class).to require_graphql_authorizations(:download_code) }
it { is_expected.to have_graphql_field(:root_ref) }
it { expect(described_class).to have_graphql_field(:root_ref) }
it { is_expected.to have_graphql_field(:tree) }
it { expect(described_class).to have_graphql_field(:tree) }
end
......@@ -6,9 +6,9 @@ describe GitlabSchema.types['RootStorageStatistics'] do
it { expect(described_class.graphql_name).to eq('RootStorageStatistics') }
it 'has all the required fields' do
is_expected.to have_graphql_fields(:storage_size, :repository_size, :lfs_objects_size,
expect(described_class).to have_graphql_fields(:storage_size, :repository_size, :lfs_objects_size,
:build_artifacts_size, :packages_size, :wiki_size)
end
it { is_expected.to require_graphql_authorizations(:read_statistics) }
it { expect(described_class).to require_graphql_authorizations(:read_statistics) }
end
......@@ -10,7 +10,7 @@ describe GitlabSchema.types['Snippet'] do
:web_url, :raw_url, :notes, :discussions,
:user_permissions, :description_html, :blob]
is_expected.to have_graphql_fields(*expected_fields)
expect(described_class).to have_graphql_fields(*expected_fields)
end
describe 'authorizations' do
......
......@@ -8,6 +8,6 @@ describe GitlabSchema.types['SnippetBlob'] do
:raw_path, :size, :binary, :name, :path,
:simple_viewer, :rich_viewer, :mode]
is_expected.to have_graphql_fields(*expected_fields)
expect(described_class).to have_graphql_fields(*expected_fields)
end
end
......@@ -7,6 +7,6 @@ describe GitlabSchema.types['SnippetBlobViewer'] do
expected_fields = [:type, :load_async, :too_large, :collapsed,
:render_error, :file_type, :loading_partial_name]
is_expected.to have_graphql_fields(*expected_fields)
expect(described_class).to have_graphql_fields(*expected_fields)
end
end
......@@ -6,7 +6,7 @@ describe GitlabSchema.types['Todo'] do
it 'has the correct fields' do
expected_fields = [:id, :project, :group, :author, :action, :target_type, :body, :state, :created_at]
is_expected.to have_graphql_fields(*expected_fields)
expect(described_class).to have_graphql_fields(*expected_fields)
end
it { expect(described_class).to require_graphql_authorizations(:read_todo) }
......
......@@ -12,7 +12,7 @@ describe GitlabSchema.types['User'] do
user_permissions snippets name username avatarUrl webUrl todos
]
is_expected.to have_graphql_fields(*expected_fields)
expect(described_class).to have_graphql_fields(*expected_fields)
end
describe 'snippets field' do
......
......@@ -42,7 +42,7 @@ describe Feature do
.once
.and_call_original
expect(Gitlab::ThreadMemoryCache.cache_backend)
expect(Gitlab::ProcessMemoryCache.cache_backend)
.to receive(:fetch)
.once
.with('flipper:persisted_names', expires_in: 1.minute)
......
......@@ -17,7 +17,7 @@ describe RuboCop::Cop::Migration::SaferBooleanColumn do
allow(cop).to receive(:in_migration?).and_return(true)
end
described_class::SMALL_TABLES.each do |table|
described_class::WHITELISTED_TABLES.each do |table|
context "for the #{table} table" do
sources_and_offense = [
["add_column :#{table}, :column, :boolean, default: true", 'should disallow nulls'],
......@@ -62,14 +62,14 @@ describe RuboCop::Cop::Migration::SaferBooleanColumn do
end
end
it 'registers no offense for tables not listed in SMALL_TABLES' do
it 'registers no offense for tables not listed in WHITELISTED_TABLES' do
inspect_source("add_column :large_table, :column, :boolean")
expect(cop.offenses).to be_empty
end
it 'registers no offense for non-boolean columns' do
table = described_class::SMALL_TABLES.sample
table = described_class::WHITELISTED_TABLES.sample
inspect_source("add_column :#{table}, :column, :string")
expect(cop.offenses).to be_empty
......@@ -78,7 +78,7 @@ describe RuboCop::Cop::Migration::SaferBooleanColumn do
context 'outside of migration' do
it 'registers no offense' do
table = described_class::SMALL_TABLES.sample
table = described_class::WHITELISTED_TABLES.sample
inspect_source("add_column :#{table}, :column, :boolean")
expect(cop.offenses).to be_empty
......
......@@ -18,7 +18,7 @@ describe RuboCop::Cop::Migration::UpdateLargeTable do
end
shared_examples 'large tables' do |update_method|
described_class::LARGE_TABLES.each do |table|
described_class::BLACKLISTED_TABLES.each do |table|
it "registers an offense for the #{table} table" do
inspect_source("#{update_method} :#{table}, :column, default: true")
......@@ -53,7 +53,7 @@ describe RuboCop::Cop::Migration::UpdateLargeTable do
end
it 'registers no offense for non-blacklisted methods' do
table = described_class::LARGE_TABLES.sample
table = described_class::BLACKLISTED_TABLES.sample
inspect_source("some_other_method :#{table}, :column, default: true")
......@@ -62,7 +62,7 @@ describe RuboCop::Cop::Migration::UpdateLargeTable do
end
context 'outside of migration' do
let(:table) { described_class::LARGE_TABLES.sample }
let(:table) { described_class::BLACKLISTED_TABLES.sample }
it 'registers no offense for add_column_with_default' do
inspect_source("add_column_with_default :#{table}, :column, default: true")
......
......@@ -71,10 +71,10 @@ module GraphqlHelpers
mutation_name = GraphqlHelpers.fieldnamerize(name)
input_variable_name = "$#{input_variable_name_for_mutation(name)}"
mutation_field = GitlabSchema.mutation.fields[mutation_name]
fields ||= all_graphql_fields_for(mutation_field.type)
fields ||= all_graphql_fields_for(mutation_field.type.to_graphql)
query = <<~MUTATION
mutation(#{input_variable_name}: #{mutation_field.arguments['input'].type}) {
mutation(#{input_variable_name}: #{mutation_field.arguments['input'].type.to_graphql}) {
#{mutation_name}(input: #{input_variable_name}) {
#{fields}
}
......@@ -118,15 +118,22 @@ module GraphqlHelpers
GraphqlHelpers.fieldnamerize(input_type)
end
def query_graphql_field(name, attributes = {}, fields = nil)
field_params = if attributes.present?
def field_with_params(name, attributes = {})
namerized = GraphqlHelpers.fieldnamerize(name.to_s)
return "#{namerized}" if attributes.blank?
field_params = if attributes.is_a?(Hash)
"(#{attributes_to_graphql(attributes)})"
else
''
"(#{attributes})"
end
"#{namerized}#{field_params}"
end
def query_graphql_field(name, attributes = {}, fields = nil)
<<~QUERY
#{GraphqlHelpers.fieldnamerize(name.to_s)}#{field_params}
#{field_with_params(name, attributes)}
#{wrap_fields(fields || all_graphql_fields_for(name.to_s.classify))}
QUERY
end
......@@ -300,7 +307,7 @@ module GraphqlHelpers
end
def field_type(field)
field_type = field.type
field_type = field.type.respond_to?(:to_graphql) ? field.type.to_graphql : field.type
# The type could be nested. For example `[GraphQL::STRING_TYPE]`:
# - List
......
......@@ -2,7 +2,7 @@
RSpec::Matchers.define :require_graphql_authorizations do |*expected|
match do |field|
expect(field.metadata[:authorize]).to eq(*expected)
expect(field.to_graphql.metadata[:authorize]).to eq(*expected)
end
end
......@@ -87,13 +87,13 @@ end
RSpec::Matchers.define :have_graphql_type do |expected|
match do |field|
expect(field.type).to eq(expected.to_graphql)
expect(field.type).to eq(expected)
end
end
RSpec::Matchers.define :have_non_null_graphql_type do |expected|
match do |field|
expect(field.type).to eq(!expected.to_graphql)
expect(field.type.to_graphql).to eq(!expected.to_graphql)
end
end
......@@ -101,16 +101,16 @@ RSpec::Matchers.define :have_graphql_resolver do |expected|
match do |field|
case expected
when Method
expect(field.metadata[:type_class].resolve_proc).to eq(expected)
expect(field.to_graphql.metadata[:type_class].resolve_proc).to eq(expected)
else
expect(field.metadata[:type_class].resolver).to eq(expected)
expect(field.to_graphql.metadata[:type_class].resolver).to eq(expected)
end
end
end
RSpec::Matchers.define :have_graphql_extension do |expected|
match do |field|
expect(field.metadata[:type_class].extensions).to include(expected)
expect(field.to_graphql.metadata[:type_class].extensions).to include(expected)
end
end
......
......@@ -15,7 +15,7 @@ RSpec.shared_context 'group and project boards query context' do
board_parent_type,
{ 'fullPath' => board_parent.full_path },
<<~BOARDS
boards(#{board_params}) {
#{field_with_params('boards', board_params)} {
pageInfo {
startCursor
endCursor
......@@ -35,7 +35,7 @@ RSpec.shared_context 'group and project boards query context' do
board_parent_type,
{ 'fullPath' => board_parent.full_path },
<<~BOARD
board(#{board_params}) {
#{field_with_params('board', board_params)} {
#{all_graphql_fields_for('board'.classify)}
}
BOARD
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment