Commit 4d743255 authored by Luke Duncalfe's avatar Luke Duncalfe

Move Design Management-related model code to 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 model code that references parts of Design Management. The
"core" Design Management model code has been moved in
https://gitlab.com/gitlab-org/gitlab/-/merge_requests/30015.
parent fcba9ed7
...@@ -17,7 +17,7 @@ module Noteable ...@@ -17,7 +17,7 @@ module Noteable
# `Noteable` class names that support resolvable notes. # `Noteable` class names that support resolvable notes.
def resolvable_types def resolvable_types
%w(MergeRequest) %w(MergeRequest DesignManagement::Design)
end end
end end
...@@ -138,6 +138,8 @@ module Noteable ...@@ -138,6 +138,8 @@ module Noteable
end end
def note_etag_key def note_etag_key
return Gitlab::Routing.url_helpers.designs_project_issue_path(project, issue, { vueroute: filename }) if self.is_a?(DesignManagement::Design)
Gitlab::Routing.url_helpers.project_noteable_notes_path( Gitlab::Routing.url_helpers.project_noteable_notes_path(
project, project,
target_type: self.class.name.underscore, target_type: self.class.name.underscore,
......
...@@ -313,6 +313,10 @@ class Event < ApplicationRecord ...@@ -313,6 +313,10 @@ class Event < ApplicationRecord
note? && target && target.for_personal_snippet? note? && target && target.for_personal_snippet?
end end
def design_note?
note? && note.for_design?
end
def note_target def note_target
target.noteable target.noteable
end end
...@@ -380,6 +384,11 @@ class Event < ApplicationRecord ...@@ -380,6 +384,11 @@ class Event < ApplicationRecord
protected protected
# rubocop:disable Metrics/CyclomaticComplexity
# rubocop:disable Metrics/PerceivedComplexity
#
# TODO Refactor this method so we no longer need to disable the above cops
# https://gitlab.com/gitlab-org/gitlab/-/issues/216879.
def capability def capability
@capability ||= begin @capability ||= begin
if push_action? || commit_note? if push_action? || commit_note?
...@@ -396,9 +405,13 @@ class Event < ApplicationRecord ...@@ -396,9 +405,13 @@ class Event < ApplicationRecord
:read_milestone :read_milestone
elsif wiki_page? elsif wiki_page?
:read_wiki :read_wiki
elsif design_note?
:read_design
end end
end end
end end
# rubocop:enable Metrics/CyclomaticComplexity
# rubocop:enable Metrics/PerceivedComplexity
private private
......
...@@ -1438,6 +1438,7 @@ class Project < ApplicationRecord ...@@ -1438,6 +1438,7 @@ class Project < ApplicationRecord
def expire_caches_before_rename(old_path) def expire_caches_before_rename(old_path)
repo = Repository.new(old_path, self, shard: repository_storage) repo = Repository.new(old_path, self, shard: repository_storage)
wiki = Repository.new("#{old_path}.wiki", self, shard: repository_storage, repo_type: Gitlab::GlRepository::WIKI) wiki = Repository.new("#{old_path}.wiki", self, shard: repository_storage, repo_type: Gitlab::GlRepository::WIKI)
design = Repository.new("#{old_path}#{Gitlab::GlRepository::DESIGN.path_suffix}", self, shard: repository_storage, repo_type: Gitlab::GlRepository::DESIGN)
if repo.exists? if repo.exists?
repo.before_delete repo.before_delete
...@@ -1446,6 +1447,10 @@ class Project < ApplicationRecord ...@@ -1446,6 +1447,10 @@ class Project < ApplicationRecord
if wiki.exists? if wiki.exists?
wiki.before_delete wiki.before_delete
end end
if design.exists?
design.before_delete
end
end end
# Check if repository already exists on disk # Check if repository already exists on disk
......
...@@ -15,6 +15,7 @@ class SystemNoteMetadata < ApplicationRecord ...@@ -15,6 +15,7 @@ class SystemNoteMetadata < ApplicationRecord
ICON_TYPES = %w[ ICON_TYPES = %w[
commit description merge confidential visible label assignee cross_reference commit description merge confidential visible label assignee cross_reference
designs_added designs_modified designs_removed designs_discussion_added
title time_tracking branch milestone discussion task moved title time_tracking branch milestone discussion task moved
opened closed merged duplicate locked unlocked outdated opened closed merged duplicate locked unlocked outdated
tag due_date pinned_embed cherry_pick health_status tag due_date pinned_embed cherry_pick health_status
......
...@@ -183,6 +183,10 @@ class Todo < ApplicationRecord ...@@ -183,6 +183,10 @@ class Todo < ApplicationRecord
target_type == "Commit" target_type == "Commit"
end end
def for_design?
target_type == DesignManagement::Design.name
end
# override to return commits, which are not active record # override to return commits, which are not active record
def target def target
if for_commit? if for_commit?
......
...@@ -11,10 +11,6 @@ module EE ...@@ -11,10 +11,6 @@ module EE
def replyable_types def replyable_types
super + %w[Epic Vulnerability] super + %w[Epic Vulnerability]
end end
def resolvable_types
super + %w(DesignManagement::Design)
end
end end
override :note_etag_key override :note_etag_key
...@@ -24,8 +20,6 @@ module EE ...@@ -24,8 +20,6 @@ module EE
::Gitlab::Routing.url_helpers.group_epic_notes_path(group, self) ::Gitlab::Routing.url_helpers.group_epic_notes_path(group, self)
when Vulnerability when Vulnerability
::Gitlab::Routing.url_helpers.project_security_vulnerability_notes_path(project, self) ::Gitlab::Routing.url_helpers.project_security_vulnerability_notes_path(project, self)
when DesignManagement::Design
::Gitlab::Routing.url_helpers.designs_project_issue_path(project, issue, { vueroute: filename })
else else
super super
end end
......
...@@ -23,18 +23,12 @@ module EE ...@@ -23,18 +23,12 @@ module EE
@capability ||= begin @capability ||= begin
if epic? || epic_note? if epic? || epic_note?
:read_epic :read_epic
elsif design_note?
:read_design
else else
super super
end end
end end
end end
def design_note?
note? && note.for_design?
end
def epic_note? def epic_note?
note? && note_target.is_a?(::Epic) note? && note_target.is_a?(::Epic)
end end
......
...@@ -655,17 +655,6 @@ module EE ...@@ -655,17 +655,6 @@ module EE
super.presence || build_feature_usage super.presence || build_feature_usage
end end
override(:expire_caches_before_rename)
def expire_caches_before_rename(old_path)
super
design = ::Repository.new("#{old_path}#{::Gitlab::GlRepository::DESIGN.path_suffix}", self, shard: repository_storage, repo_type: ::Gitlab::GlRepository::DESIGN)
if design.exists?
design.before_delete
end
end
def package_already_taken?(package_name) def package_already_taken?(package_name)
namespace.root_ancestor.all_projects namespace.root_ancestor.all_projects
.joins(:packages) .joins(:packages)
......
...@@ -8,7 +8,6 @@ module EE ...@@ -8,7 +8,6 @@ module EE
weight approved unapproved relate unrelate published weight approved unapproved relate unrelate published
epic_issue_added issue_added_to_epic epic_issue_removed issue_removed_from_epic epic_issue_added issue_added_to_epic epic_issue_removed issue_removed_from_epic
epic_issue_moved issue_changed_epic epic_date_changed relate_epic unrelate_epic epic_issue_moved issue_changed_epic epic_date_changed relate_epic unrelate_epic
designs_added designs_modified designs_removed designs_discussion_added
vulnerability_confirmed vulnerability_dismissed vulnerability_resolved vulnerability_confirmed vulnerability_dismissed vulnerability_resolved
].freeze ].freeze
......
...@@ -13,9 +13,5 @@ module EE ...@@ -13,9 +13,5 @@ module EE
def resource_parent def resource_parent
project || group project || group
end end
def for_design?
target_type == DesignManagement::Design.name
end
end end
end end
...@@ -14,10 +14,4 @@ describe EE::Noteable do ...@@ -14,10 +14,4 @@ describe EE::Noteable do
expect(klazz.replyable_types).to include("Vulnerability") expect(klazz.replyable_types).to include("Vulnerability")
end end
end end
describe '.resolvable_types' do
it 'includes design management' do
expect(klazz.resolvable_types).to include('DesignManagement::Design')
end
end
end end
...@@ -76,41 +76,6 @@ describe Event do ...@@ -76,41 +76,6 @@ describe Event do
end end
end end
context 'design event' do
include DesignManagementTestHelpers
before do
enable_design_management
end
it_behaves_like 'visible to group members only' do
let(:event) { create(:event, :for_design, project: project) }
end
context 'the event refers to a design on a confidential issue' do
let(:project) { create(:project, :public) }
let(:issue) { create(:issue, :confidential, project: project) }
let(:note) { create(:note, :on_design, issue: issue) }
let(:event) { create(:event, project: project, target: note) }
let(:assignees) do
create_list(:user, 3).each { |user| issue.assignees << user }
end
it 'visible to group reporters, the issue author, and assignees', :aggregate_failures do
expect(event).not_to be_visible_to(non_member)
expect(event).not_to be_visible_to(guest)
expect(event).to be_visible_to(reporter)
expect(event).to be_visible_to(member)
expect(event).to be_visible_to(admin)
expect(event).to be_visible_to(issue.author)
expect(assignees).to all(have_access_to(event))
end
end
end
context 'epic event' do context 'epic event' do
let(:target) { epic } let(:target) { epic }
......
...@@ -4,7 +4,6 @@ require 'spec_helper' ...@@ -4,7 +4,6 @@ require 'spec_helper'
describe EE::SystemNoteMetadata do describe EE::SystemNoteMetadata do
%i[ %i[
designs_added designs_modified designs_removed
vulnerability_confirmed vulnerability_dismissed vulnerability_resolved vulnerability_confirmed vulnerability_dismissed vulnerability_resolved
].each do |action| ].each do |action|
context 'when action type is valid' do context 'when action type is valid' do
......
# frozen_string_literal: true
require 'spec_helper'
describe Todo do
describe '#for_design?' do
it 'returns true when target is a Design' do
todo = build(:todo, target: build(:design))
expect(todo.for_design?).to eq(true)
end
it 'returns false when target is not a Design' do
todo = build(:todo)
expect(todo.for_design?).to eq(false)
end
end
end
...@@ -2524,31 +2524,6 @@ describe Project do ...@@ -2524,31 +2524,6 @@ describe Project do
it { expect(subject.license_compliance).to be_instance_of(::SCA::LicenseCompliance) } it { expect(subject.license_compliance).to be_instance_of(::SCA::LicenseCompliance) }
end end
describe '#expire_caches_before_rename' do
let(:project) { create(:project, :repository) }
let(:repo) { double(:repo, exists?: true, before_delete: true) }
let(:wiki) { double(:wiki, exists?: true, before_delete: true) }
let(:design) { double(:design, exists?: true) }
it 'expires the caches of the design repository' do
allow(Repository).to receive(:new)
.with('foo', project, shard: project.repository_storage)
.and_return(repo)
allow(Repository).to receive(:new)
.with('foo.wiki', project, shard: project.repository_storage, repo_type: Gitlab::GlRepository::WIKI)
.and_return(wiki)
allow(Repository).to receive(:new)
.with('foo.design', project, shard: project.repository_storage, repo_type: ::Gitlab::GlRepository::DESIGN)
.and_return(design)
expect(design).to receive(:before_delete)
project.expire_caches_before_rename('foo')
end
end
describe '#template_source?' do describe '#template_source?' do
let_it_be(:group) { create(:group, :private) } let_it_be(:group) { create(:group, :private) }
let_it_be(:subgroup) { create(:group, :private, parent: group) } let_it_be(:subgroup) { create(:group, :private, parent: group) }
......
...@@ -16,6 +16,7 @@ FactoryBot.define do ...@@ -16,6 +16,7 @@ FactoryBot.define do
factory :note_on_merge_request, traits: [:on_merge_request] factory :note_on_merge_request, traits: [:on_merge_request]
factory :note_on_project_snippet, traits: [:on_project_snippet] factory :note_on_project_snippet, traits: [:on_project_snippet]
factory :note_on_personal_snippet, traits: [:on_personal_snippet] factory :note_on_personal_snippet, traits: [:on_personal_snippet]
factory :note_on_design, traits: [:on_design]
factory :system_note, traits: [:system] factory :system_note, traits: [:system]
factory :discussion_note, class: 'DiscussionNote' factory :discussion_note, class: 'DiscussionNote'
......
...@@ -241,7 +241,7 @@ describe Noteable do ...@@ -241,7 +241,7 @@ describe Noteable do
describe '.resolvable_types' do describe '.resolvable_types' do
it 'exposes the replyable types' do it 'exposes the replyable types' do
expect(described_class.resolvable_types).to include('MergeRequest') expect(described_class.resolvable_types).to include('MergeRequest', 'DesignManagement::Design')
end end
end end
......
...@@ -195,11 +195,13 @@ describe Event do ...@@ -195,11 +195,13 @@ describe Event do
let(:confidential_issue) { create(:issue, :confidential, project: project, author: author, assignees: [assignee]) } let(:confidential_issue) { create(:issue, :confidential, project: project, author: author, assignees: [assignee]) }
let(:project_snippet) { create(:project_snippet, :public, project: project, author: author) } let(:project_snippet) { create(:project_snippet, :public, project: project, author: author) }
let(:personal_snippet) { create(:personal_snippet, :public, author: author) } let(:personal_snippet) { create(:personal_snippet, :public, author: author) }
let(:design) { create(:design, issue: issue, project: project) }
let(:note_on_commit) { create(:note_on_commit, project: project) } let(:note_on_commit) { create(:note_on_commit, project: project) }
let(:note_on_issue) { create(:note_on_issue, noteable: issue, project: project) } let(:note_on_issue) { create(:note_on_issue, noteable: issue, project: project) }
let(:note_on_confidential_issue) { create(:note_on_issue, noteable: confidential_issue, project: project) } let(:note_on_confidential_issue) { create(:note_on_issue, noteable: confidential_issue, project: project) }
let(:note_on_project_snippet) { create(:note_on_project_snippet, author: author, noteable: project_snippet, project: project) } let(:note_on_project_snippet) { create(:note_on_project_snippet, author: author, noteable: project_snippet, project: project) }
let(:note_on_personal_snippet) { create(:note_on_personal_snippet, author: author, noteable: personal_snippet, project: nil) } let(:note_on_personal_snippet) { create(:note_on_personal_snippet, author: author, noteable: personal_snippet, project: nil) }
let(:note_on_design) { create(:note_on_design, author: author, noteable: design, project: project) }
let(:milestone_on_project) { create(:milestone, project: project) } let(:milestone_on_project) { create(:milestone, project: project) }
let(:event) do let(:event) do
described_class.new(project: project, described_class.new(project: project,
...@@ -452,6 +454,32 @@ describe Event do ...@@ -452,6 +454,32 @@ describe Event do
include_examples 'visible to author', true include_examples 'visible to author', true
end end
end end
context 'design event' do
include DesignManagementTestHelpers
let(:target) { note_on_design }
before do
enable_design_management
end
include_examples 'visibility examples' do
let(:visibility) { visible_to_all }
end
include_examples 'visible to assignee and author', true
context 'the event refers to a design on a confidential issue' do
let(:design) { create(:design, issue: confidential_issue, project: project) }
include_examples 'visibility examples' do
let(:visibility) { visible_to_none_except(:member, :admin) }
end
include_examples 'visible to assignee and author', true
end
end
end end
describe 'wiki_page predicate scopes' do describe 'wiki_page predicate scopes' do
......
...@@ -1780,6 +1780,7 @@ describe Project do ...@@ -1780,6 +1780,7 @@ describe Project do
let(:project) { create(:project, :repository) } let(:project) { create(:project, :repository) }
let(:repo) { double(:repo, exists?: true) } let(:repo) { double(:repo, exists?: true) }
let(:wiki) { double(:wiki, exists?: true) } let(:wiki) { double(:wiki, exists?: true) }
let(:design) { double(:design, exists?: true) }
it 'expires the caches of the repository and wiki' do it 'expires the caches of the repository and wiki' do
# In EE, there are design repositories as well # In EE, there are design repositories as well
...@@ -1793,8 +1794,13 @@ describe Project do ...@@ -1793,8 +1794,13 @@ describe Project do
.with('foo.wiki', project, shard: project.repository_storage, repo_type: Gitlab::GlRepository::WIKI) .with('foo.wiki', project, shard: project.repository_storage, repo_type: Gitlab::GlRepository::WIKI)
.and_return(wiki) .and_return(wiki)
allow(Repository).to receive(:new)
.with('foo.design', project, shard: project.repository_storage, repo_type: Gitlab::GlRepository::DESIGN)
.and_return(design)
expect(repo).to receive(:before_delete) expect(repo).to receive(:before_delete)
expect(wiki).to receive(:before_delete) expect(wiki).to receive(:before_delete)
expect(design).to receive(:before_delete)
project.expire_caches_before_rename('foo') project.expire_caches_before_rename('foo')
end end
......
...@@ -61,11 +61,13 @@ describe Todo do ...@@ -61,11 +61,13 @@ describe Todo do
describe '#done' do describe '#done' do
it 'changes state to done' do it 'changes state to done' do
todo = create(:todo, state: :pending) todo = create(:todo, state: :pending)
expect { todo.done }.to change(todo, :state).from('pending').to('done') expect { todo.done }.to change(todo, :state).from('pending').to('done')
end end
it 'does not raise error when is already done' do it 'does not raise error when is already done' do
todo = create(:todo, state: :done) todo = create(:todo, state: :done)
expect { todo.done }.not_to raise_error expect { todo.done }.not_to raise_error
end end
end end
...@@ -73,15 +75,31 @@ describe Todo do ...@@ -73,15 +75,31 @@ describe Todo do
describe '#for_commit?' do describe '#for_commit?' do
it 'returns true when target is a commit' do it 'returns true when target is a commit' do
subject.target_type = 'Commit' subject.target_type = 'Commit'
expect(subject.for_commit?).to eq true expect(subject.for_commit?).to eq true
end end
it 'returns false when target is an issuable' do it 'returns false when target is an issuable' do
subject.target_type = 'Issue' subject.target_type = 'Issue'
expect(subject.for_commit?).to eq false expect(subject.for_commit?).to eq false
end end
end end
describe '#for_design?' do
it 'returns true when target is a Design' do
subject.target_type = 'DesignManagement::Design'
expect(subject.for_design?).to eq(true)
end
it 'returns false when target is not a Design' do
subject.target_type = 'Issue'
expect(subject.for_design?).to eq(false)
end
end
describe '#target' do describe '#target' do
context 'for commits' do context 'for commits' do
let(:project) { create(:project, :repository) } let(:project) { create(:project, :repository) }
...@@ -108,6 +126,7 @@ describe Todo do ...@@ -108,6 +126,7 @@ describe Todo do
it 'returns the issuable for issuables' do it 'returns the issuable for issuables' do
subject.target_id = issue.id subject.target_id = issue.id
subject.target_type = issue.class.name subject.target_type = issue.class.name
expect(subject.target).to eq issue expect(subject.target).to eq issue
end end
end end
...@@ -126,6 +145,7 @@ describe Todo do ...@@ -126,6 +145,7 @@ describe Todo do
it 'returns full reference for issuables' do it 'returns full reference for issuables' do
subject.target = issue subject.target = issue
expect(subject.target_reference).to eq issue.to_reference(full: false) expect(subject.target_reference).to eq issue.to_reference(full: false)
end end
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