summaryrefslogtreecommitdiff
path: root/spec/models/design_management
diff options
context:
space:
mode:
Diffstat (limited to 'spec/models/design_management')
-rw-r--r--spec/models/design_management/design_at_version_spec.rb9
-rw-r--r--spec/models/design_management/design_collection_spec.rb9
-rw-r--r--spec/models/design_management/design_spec.rb134
3 files changed, 106 insertions, 46 deletions
diff --git a/spec/models/design_management/design_at_version_spec.rb b/spec/models/design_management/design_at_version_spec.rb
index 2c640ee5c2c..3c1ff45c53f 100644
--- a/spec/models/design_management/design_at_version_spec.rb
+++ b/spec/models/design_management/design_at_version_spec.rb
@@ -78,18 +78,23 @@ RSpec.describe DesignManagement::DesignAtVersion do
let!(:version_a) do
create(:design_version, designs: [design_a])
end
+
let!(:version_b) do
create(:design_version, designs: [design_b])
end
+
let!(:version_mod) do
create(:design_version, modified_designs: [design_a, design_b])
end
+
let!(:version_c) do
create(:design_version, deleted_designs: [design_a])
end
+
let!(:version_d) do
create(:design_version, deleted_designs: [design_b])
end
+
let!(:version_e) do
create(:design_version, designs: [design_a])
end
@@ -296,9 +301,11 @@ RSpec.describe DesignManagement::DesignAtVersion do
let!(:version_a) do
create(:design_version, designs: create_list(:design, 3, issue: issue))
end
+
let!(:version_b) do
create(:design_version, designs: create_list(:design, 1, issue: issue))
end
+
let!(:version_c) do
create(:design_version, designs: create_list(:design, 1, issue: issue_b))
end
@@ -346,10 +353,12 @@ RSpec.describe DesignManagement::DesignAtVersion do
let!(:version_a) do
create(:design_version, designs: create_list(:design, 3, issue: issue))
end
+
let!(:version_b) do
create(:design_version, designs: create_list(:design, 2, issue: issue))
end
# 1 version, with 3 designs on issue B, so 1*3 = 3
+
let!(:version_c) do
create(:design_version, designs: create_list(:design, 3, issue: issue_b))
end
diff --git a/spec/models/design_management/design_collection_spec.rb b/spec/models/design_management/design_collection_spec.rb
index c5e290da759..de766d5ce09 100644
--- a/spec/models/design_management/design_collection_spec.rb
+++ b/spec/models/design_management/design_collection_spec.rb
@@ -34,6 +34,15 @@ RSpec.describe DesignManagement::DesignCollection do
collection.find_or_create_design!(filename: 'world.jpg')
end.not_to exceed_query_limit(1)
end
+
+ it 'inserts the design after any existing designs' do
+ design1 = collection.find_or_create_design!(filename: 'design1.jpg')
+ design1.update!(relative_position: 100)
+
+ design2 = collection.find_or_create_design!(filename: 'design2.jpg')
+
+ expect(collection.designs.ordered(issue.project)).to eq([design1, design2])
+ end
end
describe "#versions" do
diff --git a/spec/models/design_management/design_spec.rb b/spec/models/design_management/design_spec.rb
index 345147390c0..2c129f883b9 100644
--- a/spec/models/design_management/design_spec.rb
+++ b/spec/models/design_management/design_spec.rb
@@ -11,6 +11,11 @@ RSpec.describe DesignManagement::Design do
let_it_be(:design3) { create(:design, :with_versions, issue: issue, versions_count: 1) }
let_it_be(:deleted_design) { create(:design, :with_versions, deleted: true) }
+ it_behaves_like 'a class that supports relative positioning' do
+ let(:factory) { :design }
+ let(:default_params) { { issue: issue } }
+ end
+
describe 'relations' do
it { is_expected.to belong_to(:project) }
it { is_expected.to belong_to(:issue) }
@@ -21,7 +26,7 @@ RSpec.describe DesignManagement::Design do
end
describe 'validations' do
- subject(:design) { build(:design) }
+ subject(:design) { build(:design, issue: issue) }
it { is_expected.to be_valid }
it { is_expected.to validate_presence_of(:project) }
@@ -147,6 +152,45 @@ RSpec.describe DesignManagement::Design do
end
end
+ describe '.ordered' do
+ before_all do
+ design1.update!(relative_position: 2)
+ design2.update!(relative_position: 1)
+ design3.update!(relative_position: nil)
+ deleted_design.update!(relative_position: nil)
+ end
+
+ it 'sorts by relative position and ID in ascending order' do
+ expect(described_class.ordered(issue.project)).to eq([design2, design1, design3, deleted_design])
+ end
+
+ context 'when the :reorder_designs feature is enabled for the project' do
+ before do
+ stub_feature_flags(reorder_designs: issue.project)
+ end
+
+ it 'sorts by relative position and ID in ascending order' do
+ expect(described_class.ordered(issue.project)).to eq([design2, design1, design3, deleted_design])
+ end
+ end
+
+ context 'when the :reorder_designs feature is disabled' do
+ before do
+ stub_feature_flags(reorder_designs: false)
+ end
+
+ it 'sorts by ID in ascending order' do
+ expect(described_class.ordered(issue.project)).to eq([design1, design2, design3, deleted_design])
+ end
+ end
+ end
+
+ describe '.in_creation_order' do
+ it 'sorts by ID in ascending order' do
+ expect(described_class.in_creation_order).to eq([design1, design2, design3, deleted_design])
+ end
+ end
+
describe '.with_filename' do
it 'returns correct design when passed a single filename' do
expect(described_class.with_filename(design1.filename)).to eq([design1])
@@ -181,7 +225,7 @@ RSpec.describe DesignManagement::Design do
end
describe '#visible_in?' do
- let_it_be(:issue) { create(:issue) }
+ let_it_be(:issue) { create(:issue, project: issue.project) }
# It is expensive to re-create complex histories, so we do it once, and then
# assert that we can establish visibility at any given version.
@@ -237,7 +281,7 @@ RSpec.describe DesignManagement::Design do
describe '#status' do
context 'the design is new' do
- subject { build(:design) }
+ subject { build(:design, issue: issue) }
it { is_expected.to have_attributes(status: :new) }
end
@@ -257,7 +301,7 @@ RSpec.describe DesignManagement::Design do
describe '#deleted?' do
context 'the design is new' do
- let(:design) { build(:design) }
+ let(:design) { build(:design, issue: issue) }
it 'is falsy' do
expect(design).not_to be_deleted
@@ -281,7 +325,7 @@ RSpec.describe DesignManagement::Design do
end
context 'the design has been deleted, but was then re-created' do
- let(:design) { create(:design, :with_versions, versions_count: 1, deleted: true) }
+ let(:design) { create(:design, :with_versions, issue: issue, versions_count: 1, deleted: true) }
it 'is falsy' do
restore_designs(design)
@@ -299,7 +343,7 @@ RSpec.describe DesignManagement::Design do
end
it "is true when there are no versions" do
- expect(build(:design)).to be_new_design
+ expect(build(:design, issue: issue)).to be_new_design
end
it 'is false for deleted designs' do
@@ -336,7 +380,7 @@ RSpec.describe DesignManagement::Design do
describe "#full_path" do
it "builds the full path for a design" do
- design = build(:design, filename: "hello.jpg")
+ design = build(:design, issue: issue, filename: "hello.jpg")
expected_path = "#{DesignManagement.designs_directory}/issue-#{design.issue.iid}/hello.jpg"
expect(design.full_path).to eq(expected_path)
@@ -359,15 +403,13 @@ RSpec.describe DesignManagement::Design do
let(:versions_count) { 1 }
it 'builds diff refs based on the empty tree if there was only one version' do
- design = create(:design, :with_file, versions_count: 1)
-
expect(design.diff_refs.base_sha).to eq(Gitlab::Git::BLANK_SHA)
expect(design.diff_refs.head_sha).to eq(design.diff_refs.head_sha)
end
end
it 'has no diff ref if new' do
- design = build(:design)
+ design = build(:design, issue: issue)
expect(design.diff_refs).to be_nil
end
@@ -375,7 +417,7 @@ RSpec.describe DesignManagement::Design do
describe '#repository' do
it 'is a design repository' do
- design = build(:design)
+ design = build(:design, issue: issue)
expect(design.repository).to be_a(DesignManagement::Repository)
end
@@ -383,7 +425,7 @@ RSpec.describe DesignManagement::Design do
describe '#note_etag_key' do
it 'returns a correct etag key' do
- design = create(:design)
+ design = design1
expect(design.note_etag_key).to eq(
::Gitlab::Routing.url_helpers.designs_project_issue_path(design.project, design.issue, { vueroute: design.filename })
@@ -392,47 +434,26 @@ RSpec.describe DesignManagement::Design do
end
describe '#user_notes_count', :use_clean_rails_memory_store_caching do
- let_it_be(:design) { create(:design, :with_file) }
-
- subject { design.user_notes_count }
-
# Note: Cache invalidation tests are in `design_user_notes_count_service_spec.rb`
-
it 'returns a count of user-generated notes' do
- create(:diff_note_on_design, noteable: design)
-
- is_expected.to eq(1)
- end
-
- it 'does not count notes on other designs' do
- second_design = create(:design, :with_file)
- create(:diff_note_on_design, noteable: second_design)
+ common_attrs = { issue: issue, project: issue.project, author: issue.project.creator }
+ design, second_design = create_list(:design, 2, :with_file, issue: issue)
+ create(:diff_note_on_design, **common_attrs, noteable: design)
+ create(:diff_note_on_design, **common_attrs, system: true, noteable: design)
+ create(:diff_note_on_design, **common_attrs, noteable: second_design)
- is_expected.to eq(0)
- end
-
- it 'does not count system notes' do
- create(:diff_note_on_design, system: true, noteable: design)
-
- is_expected.to eq(0)
+ expect(design.user_notes_count).to eq(1)
end
end
describe '#after_note_changed' do
- subject { build(:design) }
+ it 'calls #delete_cache on DesignUserNotesCountService for non-system notes' do
+ design = design1
- it 'calls #delete_cache on DesignUserNotesCountService' do
- expect_next_instance_of(DesignManagement::DesignUserNotesCountService) do |service|
- expect(service).to receive(:delete_cache)
- end
+ expect(design.send(:user_notes_count_service)).to receive(:delete_cache).once
- subject.after_note_changed(build(:note))
- end
-
- it 'does not call #delete_cache on DesignUserNotesCountService when passed a system note' do
- expect(DesignManagement::DesignUserNotesCountService).not_to receive(:new)
-
- subject.after_note_changed(build(:note, :system))
+ design.after_note_changed(build(:note, project: issue.project))
+ design.after_note_changed(build(:note, :system, project: issue.project))
end
end
@@ -516,14 +537,14 @@ RSpec.describe DesignManagement::Design do
with_them do
let(:filename) { "my-file.#{ext}" }
- let(:design) { build(:design, filename: filename) }
+ let(:design) { build(:design, issue: issue, filename: filename) }
let(:url) { url_for_design(design) }
let(:captures) { described_class.link_reference_pattern.match(url)&.named_captures }
it 'matches the URL' do
expect(captures).to include(
'url_filename' => filename,
- 'issue' => design.issue.iid.to_s,
+ 'issue' => issue.iid.to_s,
'namespace' => design.project.namespace.to_param,
'project' => design.project.name
)
@@ -565,4 +586,25 @@ RSpec.describe DesignManagement::Design do
end
end
end
+
+ describe '#immediately_before' do
+ let_it_be(:design) { create(:design, issue: issue, relative_position: 100) }
+ let_it_be(:next_design) { create(:design, issue: issue, relative_position: 200) }
+
+ it 'is true when there is no element positioned between this item and the next' do
+ expect(design.immediately_before?(next_design)).to be true
+ end
+
+ it 'is false when there is an element positioned between this item and the next' do
+ create(:design, issue: issue, relative_position: 150)
+
+ expect(design.immediately_before?(next_design)).to be false
+ end
+
+ it 'is false when the next design is to the left of this design' do
+ further_left = create(:design, issue: issue, relative_position: 50)
+
+ expect(design.immediately_before?(further_left)).to be false
+ end
+ end
end