Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'spec/graphql/types/global_id_type_spec.rb')
-rw-r--r--spec/graphql/types/global_id_type_spec.rb215
1 files changed, 215 insertions, 0 deletions
diff --git a/spec/graphql/types/global_id_type_spec.rb b/spec/graphql/types/global_id_type_spec.rb
new file mode 100644
index 00000000000..2a7b26f66b0
--- /dev/null
+++ b/spec/graphql/types/global_id_type_spec.rb
@@ -0,0 +1,215 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Types::GlobalIDType do
+ let_it_be(:project) { create(:project) }
+ let(:gid) { project.to_global_id }
+ let(:foreign_gid) { GlobalID.new(::URI::GID.build(app: 'otherapp', model_name: 'Project', model_id: project.id, params: nil)) }
+
+ it 'is has the correct name' do
+ expect(described_class.to_graphql.name).to eq('GlobalID')
+ end
+
+ describe '.coerce_result' do
+ it 'can coerce results' do
+ expect(described_class.coerce_isolated_result(gid)).to eq(gid.to_s)
+ end
+
+ it 'rejects integer IDs' do
+ expect { described_class.coerce_isolated_result(project.id) }
+ .to raise_error(ArgumentError)
+ end
+
+ it 'rejects strings' do
+ expect { described_class.coerce_isolated_result('not a GID') }
+ .to raise_error(ArgumentError)
+ end
+ end
+
+ describe '.coerce_input' do
+ it 'can coerce valid input' do
+ coerced = described_class.coerce_isolated_input(gid.to_s)
+
+ expect(coerced).to eq(gid)
+ end
+
+ it 'handles all valid application GIDs' do
+ expect { described_class.coerce_isolated_input(build_stubbed(:user).to_global_id.to_s) }
+ .not_to raise_error
+ end
+
+ it 'rejects invalid input' do
+ expect { described_class.coerce_isolated_input('not valid') }
+ .to raise_error(GraphQL::CoercionError)
+ end
+
+ it 'rejects nil' do
+ expect { described_class.coerce_isolated_input(nil) }
+ .to raise_error(GraphQL::CoercionError)
+ end
+
+ it 'rejects gids from different apps' do
+ expect { described_class.coerce_isolated_input(foreign_gid) }
+ .to raise_error(GraphQL::CoercionError)
+ end
+ end
+
+ describe 'a parameterized type' do
+ let(:type) { ::Types::GlobalIDType[::Project] }
+
+ it 'is has the correct name' do
+ expect(type.to_graphql.name).to eq('ProjectID')
+ end
+
+ context 'the GID is appropriate' do
+ it 'can coerce results' do
+ expect(type.coerce_isolated_result(gid)).to eq(gid.to_s)
+ end
+
+ it 'can coerce IDs to a GlobalIDType' do
+ expect(type.coerce_isolated_result(project.id)).to eq(gid.to_s)
+ end
+
+ it 'can coerce valid input' do
+ expect(type.coerce_isolated_input(gid.to_s)).to eq(gid)
+ end
+ end
+
+ context 'the GID is not for an appropriate type' do
+ let(:gid) { build_stubbed(:user).to_global_id }
+
+ it 'raises errors when coercing results' do
+ expect { type.coerce_isolated_result(gid) }.to raise_error(GraphQL::CoercionError)
+ end
+
+ it 'will not coerce invalid input, even if its a valid GID' do
+ expect { type.coerce_isolated_input(gid.to_s) }
+ .to raise_error(GraphQL::CoercionError)
+ end
+ end
+ end
+
+ describe 'a parameterized type with a namespace' do
+ let(:type) { ::Types::GlobalIDType[::Ci::Build] }
+
+ it 'is has a valid GraphQL identifier for a name' do
+ expect(type.to_graphql.name).to eq('CiBuildID')
+ end
+ end
+
+ describe 'compatibility' do
+ # Simplified schema to test compatibility
+
+ def query(doc, vars)
+ GraphQL::Query.new(schema, document: doc, context: {}, variables: vars)
+ end
+
+ def run_query(gql_query, vars)
+ query(GraphQL.parse(gql_query), vars).result
+ end
+
+ all_types = [::GraphQL::ID_TYPE, ::Types::GlobalIDType, ::Types::GlobalIDType[::Project]]
+
+ shared_examples 'a working query' do
+ let!(:schema) do
+ # capture values so they can be closed over
+ arg_type = argument_type
+ res_type = result_type
+
+ project = Class.new(GraphQL::Schema::Object) do
+ graphql_name 'Project'
+ field :name, String, null: false
+ field :id, res_type, null: false, resolver_method: :global_id
+
+ def global_id
+ object.to_global_id
+ end
+ end
+
+ Class.new(GraphQL::Schema) do
+ query(Class.new(GraphQL::Schema::Object) do
+ graphql_name 'Query'
+
+ field :project_by_id, project, null: true do
+ argument :id, arg_type, required: true
+ end
+
+ def project_by_id(id:)
+ gid = ::Types::GlobalIDType[::Project].coerce_isolated_input(id)
+ gid.model_class.find(gid.model_id)
+ end
+ end)
+ end
+ end
+
+ it 'works' do
+ res = run_query(document, 'projectId' => project.to_global_id.to_s)
+
+ expect(res['errors']).to be_blank
+ expect(res.dig('data', 'project', 'name')).to eq(project.name)
+ expect(res.dig('data', 'project', 'id')).to eq(project.to_global_id.to_s)
+ end
+ end
+
+ context 'when the argument is declared as ID' do
+ let(:document) do
+ <<-GRAPHQL
+ query($projectId: ID!){
+ project: projectById(id: $projectId) {
+ name, id
+ }
+ }
+ GRAPHQL
+ end
+
+ let(:argument_type) { ::GraphQL::ID_TYPE }
+
+ where(:result_type) { all_types }
+
+ with_them do
+ it_behaves_like 'a working query'
+ end
+ end
+
+ context 'when the argument is declared as GlobalID' do
+ let(:document) do
+ <<-GRAPHQL
+ query($projectId: GlobalID!) {
+ project: projectById(id: $projectId) {
+ name, id
+ }
+ }
+ GRAPHQL
+ end
+
+ let(:argument_type) { ::Types::GlobalIDType }
+
+ where(:result_type) { all_types }
+
+ with_them do
+ it_behaves_like 'a working query'
+ end
+ end
+
+ context 'when the argument is declared as ProjectID' do
+ let(:document) do
+ <<-GRAPHQL
+ query($projectId: ProjectID!) {
+ project: projectById(id: $projectId) {
+ name, id
+ }
+ }
+ GRAPHQL
+ end
+
+ let(:argument_type) { ::Types::GlobalIDType[::Project] }
+
+ where(:result_type) { all_types }
+
+ with_them do
+ it_behaves_like 'a working query'
+ end
+ end
+ end
+end