Commit f7af6ee2 authored by Markus Koller's avatar Markus Koller

Move Design Management GraphQL classes into FOSS

This change is part of
https://gitlab.com/gitlab-org/gitlab/-/issues/212566 to move all Design
Management code to FOSS.

This MR moves the backend GraphQL classes and their specs, and also
includes the design-related changes to the UrlBuilder.
parent 4b74033f
...@@ -85,6 +85,14 @@ module Types ...@@ -85,6 +85,14 @@ module Types
field :task_completion_status, Types::TaskCompletionStatus, null: false, field :task_completion_status, Types::TaskCompletionStatus, null: false,
description: 'Task completion status of the issue' description: 'Task completion status of the issue'
field :designs, Types::DesignManagement::DesignCollectionType, null: true,
method: :design_collection,
deprecated: { reason: 'Use `designCollection`', milestone: '12.2' },
description: 'The designs associated with this issue'
field :design_collection, Types::DesignManagement::DesignCollectionType, null: true,
description: 'Collection of design images associated with this issue'
end end
end end
......
...@@ -42,6 +42,8 @@ module Types ...@@ -42,6 +42,8 @@ module Types
mount_mutation Mutations::Snippets::Create mount_mutation Mutations::Snippets::Create
mount_mutation Mutations::Snippets::MarkAsSpam mount_mutation Mutations::Snippets::MarkAsSpam
mount_mutation Mutations::JiraImport::Start mount_mutation Mutations::JiraImport::Start
mount_mutation Mutations::DesignManagement::Upload, calls_gitaly: true
mount_mutation Mutations::DesignManagement::Delete, calls_gitaly: true
end end
end end
......
...@@ -17,6 +17,8 @@ module Types ...@@ -17,6 +17,8 @@ module Types
Types::MergeRequestType Types::MergeRequestType
when Snippet when Snippet
Types::SnippetType Types::SnippetType
when ::DesignManagement::Design
Types::DesignManagement::DesignType
else else
raise "Unknown GraphQL type for #{object}" raise "Unknown GraphQL type for #{object}"
end end
...@@ -25,5 +27,3 @@ module Types ...@@ -25,5 +27,3 @@ module Types
end end
end end
end end
Types::Notes::NoteableType.extend_if_ee('::EE::Types::Notes::NoteableType')
...@@ -6,11 +6,9 @@ module Types ...@@ -6,11 +6,9 @@ module Types
description 'Check permissions for the current user on a issue' description 'Check permissions for the current user on a issue'
graphql_name 'IssuePermissions' graphql_name 'IssuePermissions'
abilities :read_issue, :admin_issue, abilities :read_issue, :admin_issue, :update_issue, :reopen_issue,
:update_issue, :create_note, :read_design, :create_design, :destroy_design,
:reopen_issue :create_note
end end
end end
end end
Types::PermissionTypes::Issue.prepend_if_ee('::EE::Types::PermissionTypes::Issue')
...@@ -17,7 +17,7 @@ module Types ...@@ -17,7 +17,7 @@ module Types
:admin_wiki, :admin_project, :update_pages, :admin_wiki, :admin_project, :update_pages,
:admin_remote_mirror, :create_label, :update_wiki, :destroy_wiki, :admin_remote_mirror, :create_label, :update_wiki, :destroy_wiki,
:create_pages, :destroy_pages, :read_pages_content, :admin_operations, :create_pages, :destroy_pages, :read_pages_content, :admin_operations,
:read_merge_request :read_merge_request, :read_design, :create_design, :destroy_design
permission_field :create_snippet permission_field :create_snippet
...@@ -27,5 +27,3 @@ module Types ...@@ -27,5 +27,3 @@ module Types
end end
end end
end end
Types::PermissionTypes::Project.prepend_if_ee('EE::Types::PermissionTypes::Project')
...@@ -4,6 +4,9 @@ module Types ...@@ -4,6 +4,9 @@ module Types
class QueryType < ::Types::BaseObject class QueryType < ::Types::BaseObject
graphql_name 'Query' graphql_name 'Query'
# The design management context object needs to implement #issue
DesignManagementObject = Struct.new(:issue)
field :project, Types::ProjectType, field :project, Types::ProjectType,
null: true, null: true,
resolver: Resolvers::ProjectResolver, resolver: Resolvers::ProjectResolver,
...@@ -40,9 +43,17 @@ module Types ...@@ -40,9 +43,17 @@ module Types
resolver: Resolvers::SnippetsResolver, resolver: Resolvers::SnippetsResolver,
description: 'Find Snippets visible to the current user' description: 'Find Snippets visible to the current user'
field :design_management, Types::DesignManagementType,
null: false,
description: 'Fields related to design management'
field :echo, GraphQL::STRING_TYPE, null: false, field :echo, GraphQL::STRING_TYPE, null: false,
description: 'Text to echo back', description: 'Text to echo back',
resolver: Resolvers::EchoResolver resolver: Resolvers::EchoResolver
def design_management
DesignManagementObject.new(nil)
end
end end
end end
......
...@@ -5,6 +5,7 @@ module Types ...@@ -5,6 +5,7 @@ module Types
value 'COMMIT', value: 'Commit', description: 'A Commit' value 'COMMIT', value: 'Commit', description: 'A Commit'
value 'ISSUE', value: 'Issue', description: 'An Issue' value 'ISSUE', value: 'Issue', description: 'An Issue'
value 'MERGEREQUEST', value: 'MergeRequest', description: 'A MergeRequest' value 'MERGEREQUEST', value: 'MergeRequest', description: 'A MergeRequest'
value 'DESIGN', value: 'DesignManagement::Design', description: 'A Design'
end end
end end
......
...@@ -13,14 +13,6 @@ module EE ...@@ -13,14 +13,6 @@ module EE
description: 'Weight of the issue', description: 'Weight of the issue',
resolve: -> (obj, _args, _ctx) { obj.supports_weight? ? obj.weight : nil } resolve: -> (obj, _args, _ctx) { obj.supports_weight? ? obj.weight : nil }
field :designs, ::Types::DesignManagement::DesignCollectionType, null: true,
method: :design_collection,
deprecated: { reason: 'Use `designCollection`', milestone: '12.2' },
description: 'The designs associated with this issue'
field :design_collection, ::Types::DesignManagement::DesignCollectionType, null: true,
description: 'Collection of design images associated with this issue'
field :health_status, field :health_status,
::Types::HealthStatusEnum, ::Types::HealthStatusEnum,
null: true, null: true,
......
...@@ -6,8 +6,6 @@ module EE ...@@ -6,8 +6,6 @@ module EE
extend ActiveSupport::Concern extend ActiveSupport::Concern
prepended do prepended do
mount_mutation ::Mutations::DesignManagement::Upload, calls_gitaly: true
mount_mutation ::Mutations::DesignManagement::Delete, calls_gitaly: true
mount_mutation ::Mutations::Issues::SetWeight mount_mutation ::Mutations::Issues::SetWeight
mount_mutation ::Mutations::EpicTree::Reorder mount_mutation ::Mutations::EpicTree::Reorder
mount_mutation ::Mutations::Epics::Update mount_mutation ::Mutations::Epics::Update
......
# frozen_string_literal: true
module EE
module Types
module Notes
module NoteableType
extend ::Gitlab::Utils::Override
override :resolve_type
def resolve_type(object, context)
case object
when DesignManagement::Design
::Types::DesignManagement::DesignType
else
super
end
end
end
end
end
end
# frozen_string_literal: true
module EE
module Types
module PermissionTypes
module Issue
extend ActiveSupport::Concern
prepended do
abilities :read_design, :create_design, :destroy_design
end
end
end
end
end
# frozen_string_literal: true
module EE
module Types
module PermissionTypes
module Project
extend ActiveSupport::Concern
prepended do
abilities :read_design, :create_design, :destroy_design
end
end
end
end
end
...@@ -5,9 +5,6 @@ module EE ...@@ -5,9 +5,6 @@ module EE
module QueryType module QueryType
extend ActiveSupport::Concern extend ActiveSupport::Concern
# The design management context object needs to implement #issue
DesignManagementObject = Struct.new(:issue)
prepended do prepended do
field :vulnerabilities, field :vulnerabilities,
::Types::VulnerabilityType.connection_type, ::Types::VulnerabilityType.connection_type,
...@@ -21,10 +18,6 @@ module EE ...@@ -21,10 +18,6 @@ module EE
description: "Number of vulnerabilities per severity level, per day, for the projects on the current user's instance security dashboard", description: "Number of vulnerabilities per severity level, per day, for the projects on the current user's instance security dashboard",
resolver: ::Resolvers::VulnerabilitiesHistoryResolver resolver: ::Resolvers::VulnerabilitiesHistoryResolver
field :design_management, ::Types::DesignManagementType,
null: false,
description: 'Fields related to design management'
field :geo_node, ::Types::Geo::GeoNodeType, field :geo_node, ::Types::Geo::GeoNodeType,
null: true, null: true,
resolver: ::Resolvers::Geo::GeoNodeResolver, resolver: ::Resolvers::Geo::GeoNodeResolver,
...@@ -34,10 +27,6 @@ module EE ...@@ -34,10 +27,6 @@ module EE
null: true, null: true,
resolver: ::Resolvers::InstanceSecurityDashboardResolver, resolver: ::Resolvers::InstanceSecurityDashboardResolver,
description: 'Fields related to Instance Security Dashboard' description: 'Fields related to Instance Security Dashboard'
def design_management
DesignManagementObject.new(nil)
end
end end
end end
end end
......
...@@ -6,7 +6,6 @@ module EE ...@@ -6,7 +6,6 @@ module EE
extend ActiveSupport::Concern extend ActiveSupport::Concern
prepended do prepended do
value 'DESIGN', value: 'DesignManagement::Design', description: 'A Design'
value 'EPIC', value: 'Epic', description: 'An Epic' value 'EPIC', value: 'Epic', description: 'An Epic'
end end
end end
......
# frozen_string_literal: true
require 'spec_helper'
describe Types::Notes::NoteableType do
describe ".resolve_type" do
it 'knows the correct type for EE objects' do
expect(described_class.resolve_type(build(:design), {})).to eq(Types::DesignManagement::DesignType)
end
end
end
...@@ -7,9 +7,5 @@ describe GitlabSchema.types['Issue'] do ...@@ -7,9 +7,5 @@ describe GitlabSchema.types['Issue'] do
it { expect(described_class).to have_graphql_field(:weight) } it { expect(described_class).to have_graphql_field(:weight) }
it { expect(described_class).to have_graphql_field(:designs) }
it { expect(described_class).to have_graphql_field(:design_collection) }
it { expect(described_class).to have_graphql_field(:health_status) } it { expect(described_class).to have_graphql_field(:health_status) }
end end
# frozen_string_literal: true
require 'spec_helper'
describe Types::PermissionTypes::Issue do
it "exposes design permissions" do
expected_permissions = [
:read_design, :create_design, :destroy_design
]
expected_permissions.each do |permission|
expect(described_class).to have_graphql_field(permission)
end
end
end
# frozen_string_literal: true
require 'spec_helper'
describe Types::PermissionTypes::Project do
it "exposes design permissions" do
expected_permissions = [
:read_design, :create_design, :destroy_design
]
expected_permissions.each do |permission|
expect(described_class).to have_graphql_field(permission)
end
end
end
...@@ -5,7 +5,6 @@ require 'spec_helper' ...@@ -5,7 +5,6 @@ require 'spec_helper'
describe GitlabSchema.types['Query'] do describe GitlabSchema.types['Query'] do
specify do specify do
expect(described_class).to have_graphql_fields( expect(described_class).to have_graphql_fields(
:design_management,
:geo_node, :geo_node,
:vulnerabilities, :vulnerabilities,
:instance_security_dashboard, :instance_security_dashboard,
......
...@@ -6,7 +6,6 @@ describe 'getting project information' do ...@@ -6,7 +6,6 @@ describe 'getting project information' do
include GraphqlHelpers include GraphqlHelpers
let_it_be(:current_user) { create(:user) } let_it_be(:current_user) { create(:user) }
let_it_be(:design_todo) { create(:todo, user: current_user, target: create(:design)) }
let_it_be(:epic_todo) { create(:todo, user: current_user, target: create(:epic)) } let_it_be(:epic_todo) { create(:todo, user: current_user, target: create(:epic)) }
let(:fields) do let(:fields) do
<<~QUERY <<~QUERY
...@@ -29,7 +28,6 @@ describe 'getting project information' do ...@@ -29,7 +28,6 @@ describe 'getting project information' do
it 'returns Todos for all target types' do it 'returns Todos for all target types' do
is_expected.to include( is_expected.to include(
a_hash_including('targetType' => 'DESIGN'),
a_hash_including('targetType' => 'EPIC') a_hash_including('targetType' => 'EPIC')
) )
end end
......
...@@ -5,94 +5,6 @@ require 'spec_helper' ...@@ -5,94 +5,6 @@ require 'spec_helper'
describe 'Query' do describe 'Query' do
include GraphqlHelpers include GraphqlHelpers
let_it_be(:project) { create(:project) }
let_it_be(:issue) { create(:issue, project: project) }
let_it_be(:developer) { create(:user) }
let(:current_user) { developer }
describe '.designManagement' do
include DesignManagementTestHelpers
let_it_be(:version) { create(:design_version, issue: issue) }
let_it_be(:design) { version.designs.first }
let(:query_result) { graphql_data.dig(*path) }
let(:query) { graphql_query_for(:design_management, nil, dm_fields) }
before do
enable_design_management
project.add_developer(developer)
post_graphql(query, current_user: current_user)
end
shared_examples 'a query that needs authorization' do
context 'the current user is not able to read designs' do
let(:current_user) { create(:user) }
it 'does not retrieve the record' do
expect(query_result).to be_nil
end
it 'raises an error' do
expect(graphql_errors).to include(
a_hash_including('message' => a_string_matching(%r{you don't have permission}))
)
end
end
end
describe '.version' do
let(:path) { %w[designManagement version] }
let(:dm_fields) do
query_graphql_field(:version, { 'id' => global_id_of(version) }, 'id sha')
end
it_behaves_like 'a working graphql query'
it_behaves_like 'a query that needs authorization'
context 'the current user is able to read designs' do
it 'fetches the expected data' do
expect(query_result).to eq('id' => global_id_of(version), 'sha' => version.sha)
end
end
end
describe '.designAtVersion' do
let_it_be(:design_at_version) do
::DesignManagement::DesignAtVersion.new(design: design, version: version)
end
let(:path) { %w[designManagement designAtVersion] }
let(:dm_fields) do
query_graphql_field(:design_at_version, { 'id' => global_id_of(design_at_version) }, <<~FIELDS)
id
filename
version { id sha }
design { id }
issue { title iid }
project { id fullPath }
FIELDS
end
it_behaves_like 'a working graphql query'
it_behaves_like 'a query that needs authorization'
context 'the current user is able to read designs' do
it 'fetches the expected data, including the correct associations' do
expect(query_result).to eq(
'id' => global_id_of(design_at_version),
'filename' => design_at_version.design.filename,
'version' => { 'id' => global_id_of(version), 'sha' => version.sha },
'design' => { 'id' => global_id_of(design) },
'issue' => { 'title' => issue.title, 'iid' => issue.iid.to_s },
'project' => { 'id' => global_id_of(project), 'fullPath' => project.full_path }
)
end
end
end
end
describe '.vulnerabilitiesCountByDayAndSeverity' do describe '.vulnerabilitiesCountByDayAndSeverity' do
let(:query_result) { graphql_data.dig('vulnerabilitiesCountByDayAndSeverity', 'nodes') } let(:query_result) { graphql_data.dig('vulnerabilitiesCountByDayAndSeverity', 'nodes') }
...@@ -117,8 +29,10 @@ describe 'Query' do ...@@ -117,8 +29,10 @@ describe 'Query' do
it "fetches historical vulnerability data from the start date to the end date for projects on the current user's instance security dashboard" do it "fetches historical vulnerability data from the start date to the end date for projects on the current user's instance security dashboard" do
Timecop.freeze(Time.zone.parse('2019-10-31')) do Timecop.freeze(Time.zone.parse('2019-10-31')) do
project = create(:project)
current_user = create(:user)
current_user.security_dashboard_projects << project current_user.security_dashboard_projects << project
project.add_developer(developer) project.add_developer(current_user)
create(:vulnerability, :critical, created_at: 15.days.ago, dismissed_at: 10.days.ago, project: project) create(:vulnerability, :critical, created_at: 15.days.ago, dismissed_at: 10.days.ago, project: project)
create(:vulnerability, :high, created_at: 15.days.ago, dismissed_at: 11.days.ago, project: project) create(:vulnerability, :high, created_at: 15.days.ago, dismissed_at: 11.days.ago, project: project)
......
...@@ -76,24 +76,6 @@ describe API::Internal::Base do ...@@ -76,24 +76,6 @@ describe API::Internal::Base do
let_it_be(:key) { create(:key, user: user) } let_it_be(:key) { create(:key, user: user) }
let(:secret_token) { Gitlab::Shell.secret_token } let(:secret_token) { Gitlab::Shell.secret_token }
context "for design repositories" do
let_it_be(:project) { create(:project) }
let(:gl_repository) { ::Gitlab::GlRepository::DESIGN.identifier_for_container(project) }
it "does not allow access" do
post(api("/internal/allowed"),
params: {
key_id: key.id,
project: project.full_path,
gl_repository: gl_repository,
secret_token: secret_token,
protocol: 'ssh'
})
expect(response).to have_gitlab_http_status(:unauthorized)
end
end
context "project alias" do context "project alias" do
let(:project) { create(:project, :public, :repository) } let(:project) { create(:project, :public, :repository) }
let(:project_alias) { create(:project_alias, project: project) } let(:project_alias) { create(:project_alias, project: project) }
......
...@@ -26,12 +26,6 @@ describe API::Todos do ...@@ -26,12 +26,6 @@ describe API::Todos do
create(:todo, project: nil, group: new_group, author: author_1, user: user, target: new_epic) create(:todo, project: nil, group: new_group, author: author_1, user: user, target: new_epic)
end end
shared_examples 'an endpoint that responds with success' do
specify do
expect(response).to have_gitlab_http_status(:ok)
end
end
context 'when there is an Epic Todo' do context 'when there is an Epic Todo' do
let!(:epic_todo) { create_todo_for_new_epic } let!(:epic_todo) { create_todo_for_new_epic }
...@@ -39,7 +33,9 @@ describe API::Todos do ...@@ -39,7 +33,9 @@ describe API::Todos do
get api('/todos', personal_access_token: pat) get api('/todos', personal_access_token: pat)
end end
it_behaves_like 'an endpoint that responds with success' specify do
expect(response).to have_gitlab_http_status(:ok)
end
it 'avoids N+1 queries', :request_store do it 'avoids N+1 queries', :request_store do
create_todo_for_new_epic create_todo_for_new_epic
......
...@@ -17,6 +17,14 @@ describe Mutations::DesignManagement::Delete do ...@@ -17,6 +17,14 @@ describe Mutations::DesignManagement::Delete do
let(:mutation) { described_class.new(object: nil, context: { current_user: user }, field: nil) } let(:mutation) { described_class.new(object: nil, context: { current_user: user }, field: nil) }
before do before do
# TODO these tests are being temporarily skipped unless run in EE,
# as we are in the process of moving Design Management to FOSS in 13.0
# in steps. In the current step the services have not yet been moved,
# which are used by this mutation.
#
# See https://gitlab.com/gitlab-org/gitlab/-/issues/212566#note_327724283.
skip 'See https://gitlab.com/gitlab-org/gitlab/-/issues/212566#note_327724283' unless Gitlab.ee?
stub_const('Errors', Gitlab::Graphql::Errors, transfer_nested_constants: true) stub_const('Errors', Gitlab::Graphql::Errors, transfer_nested_constants: true)
end end
......
...@@ -37,6 +37,14 @@ describe Mutations::DesignManagement::Upload do ...@@ -37,6 +37,14 @@ describe Mutations::DesignManagement::Upload do
context "when the feature is available" do context "when the feature is available" do
before do before do
# TODO these tests are being temporarily skipped unless run in EE,
# as we are in the process of moving Design Management to FOSS in 13.0
# in steps. In the current step the services have not yet been moved,
# which are used by this mutation.
#
# See https://gitlab.com/gitlab-org/gitlab/-/issues/212566#note_327724283.
skip 'See https://gitlab.com/gitlab-org/gitlab/-/issues/212566#note_327724283' unless Gitlab.ee?
enable_design_management enable_design_management
end end
......
...@@ -14,7 +14,8 @@ describe GitlabSchema.types['Issue'] do ...@@ -14,7 +14,8 @@ describe GitlabSchema.types['Issue'] do
it 'has specific fields' do it 'has specific fields' do
fields = %i[iid title description state reference author assignees participants labels milestone due_date fields = %i[iid title description state reference author assignees participants labels milestone due_date
confidential discussion_locked upvotes downvotes user_notes_count web_path web_url relative_position confidential discussion_locked upvotes downvotes user_notes_count web_path web_url relative_position
subscribed time_estimate total_time_spent closed_at created_at updated_at task_completion_status] subscribed time_estimate total_time_spent closed_at created_at updated_at task_completion_status
designs design_collection]
fields.each do |field_name| fields.each do |field_name|
expect(described_class).to have_graphql_field(field_name) expect(described_class).to have_graphql_field(field_name)
......
...@@ -8,6 +8,7 @@ describe Types::Notes::NoteableType do ...@@ -8,6 +8,7 @@ describe Types::Notes::NoteableType do
it 'knows the correct type for objects' do it 'knows the correct type for objects' do
expect(described_class.resolve_type(build(:issue), {})).to eq(Types::IssueType) expect(described_class.resolve_type(build(:issue), {})).to eq(Types::IssueType)
expect(described_class.resolve_type(build(:merge_request), {})).to eq(Types::MergeRequestType) expect(described_class.resolve_type(build(:merge_request), {})).to eq(Types::MergeRequestType)
expect(described_class.resolve_type(build(:design), {})).to eq(Types::DesignManagement::DesignType)
end end
end end
end end
...@@ -5,8 +5,9 @@ require 'spec_helper' ...@@ -5,8 +5,9 @@ require 'spec_helper'
describe Types::PermissionTypes::Issue do describe Types::PermissionTypes::Issue do
it do it do
expected_permissions = [ expected_permissions = [
:read_issue, :admin_issue, :update_issue, :read_issue, :admin_issue, :update_issue, :reopen_issue,
:create_note, :reopen_issue :read_design, :create_design, :destroy_design,
:create_note
] ]
expected_permissions.each do |permission| expected_permissions.each do |permission|
......
...@@ -13,7 +13,7 @@ describe Types::PermissionTypes::Project do ...@@ -13,7 +13,7 @@ describe Types::PermissionTypes::Project do
:create_merge_request_from, :create_wiki, :push_code, :create_deployment, :push_to_delete_protected_branch, :create_merge_request_from, :create_wiki, :push_code, :create_deployment, :push_to_delete_protected_branch,
:admin_wiki, :admin_project, :update_pages, :admin_remote_mirror, :create_label, :admin_wiki, :admin_project, :update_pages, :admin_remote_mirror, :create_label,
:update_wiki, :destroy_wiki, :create_pages, :destroy_pages, :read_pages_content, :update_wiki, :destroy_wiki, :create_pages, :destroy_pages, :read_pages_content,
:read_merge_request :read_merge_request, :read_design, :create_design, :destroy_design
] ]
expected_permissions.each do |permission| expected_permissions.each do |permission|
......
...@@ -8,7 +8,7 @@ describe GitlabSchema.types['Query'] do ...@@ -8,7 +8,7 @@ describe GitlabSchema.types['Query'] do
end end
it 'has the expected fields' do it 'has the expected fields' do
expected_fields = %i[project namespace group echo metadata current_user snippets] expected_fields = %i[project namespace group echo metadata current_user snippets design_management]
expect(described_class).to have_graphql_fields(*expected_fields).at_least expect(described_class).to have_graphql_fields(*expected_fields).at_least
end end
......
...@@ -21,16 +21,7 @@ describe Gitlab::GitAccessDesign do ...@@ -21,16 +21,7 @@ describe Gitlab::GitAccessDesign do
end end
context 'when the user is allowed to manage designs' do context 'when the user is allowed to manage designs' do
# TODO This test is being temporarily skipped unless run in EE,
# as we are in the process of moving Design Management to FOSS in 13.0
# in steps. In the current step the policies have not yet been moved
# which means that although the `GitAccessDesign` class has moved, the
# user will always be denied access in FOSS.
#
# See https://gitlab.com/gitlab-org/gitlab/-/issues/212566#note_327724283.
it do it do
skip 'See https://gitlab.com/gitlab-org/gitlab/-/issues/212566#note_327724283' unless Gitlab.ee?
is_expected.to be_a(::Gitlab::GitAccessResult::Success) is_expected.to be_a(::Gitlab::GitAccessResult::Success)
end end
end end
......
...@@ -9,6 +9,7 @@ describe 'Query current user todos' do ...@@ -9,6 +9,7 @@ describe 'Query current user todos' do
let_it_be(:commit_todo) { create(:on_commit_todo, user: current_user, project: create(:project, :repository)) } let_it_be(:commit_todo) { create(:on_commit_todo, user: current_user, project: create(:project, :repository)) }
let_it_be(:issue_todo) { create(:todo, user: current_user, target: create(:issue)) } let_it_be(:issue_todo) { create(:todo, user: current_user, target: create(:issue)) }
let_it_be(:merge_request_todo) { create(:todo, user: current_user, target: create(:merge_request)) } let_it_be(:merge_request_todo) { create(:todo, user: current_user, target: create(:merge_request)) }
let_it_be(:design_todo) { create(:todo, user: current_user, target: create(:design)) }
let(:fields) do let(:fields) do
<<~QUERY <<~QUERY
...@@ -34,7 +35,8 @@ describe 'Query current user todos' do ...@@ -34,7 +35,8 @@ describe 'Query current user todos' do
is_expected.to include( is_expected.to include(
a_hash_including('id' => commit_todo.to_global_id.to_s), a_hash_including('id' => commit_todo.to_global_id.to_s),
a_hash_including('id' => issue_todo.to_global_id.to_s), a_hash_including('id' => issue_todo.to_global_id.to_s),
a_hash_including('id' => merge_request_todo.to_global_id.to_s) a_hash_including('id' => merge_request_todo.to_global_id.to_s),
a_hash_including('id' => design_todo.to_global_id.to_s)
) )
end end
...@@ -42,7 +44,8 @@ describe 'Query current user todos' do ...@@ -42,7 +44,8 @@ describe 'Query current user todos' do
is_expected.to include( is_expected.to include(
a_hash_including('targetType' => 'COMMIT'), a_hash_including('targetType' => 'COMMIT'),
a_hash_including('targetType' => 'ISSUE'), a_hash_including('targetType' => 'ISSUE'),
a_hash_including('targetType' => 'MERGEREQUEST') a_hash_including('targetType' => 'MERGEREQUEST'),
a_hash_including('targetType' => 'DESIGN')
) )
end end
end end
...@@ -29,6 +29,14 @@ describe "deleting designs" do ...@@ -29,6 +29,14 @@ describe "deleting designs" do
end end
before do before do
# TODO these tests are being temporarily skipped unless run in EE,
# as we are in the process of moving Design Management to FOSS in 13.0
# in steps. In the current step the services have not yet been moved,
# which are used by this mutation.
#
# See https://gitlab.com/gitlab-org/gitlab/-/issues/212566#note_327724283.
skip 'See https://gitlab.com/gitlab-org/gitlab/-/issues/212566#note_327724283' unless Gitlab.ee?
enable_design_management enable_design_management
project.add_developer(developer) project.add_developer(developer)
......
...@@ -24,6 +24,14 @@ describe "uploading designs" do ...@@ -24,6 +24,14 @@ describe "uploading designs" do
let(:mutation_response) { graphql_mutation_response(:design_management_upload) } let(:mutation_response) { graphql_mutation_response(:design_management_upload) }
before do before do
# TODO these tests are being temporarily skipped unless run in EE,
# as we are in the process of moving Design Management to FOSS in 13.0
# in steps. In the current step the services have not yet been moved,
# which are used by this mutation.
#
# See https://gitlab.com/gitlab-org/gitlab/-/issues/212566#note_327724283.
skip 'See https://gitlab.com/gitlab-org/gitlab/-/issues/212566#note_327724283' unless Gitlab.ee?
enable_design_management enable_design_management
project.add_developer(current_user) project.add_developer(current_user)
......
...@@ -6,6 +6,16 @@ describe 'Getting designs related to an issue' do ...@@ -6,6 +6,16 @@ describe 'Getting designs related to an issue' do
include GraphqlHelpers include GraphqlHelpers
include DesignManagementTestHelpers include DesignManagementTestHelpers
before_all do
# TODO these tests are being temporarily skipped unless run in EE,
# as we are in the process of moving Design Management to FOSS in 13.0
# in steps. In the current step the services have not yet been moved,
# which are used by the `:with_smaller_image_versions` factory trait.
#
# See https://gitlab.com/gitlab-org/gitlab/-/issues/212566#note_327724283.
skip 'See https://gitlab.com/gitlab-org/gitlab/-/issues/212566#note_327724283' unless Gitlab.ee?
end
let_it_be(:design) { create(:design, :with_smaller_image_versions, versions_count: 1) } let_it_be(:design) { create(:design, :with_smaller_image_versions, versions_count: 1) }
let_it_be(:current_user) { design.project.owner } let_it_be(:current_user) { design.project.owner }
let(:design_query) do let(:design_query) do
......
# frozen_string_literal: true
require 'spec_helper'
describe 'Query' do
include GraphqlHelpers
let_it_be(:project) { create(:project) }
let_it_be(:issue) { create(:issue, project: project) }
let_it_be(:developer) { create(:user) }
let(:current_user) { developer }
describe '.designManagement' do
include DesignManagementTestHelpers
let_it_be(:version) { create(:design_version, issue: issue) }
let_it_be(:design) { version.designs.first }
let(:query_result) { graphql_data.dig(*path) }
let(:query) { graphql_query_for(:design_management, nil, dm_fields) }
before do
enable_design_management
project.add_developer(developer)
post_graphql(query, current_user: current_user)
end
shared_examples 'a query that needs authorization' do
context 'the current user is not able to read designs' do
let(:current_user) { create(:user) }
it 'does not retrieve the record' do
expect(query_result).to be_nil
end
it 'raises an error' do
expect(graphql_errors).to include(
a_hash_including('message' => a_string_matching(%r{you don't have permission}))
)
end
end
end
describe '.version' do
let(:path) { %w[designManagement version] }
let(:dm_fields) do
query_graphql_field(:version, { 'id' => global_id_of(version) }, 'id sha')
end
it_behaves_like 'a working graphql query'
it_behaves_like 'a query that needs authorization'
context 'the current user is able to read designs' do
it 'fetches the expected data' do
expect(query_result).to eq('id' => global_id_of(version), 'sha' => version.sha)
end
end
end
describe '.designAtVersion' do
let_it_be(:design_at_version) do
::DesignManagement::DesignAtVersion.new(design: design, version: version)
end
let(:path) { %w[designManagement designAtVersion] }
let(:dm_fields) do
query_graphql_field(:design_at_version, { 'id' => global_id_of(design_at_version) }, <<~FIELDS)
id
filename
version { id sha }
design { id }
issue { title iid }
project { id fullPath }
FIELDS
end
it_behaves_like 'a working graphql query'
it_behaves_like 'a query that needs authorization'
context 'the current user is able to read designs' do
it 'fetches the expected data, including the correct associations' do
expect(query_result).to eq(
'id' => global_id_of(design_at_version),
'filename' => design_at_version.design.filename,
'version' => { 'id' => global_id_of(version), 'sha' => version.sha },
'design' => { 'id' => global_id_of(design) },
'issue' => { 'title' => issue.title, 'iid' => issue.iid.to_s },
'project' => { 'id' => global_id_of(project), 'fullPath' => project.full_path }
)
end
end
end
end
end
...@@ -917,6 +917,23 @@ describe API::Internal::Base do ...@@ -917,6 +917,23 @@ describe API::Internal::Base do
expect(json_response['status']).to be_falsy expect(json_response['status']).to be_falsy
end end
end end
context 'for design repositories' do
let(:gl_repository) { Gitlab::GlRepository::DESIGN.identifier_for_container(project) }
it 'does not allow access' do
post(api('/internal/allowed'),
params: {
key_id: key.id,
project: project.full_path,
gl_repository: gl_repository,
secret_token: secret_token,
protocol: 'ssh'
})
expect(response).to have_gitlab_http_status(:unauthorized)
end
end
end end
describe 'POST /internal/post_receive', :clean_gitlab_redis_shared_state do describe 'POST /internal/post_receive', :clean_gitlab_redis_shared_state do
......
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