Commit db812b5b authored by Douglas Barbosa Alexandre's avatar Douglas Barbosa Alexandre

Merge branch 'fix-move-null-designs' into 'master'

Use correct order when repositioning existing designs

See merge request gitlab-org/gitlab!39826
parents 3420cef1 de68b422
...@@ -137,9 +137,10 @@ module RelativePositioning ...@@ -137,9 +137,10 @@ module RelativePositioning
# If `true`, then all objects with `null` positions are placed _after_ # If `true`, then all objects with `null` positions are placed _after_
# all siblings with positions. If `false`, all objects with `null` # all siblings with positions. If `false`, all objects with `null`
# positions are placed _before_ all siblings with positions. # positions are placed _before_ all siblings with positions.
# @returns [Number] The number of moved records.
def move_nulls(objects, at_end:) def move_nulls(objects, at_end:)
objects = objects.reject(&:relative_position) objects = objects.reject(&:relative_position)
return if objects.empty? return 0 if objects.empty?
representative = objects.first representative = objects.first
number_of_gaps = objects.size + 1 # 1 at left, one between each, and one at right number_of_gaps = objects.size + 1 # 1 at left, one between each, and one at right
...@@ -186,6 +187,8 @@ module RelativePositioning ...@@ -186,6 +187,8 @@ module RelativePositioning
end end
end end
end end
objects.size
end end
end end
......
...@@ -87,10 +87,12 @@ module DesignManagement ...@@ -87,10 +87,12 @@ module DesignManagement
# See https://gitlab.com/gitlab-org/gitlab/-/merge_requests/17788/diffs#note_230875678 # See https://gitlab.com/gitlab-org/gitlab/-/merge_requests/17788/diffs#note_230875678
order(:relative_position, :id) order(:relative_position, :id)
else else
order(:id) in_creation_order
end end
end end
scope :in_creation_order, -> { reorder(:id) }
scope :with_filename, -> (filenames) { where(filename: filenames) } scope :with_filename, -> (filenames) { where(filename: filenames) }
scope :on_issue, ->(issue) { where(issue_id: issue) } scope :on_issue, ->(issue) { where(issue_id: issue) }
......
...@@ -39,9 +39,12 @@ module DesignManagement ...@@ -39,9 +39,12 @@ module DesignManagement
delegate :issue, :project, to: :current_design delegate :issue, :project, to: :current_design
def move_nulls_to_end def move_nulls_to_end
current_design.class.move_nulls_to_end(issue.designs) moved_records = current_design.class.move_nulls_to_end(issue.designs.in_creation_order)
next_design.reset if next_design && next_design.relative_position.nil? return if moved_records == 0
previous_design.reset if previous_design && previous_design.relative_position.nil?
current_design.reset
next_design&.reset
previous_design&.reset
end end
def neighbors def neighbors
......
---
title: Use correct order when repositioning existing designs
merge_request: 39826
author:
type: fixed
...@@ -185,6 +185,12 @@ RSpec.describe DesignManagement::Design do ...@@ -185,6 +185,12 @@ RSpec.describe DesignManagement::Design do
end 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 describe '.with_filename' do
it 'returns correct design when passed a single filename' do it 'returns correct design when passed a single filename' do
expect(described_class.with_filename(design1.filename)).to eq([design1]) expect(described_class.with_filename(design1.filename)).to eq([design1])
......
...@@ -117,9 +117,30 @@ RSpec.describe DesignManagement::MoveDesignsService do ...@@ -117,9 +117,30 @@ RSpec.describe DesignManagement::MoveDesignsService do
let(:previous_design) { designs.second } let(:previous_design) { designs.second }
let(:next_design) { designs.third } let(:next_design) { designs.third }
it 'calls move_between and is successful' do it 'repositions existing designs and correctly places the given design' do
expect(current_design).to receive(:move_between).with(previous_design, next_design) other_design1 = create(:design, issue: issue, relative_position: 10)
other_design2 = create(:design, issue: issue, relative_position: 20)
other_design3, other_design4 = create_list(:design, 2, issue: issue)
expect(subject).to be_success expect(subject).to be_success
expect(issue.designs.ordered(issue.project)).to eq([
# Existing designs which already had a relative_position set.
# These should stay at the beginning, in the same order.
other_design1,
other_design2,
# The designs we're passing into the service.
# These should be placed between the existing designs, in the correct order.
previous_design,
current_design,
next_design,
# Existing designs which didn't have a relative_position set.
# These should be placed at the end, in the order of their IDs.
other_design3,
other_design4
])
end end
end end
end end
......
...@@ -24,7 +24,7 @@ RSpec.shared_examples 'a class that supports relative positioning' do ...@@ -24,7 +24,7 @@ RSpec.shared_examples 'a class that supports relative positioning' do
item3.update!(relative_position: nil) item3.update!(relative_position: nil)
items = [item1, item2, item3] items = [item1, item2, item3]
described_class.move_nulls_to_end(items) expect(described_class.move_nulls_to_end(items)).to be(2)
expect(items.sort_by(&:relative_position)).to eq(items) expect(items.sort_by(&:relative_position)).to eq(items)
expect(item1.relative_position).to be(1000) expect(item1.relative_position).to be(1000)
...@@ -53,9 +53,8 @@ RSpec.shared_examples 'a class that supports relative positioning' do ...@@ -53,9 +53,8 @@ RSpec.shared_examples 'a class that supports relative positioning' do
it 'does not perform any moves if all items have their relative_position set' do it 'does not perform any moves if all items have their relative_position set' do
item1.update!(relative_position: 1) item1.update!(relative_position: 1)
expect do expect(described_class.move_nulls_to_start([item1])).to be(0)
described_class.move_nulls_to_end([item1]) expect(item1.reload.relative_position).to be(1)
end.not_to change { item1.reset.relative_position }
end end
it 'manages to move nulls to the end even if there is a sequence at the end' do it 'manages to move nulls to the end even if there is a sequence at the end' do
...@@ -97,7 +96,7 @@ RSpec.shared_examples 'a class that supports relative positioning' do ...@@ -97,7 +96,7 @@ RSpec.shared_examples 'a class that supports relative positioning' do
item3.update!(relative_position: 1000) item3.update!(relative_position: 1000)
items = [item1, item2, item3] items = [item1, item2, item3]
described_class.move_nulls_to_start(items) expect(described_class.move_nulls_to_start(items)).to be(2)
items.map(&:reload) items.map(&:reload)
expect(items.sort_by(&:relative_position)).to eq(items) expect(items.sort_by(&:relative_position)).to eq(items)
...@@ -128,10 +127,8 @@ RSpec.shared_examples 'a class that supports relative positioning' do ...@@ -128,10 +127,8 @@ RSpec.shared_examples 'a class that supports relative positioning' do
it 'does not perform any moves if all items have their relative_position set' do it 'does not perform any moves if all items have their relative_position set' do
item1.update!(relative_position: 1) item1.update!(relative_position: 1)
described_class.move_nulls_to_start([item1]) expect(described_class.move_nulls_to_start([item1])).to be(0)
item1.reload expect(item1.reload.relative_position).to be(1)
expect(item1.relative_position).to be(1)
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