summaryrefslogtreecommitdiff
path: root/spec/graphql
diff options
context:
space:
mode:
authorNick Thomas <nick@gitlab.com>2017-08-16 14:04:41 +0100
committerBob Van Landuyt <bob@vanlanduyt.co>2018-06-05 20:47:42 +0200
commit9c6c17cbcdb8bf8185fc1b873dcfd08f723e4df5 (patch)
tree624dba30e87ed0ea39afa0535d92c37c7718daef /spec/graphql
parent67dc43db2f30095cce7fe01d7f475d084be936e8 (diff)
downloadgitlab-ce-9c6c17cbcdb8bf8185fc1b873dcfd08f723e4df5.tar.gz
Add a minimal GraphQL API
Diffstat (limited to 'spec/graphql')
-rw-r--r--spec/graphql/gitlab_schema_spec.rb27
-rw-r--r--spec/graphql/loaders/full_path_loader_spec.rb38
-rw-r--r--spec/graphql/loaders/iid_loader_spec.rb64
-rw-r--r--spec/graphql/types/query_type_spec.rb37
-rw-r--r--spec/graphql/types/time_type_spec.rb16
5 files changed, 182 insertions, 0 deletions
diff --git a/spec/graphql/gitlab_schema_spec.rb b/spec/graphql/gitlab_schema_spec.rb
new file mode 100644
index 00000000000..3582f297866
--- /dev/null
+++ b/spec/graphql/gitlab_schema_spec.rb
@@ -0,0 +1,27 @@
+require 'spec_helper'
+
+describe GitlabSchema do
+ it 'uses batch loading' do
+ expect(described_class.instrumenters[:multiplex]).to include(GraphQL::Batch::SetupMultiplex)
+ end
+
+ it 'enables the preload instrumenter' do
+ expect(field_instrumenters).to include(instance_of(::GraphQL::Preload::Instrument))
+ end
+
+ it 'enables the authorization instrumenter' do
+ expect(field_instrumenters).to include(instance_of(::Gitlab::Graphql::Authorize))
+ end
+
+ it 'has the base mutation' do
+ expect(described_class.mutation).to eq(::Types::MutationType)
+ end
+
+ it 'has the base query' do
+ expect(described_class.query).to eq(::Types::QueryType)
+ end
+
+ def field_instrumenters
+ described_class.instrumenters[:field]
+ end
+end
diff --git a/spec/graphql/loaders/full_path_loader_spec.rb b/spec/graphql/loaders/full_path_loader_spec.rb
new file mode 100644
index 00000000000..2a473239550
--- /dev/null
+++ b/spec/graphql/loaders/full_path_loader_spec.rb
@@ -0,0 +1,38 @@
+require 'spec_helper'
+
+describe Loaders::FullPathLoader do
+ include GraphqlHelpers
+
+ set(:project1) { create(:project) }
+ set(:project2) { create(:project) }
+
+ set(:other_project) { create(:project) }
+
+ describe '.project' do
+ it 'batch-resolves projects by full path' do
+ paths = [project1.full_path, project2.full_path]
+
+ result = batch(max_queries: 1) do
+ paths.map { |path| resolve_project(path) }
+ end
+
+ expect(result).to contain_exactly(project1, project2)
+ end
+
+ it 'resolves an unknown full_path to nil' do
+ result = batch { resolve_project('unknown/project') }
+
+ expect(result).to be_nil
+ end
+
+ it 'returns a promise' do
+ batch do
+ expect(resolve_project(project1.full_path)).to be_a(Promise)
+ end
+ end
+ end
+
+ def resolve_project(full_path)
+ resolve(described_class, :project, args: { full_path: full_path })
+ end
+end
diff --git a/spec/graphql/loaders/iid_loader_spec.rb b/spec/graphql/loaders/iid_loader_spec.rb
new file mode 100644
index 00000000000..8a0c1f0791a
--- /dev/null
+++ b/spec/graphql/loaders/iid_loader_spec.rb
@@ -0,0 +1,64 @@
+require 'spec_helper'
+
+describe Loaders::IidLoader do
+ include GraphqlHelpers
+
+ set(:project) { create(:project, :repository) }
+ set(:merge_request_1) { create(:merge_request, :simple, source_project: project, target_project: project) }
+ set(:merge_request_2) { create(:merge_request, :rebased, source_project: project, target_project: project) }
+
+ set(:other_project) { create(:project, :repository) }
+ set(:other_merge_request) { create(:merge_request, source_project: other_project, target_project: other_project) }
+
+ let(:full_path) { project.full_path }
+ let(:iid_1) { merge_request_1.iid }
+ let(:iid_2) { merge_request_2.iid }
+
+ let(:other_full_path) { other_project.full_path }
+ let(:other_iid) { other_merge_request.iid }
+
+ describe '.merge_request' do
+ it 'batch-resolves merge requests by target project full path and IID' do
+ path = full_path # avoid database query
+
+ result = batch(max_queries: 2) do
+ [resolve_mr(path, iid_1), resolve_mr(path, iid_2)]
+ end
+
+ expect(result).to contain_exactly(merge_request_1, merge_request_2)
+ end
+
+ it 'can batch-resolve merge requests from different projects' do
+ path = project.full_path # avoid database queries
+ other_path = other_full_path
+
+ result = batch(max_queries: 3) do
+ [resolve_mr(path, iid_1), resolve_mr(path, iid_2), resolve_mr(other_path, other_iid)]
+ end
+
+ expect(result).to contain_exactly(merge_request_1, merge_request_2, other_merge_request)
+ end
+
+ it 'resolves an unknown iid to nil' do
+ result = batch { resolve_mr(full_path, -1) }
+
+ expect(result).to be_nil
+ end
+
+ it 'resolves a known iid for an unknown full_path to nil' do
+ result = batch { resolve_mr('unknown/project', iid_1) }
+
+ expect(result).to be_nil
+ end
+
+ it 'returns a promise' do
+ batch do
+ expect(resolve_mr(full_path, iid_1)).to be_a(Promise)
+ end
+ end
+ end
+
+ def resolve_mr(full_path, iid)
+ resolve(described_class, :merge_request, args: { project: full_path, iid: iid })
+ end
+end
diff --git a/spec/graphql/types/query_type_spec.rb b/spec/graphql/types/query_type_spec.rb
new file mode 100644
index 00000000000..17d9395504c
--- /dev/null
+++ b/spec/graphql/types/query_type_spec.rb
@@ -0,0 +1,37 @@
+require 'spec_helper'
+
+describe GitlabSchema.types['Query'] do
+ it 'is called Query' do
+ expect(described_class.name).to eq('Query')
+ end
+
+ it { is_expected.to have_graphql_fields(:project, :merge_request, :echo) }
+
+ describe 'project field' do
+ subject { described_class.fields['project'] }
+
+ it 'finds projects by full path' do
+ is_expected.to have_graphql_arguments(:full_path)
+ is_expected.to have_graphql_type(Types::ProjectType)
+ is_expected.to have_graphql_resolver(Loaders::FullPathLoader[:project])
+ end
+
+ it 'authorizes with read_project' do
+ is_expected.to require_graphql_authorizations(:read_project)
+ end
+ end
+
+ describe 'merge_request field' do
+ subject { described_class.fields['merge_request'] }
+
+ it 'finds MRs by project and IID' do
+ is_expected.to have_graphql_arguments(:project, :iid)
+ is_expected.to have_graphql_type(Types::MergeRequestType)
+ is_expected.to have_graphql_resolver(Loaders::IidLoader[:merge_request])
+ end
+
+ it 'authorizes with read_merge_request' do
+ is_expected.to require_graphql_authorizations(:read_merge_request)
+ end
+ end
+end
diff --git a/spec/graphql/types/time_type_spec.rb b/spec/graphql/types/time_type_spec.rb
new file mode 100644
index 00000000000..087655cc67d
--- /dev/null
+++ b/spec/graphql/types/time_type_spec.rb
@@ -0,0 +1,16 @@
+require 'spec_helper'
+
+describe GitlabSchema.types['Time'] do
+ let(:float) { 1504630455.96215 }
+ let(:time) { Time.at(float) }
+
+ it { expect(described_class.name).to eq('Time') }
+
+ it 'coerces Time into fractional seconds since epoch' do
+ expect(described_class.coerce_isolated_result(time)).to eq(float)
+ end
+
+ it 'coerces fractional seconds since epoch into Time' do
+ expect(described_class.coerce_isolated_input(float)).to eq(time)
+ end
+end