summaryrefslogtreecommitdiff
path: root/spec/requests/api/graphql/project/issue/design_collection/version_spec.rb
diff options
context:
space:
mode:
Diffstat (limited to 'spec/requests/api/graphql/project/issue/design_collection/version_spec.rb')
-rw-r--r--spec/requests/api/graphql/project/issue/design_collection/version_spec.rb216
1 files changed, 216 insertions, 0 deletions
diff --git a/spec/requests/api/graphql/project/issue/design_collection/version_spec.rb b/spec/requests/api/graphql/project/issue/design_collection/version_spec.rb
new file mode 100644
index 00000000000..04f445b4318
--- /dev/null
+++ b/spec/requests/api/graphql/project/issue/design_collection/version_spec.rb
@@ -0,0 +1,216 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe 'Query.project(fullPath).issue(iid).designCollection.version(sha)' do
+ include GraphqlHelpers
+ include DesignManagementTestHelpers
+
+ let_it_be(:project) { create(:project) }
+ let_it_be(:issue) { create(:issue, project: project) }
+ let_it_be(:developer) { create(:user) }
+ let_it_be(:stranger) { create(:user) }
+ let_it_be(:old_version) do
+ create(:design_version, issue: issue,
+ created_designs: create_list(:design, 3, issue: issue))
+ end
+ let_it_be(:version) do
+ create(:design_version, issue: issue,
+ modified_designs: old_version.designs,
+ created_designs: create_list(:design, 2, issue: issue))
+ end
+
+ let(:current_user) { developer }
+
+ def query(vq = version_fields)
+ graphql_query_for(:project, { fullPath: project.full_path },
+ query_graphql_field(:issue, { iid: issue.iid.to_s },
+ query_graphql_field(:design_collection, nil,
+ query_graphql_field(:version, { sha: version.sha }, vq))))
+ end
+
+ let(:post_query) { post_graphql(query, current_user: current_user) }
+ let(:path_prefix) { %w[project issue designCollection version] }
+
+ let(:data) { graphql_data.dig(*path) }
+
+ before do
+ enable_design_management
+ project.add_developer(developer)
+ end
+
+ describe 'scalar fields' do
+ let(:path) { path_prefix }
+ let(:version_fields) { query_graphql_field(:sha) }
+
+ before do
+ post_query
+ end
+
+ { id: ->(x) { x.to_global_id.to_s }, sha: ->(x) { x.sha } }.each do |field, value|
+ describe ".#{field}" do
+ let(:version_fields) { query_graphql_field(field) }
+
+ it "retrieves the #{field}" do
+ expect(data).to match(a_hash_including(field.to_s => value[version]))
+ end
+ end
+ end
+ end
+
+ describe 'design_at_version' do
+ let(:path) { path_prefix + %w[designAtVersion] }
+ let(:design) { issue.designs.visible_at_version(version).to_a.sample }
+ let(:design_at_version) { build(:design_at_version, design: design, version: version) }
+
+ let(:version_fields) do
+ query_graphql_field(:design_at_version, dav_params, 'id filename')
+ end
+
+ shared_examples :finds_dav do
+ it 'finds all the designs as of the given version' do
+ post_query
+
+ expect(data).to match(
+ a_hash_including(
+ 'id' => global_id_of(design_at_version),
+ 'filename' => design.filename
+ ))
+ end
+
+ context 'when the current_user is not authorized' do
+ let(:current_user) { stranger }
+
+ it 'returns nil' do
+ post_query
+
+ expect(data).to be_nil
+ end
+ end
+ end
+
+ context 'by ID' do
+ let(:dav_params) { { id: global_id_of(design_at_version) } }
+
+ include_examples :finds_dav
+ end
+
+ context 'by filename' do
+ let(:dav_params) { { filename: design.filename } }
+
+ include_examples :finds_dav
+ end
+
+ context 'by design_id' do
+ let(:dav_params) { { design_id: global_id_of(design) } }
+
+ include_examples :finds_dav
+ end
+ end
+
+ describe 'designs_at_version' do
+ let(:path) { path_prefix + %w[designsAtVersion edges] }
+ let(:version_fields) do
+ query_graphql_field(:designs_at_version, dav_params, 'edges { node { id filename } }')
+ end
+
+ let(:dav_params) { nil }
+
+ let(:results) do
+ issue.designs.visible_at_version(version).map do |d|
+ dav = build(:design_at_version, design: d, version: version)
+ { 'id' => global_id_of(dav), 'filename' => d.filename }
+ end
+ end
+
+ it 'finds all the designs as of the given version' do
+ post_query
+
+ expect(data.pluck('node')).to match_array(results)
+ end
+
+ describe 'filtering' do
+ let(:designs) { issue.designs.sample(3) }
+ let(:filenames) { designs.map(&:filename) }
+ let(:ids) do
+ designs.map { |d| global_id_of(build(:design_at_version, design: d, version: version)) }
+ end
+
+ before do
+ post_query
+ end
+
+ describe 'by filename' do
+ let(:dav_params) { { filenames: filenames } }
+
+ it 'finds the designs by filename' do
+ expect(data.map { |e| e.dig('node', 'id') }).to match_array(ids)
+ end
+ end
+
+ describe 'by design-id' do
+ let(:dav_params) { { ids: designs.map { |d| global_id_of(d) } } }
+
+ it 'finds the designs by id' do
+ expect(data.map { |e| e.dig('node', 'filename') }).to match_array(filenames)
+ end
+ end
+ end
+
+ describe 'pagination' do
+ let(:end_cursor) { graphql_data_at(*path_prefix, :designs_at_version, :page_info, :end_cursor) }
+
+ let(:ids) do
+ ::DesignManagement::Design.visible_at_version(version).order(:id).map do |d|
+ global_id_of(build(:design_at_version, design: d, version: version))
+ end
+ end
+
+ let(:version_fields) do
+ query_graphql_field(:designs_at_version, { first: 2 }, fields)
+ end
+
+ let(:cursored_query) do
+ frag = query_graphql_field(:designs_at_version, { after: end_cursor }, fields)
+ query(frag)
+ end
+
+ let(:fields) { ['pageInfo { endCursor }', 'edges { node { id } }'] }
+
+ def response_values(data = graphql_data)
+ data.dig(*path).map { |e| e.dig('node', 'id') }
+ end
+
+ it 'sorts designs for reliable pagination' do
+ post_graphql(query, current_user: current_user)
+
+ expect(response_values).to match_array(ids.take(2))
+
+ post_graphql(cursored_query, current_user: current_user)
+
+ new_data = Gitlab::Json.parse(response.body).fetch('data')
+
+ expect(response_values(new_data)).to match_array(ids.drop(2))
+ end
+ end
+ end
+
+ describe 'designs' do
+ let(:path) { path_prefix + %w[designs edges] }
+ let(:version_fields) do
+ query_graphql_field(:designs, nil, 'edges { node { id filename } }')
+ end
+
+ let(:results) do
+ version.designs.map do |design|
+ { 'id' => global_id_of(design), 'filename' => design.filename }
+ end
+ end
+
+ it 'finds all the designs as of the given version' do
+ post_query
+
+ expect(data.pluck('node')).to match_array(results)
+ end
+ end
+end