Commit cc152518 authored by James Lopez's avatar James Lopez

Merge branch '207278-graphql-upgrade-to-graphql-ruby-1-10' into 'master'

GraphQL: Upgrade to GraphQL-Ruby 1.10

Closes #207278

See merge request gitlab-org/gitlab!26096
parents ee0c3cc7 846ef5c2
......@@ -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
......
......@@ -2,9 +2,7 @@
require 'spec_helper'
# describe GitlabSchema.types['DesignAtVersion'] do
# This not available on the schema until we mount it somewhere
describe ::Types::DesignManagement::DesignAtVersionType.to_graphql do
describe GitlabSchema.types['DesignAtVersion'] do
it_behaves_like 'a GraphQL type with design fields' do
let(:extra_design_fields) { %i[version design] }
let_it_be(:design) { create(:design, :with_versions) }
......
......@@ -3,5 +3,5 @@
require 'spec_helper'
describe GitlabSchema.types['DesignManagement'] do
it { is_expected.to have_graphql_fields(:version, :design_at_version) }
it { expect(described_class).to have_graphql_fields(:version, :design_at_version) }
end
......@@ -23,7 +23,7 @@ describe GitlabSchema.types['Epic'] do
it { expect(described_class).to have_graphql_fields(fields) }
it { is_expected.to have_graphql_field(:subscribed, complexity: 5) }
it { expect(described_class).to have_graphql_field(:subscribed, complexity: 5) }
it { is_expected.to have_graphql_field(:participants, complexity: 5) }
it { expect(described_class).to have_graphql_field(:participants, complexity: 5) }
end
......@@ -6,7 +6,7 @@ describe GitlabSchema.types['Project'] do
it 'includes the ee specific fields' do
expected_fields = %w[service_desk_enabled service_desk_address vulnerabilities]
is_expected.to include_graphql_fields(*expected_fields)
expect(described_class).to include_graphql_fields(*expected_fields)
end
describe 'vulnerabilities' do
......
......@@ -4,6 +4,6 @@ require 'spec_helper'
describe GitlabSchema.types['Query'] do
it do
is_expected.to have_graphql_fields(:design_management).at_least
expect(described_class).to have_graphql_fields(:design_management).at_least
end
end
......@@ -90,7 +90,7 @@ describe 'Updating an epic tree' do
end
it_behaves_like 'a mutation that returns top-level errors',
errors: ['Variable epicTreeReorderInput of type EpicTreeReorderInput! was provided invalid value for moved.relativePosition (Expected "invalid" to be one of: before, after)']
errors: ['Variable $epicTreeReorderInput of type EpicTreeReorderInput! was provided invalid value for moved.relativePosition (Expected "invalid" to be one of: before, after)']
end
context 'when object being moved is not supported type' do
......
......@@ -55,7 +55,7 @@ describe 'Setting weight of an issue' do
let(:input) { { weight: "2" } }
it 'raises invalid value error' do
error = "Variable issueSetWeightInput of type IssueSetWeightInput! was provided "\
error = "Variable $issueSetWeightInput of type IssueSetWeightInput! was provided "\
"invalid value for weight (Could not coerce value \"#{input[:weight]}\" to Int)"
post_graphql_mutation(mutation, current_user: current_user)
......
......@@ -22,7 +22,7 @@ RSpec.shared_examples 'a GraphQL type with design fields' do
notes_count
] + extra_design_fields
is_expected.to have_graphql_fields(*expected_fields).only
expect(described_class).to have_graphql_fields(*expected_fields).only
end
describe '#image' do
......@@ -41,7 +41,7 @@ RSpec.shared_examples 'a GraphQL type with design fields' do
end
it 'resolves to the design image URL' do
image = field.resolve(instance, args, context)
image = field.resolve_field(instance, args, context)
sha = design.versions.first.sha
url = ::Gitlab::Routing.url_helpers.project_design_management_designs_raw_image_url(design.project, design, sha)
......@@ -67,10 +67,10 @@ RSpec.shared_examples 'a GraphQL type with design fields' do
# = 10
expect(instance).not_to eq(instance_b) # preload designs themselves.
expect do
image_a = field.resolve(instance, args, context)
image_b = field.resolve(instance, args, context)
image_c = field.resolve(instance_b, args, context)
image_d = field.resolve(instance_b, args, context)
image_a = field.resolve_field(instance, args, context)
image_b = field.resolve_field(instance, args, context)
image_c = field.resolve_field(instance_b, args, context)
image_d = field.resolve_field(instance_b, args, context)
expect(image_a).to eq(image_b)
expect(image_c).not_to eq(image_b)
expect(image_c).to eq(image_d)
......
......@@ -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
......
......@@ -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