Commit a9cd5d23 authored by Alex Kalderimis's avatar Alex Kalderimis

Add Design-At-Version Graph-QL type

Also adds design-fields specs

Note that until we mount this type, we cannot use the mechanism
`GitlabSchema.types[name]` to describe the type in tests
parent 0dae7ac8
# frozen_string_literal: true
module Types
module DesignManagement
class DesignAtVersionType < BaseObject
graphql_name 'DesignAtVersion'
description 'A design pinned to a specific version'
authorize :read_design
delegate :design, :version, to: :object
delegate :issue, :filename, :full_path, :diff_refs, to: :design
implements ::Types::DesignManagement::DesignFields
field :version,
Types::DesignManagement::VersionType,
null: false,
description: 'The version this design-at-versions is pinned to'
field :design,
Types::DesignManagement::DesignType,
null: false,
description: 'The underlying design.'
def cached_stateful_version(_parent)
version
end
def notes_count
design.user_notes_count
end
end
end
end
# frozen_string_literal: true
module Types
module DesignManagement
module DesignFields
include BaseInterface
field_class Types::BaseField
field :id, GraphQL::ID_TYPE, description: 'The ID of this design', null: false
field :project, Types::ProjectType, null: false, description: 'The project the design belongs to'
field :issue, Types::IssueType, null: false, description: 'The issue the design belongs to'
field :filename, GraphQL::STRING_TYPE, null: false, description: 'The filename of the design'
field :full_path, GraphQL::STRING_TYPE, null: false, description: 'The full path to the design file'
field :image, GraphQL::STRING_TYPE, null: false, extras: [:parent], description: 'The URL of the image'
field :diff_refs, Types::DiffRefsType,
null: false,
calls_gitaly: true,
extras: [:parent],
description: 'The diff refs for this design'
field :event, Types::DesignManagement::DesignVersionEventEnum,
null: false,
extras: [:parent],
description: 'How this design was changed in the current version'
field :notes_count,
GraphQL::INT_TYPE,
null: false,
method: :user_notes_count,
description: 'The total count of user-created notes for this design'
def diff_refs(parent:)
version = cached_stateful_version(parent)
version.diff_refs
end
def image(parent:)
sha = cached_stateful_version(parent).sha
::Gitlab::Routing.url_helpers.project_design_url(design.project, design, sha)
end
def event(parent:)
version = cached_stateful_version(parent)
action = cached_actions_for_version(version)[design.id]
action&.event || ::Types::DesignManagement::DesignVersionEventEnum::NONE
end
def cached_actions_for_version(version)
Gitlab::SafeRequestStore.fetch(['DesignFields', 'actions_for_version', version.id]) do
version.actions.to_h { |dv| [dv.design_id, dv] }
end
end
def project
::Gitlab::Graphql::Loaders::BatchModelLoader.new(::Project, design.project_id).find
end
def issue
::Gitlab::Graphql::Loaders::BatchModelLoader.new(::Issue, design.issue_id).find
end
end
end
end
......@@ -7,53 +7,17 @@ module Types
authorize :read_design
implements(Types::Notes::NoteableType)
alias_method :design, :object
field :id, GraphQL::ID_TYPE, null: false,
description: 'ID of the design'
field :project, Types::ProjectType, null: false,
description: 'Project associated with the design'
field :issue, Types::IssueType, null: false,
description: 'Issue associated with the design'
field :notes_count, GraphQL::INT_TYPE, null: false,
method: :user_notes_count,
description: 'Total count of user-created notes for the design'
field :filename, GraphQL::STRING_TYPE, null: false,
description: 'Filename of the design file'
field :full_path, GraphQL::STRING_TYPE, null: false,
description: 'Full path of the design file'
field :event, Types::DesignManagement::DesignVersionEventEnum, null: false,
description: 'Type of change made to the design at the version specified by the `atVersion` argument '\
'if supplied. Defaults to the latest version',
extras: [:parent]
field :image, GraphQL::STRING_TYPE, null: false,
description: 'Image of the design',
extras: [:parent]
field :diff_refs, Types::DiffRefsType, null: false,
description: 'Diff refs of the design',
calls_gitaly: true
implements(Types::Notes::NoteableType)
implements(Types::DesignManagement::DesignFields)
field :versions,
Types::DesignManagement::VersionType.connection_type,
resolver: Resolvers::DesignManagement::VersionResolver,
description: 'All versions related to the design, ordered newest first',
description: "All versions related to this design ordered newest first",
extras: [:parent]
def image(parent:)
sha = cached_stateful_version(parent).sha
Gitlab::Routing.url_helpers.project_design_url(design.project, design, sha)
end
def event(parent:)
version = cached_stateful_version(parent)
action = cached_actions_for_version(version)[design.id]
action&.event || Types::DesignManagement::DesignVersionEventEnum::NONE
end
# Returns a `DesignManagement::Version` for this query based on the
# `atVersion` argument passed to a parent node if present, or otherwise
# the most recent `Version` for the issue.
......@@ -71,12 +35,6 @@ module Types
end
end
def cached_actions_for_version(version)
Gitlab::SafeRequestStore.fetch([request_cache_base_key, 'actions_for_version', version.id]) do
version.actions.to_h { |dv| [dv.design_id, dv] }
end
end
def request_cache_base_key
self.class.name
end
......
# frozen_string_literal: true
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
it_behaves_like 'a GraphQL type with design fields' do
let(:extra_design_fields) { %i[version design] }
end
end
......@@ -3,26 +3,7 @@
require 'spec_helper'
describe GitlabSchema.types['Design'] do
it { expect(described_class).to require_graphql_authorizations(:read_design) }
it { expect(described_class.interfaces).to include(Types::Notes::NoteableType.to_graphql) }
it 'exposes the expected fields' do
expected_fields = %i[
diff_refs
discussions
event
filename
full_path
id
image
issue
notes
notes_count
project
versions
]
is_expected.to have_graphql_fields(*expected_fields)
it_behaves_like 'a GraphQL type with design fields' do
let(:extra_design_fields) { %i[notes discussions versions] }
end
end
# frozen_string_literal: true
shared_examples 'a GraphQL type with design fields' do
it { expect(described_class).to require_graphql_authorizations(:read_design) }
it 'exposes the expected design fields' do
expected_fields = %i[
id
project
issue
filename
full_path
image
diff_refs
event
notes_count
] + extra_design_fields
is_expected.to have_graphql_fields(*expected_fields)
end
end
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