diff options
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.rb | 216 |
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 |