relative_positioning_spec.rb 6.81 KB
Newer Older
1 2
# frozen_string_literal: true

Valery Sizov's avatar
Valery Sizov committed
3 4
require 'spec_helper'

Sean McGivern's avatar
Sean McGivern committed
5
describe RelativePositioning do
6
  let(:project) { create(:project) }
Valery Sizov's avatar
Valery Sizov committed
7 8
  let(:issue) { create(:issue, project: project) }
  let(:issue1) { create(:issue, project: project) }
Valery Sizov's avatar
Valery Sizov committed
9
  let(:new_issue) { create(:issue, project: project) }
Valery Sizov's avatar
Valery Sizov committed
10

11 12 13 14 15 16 17
  describe '.move_to_end' do
    it 'moves the object to the end' do
      Issue.move_to_end([issue, issue1])

      expect(issue1.prev_relative_position).to eq issue.relative_position
      expect(issue.prev_relative_position).to eq nil
      expect(issue1.next_relative_position).to eq nil
Valery Sizov's avatar
Valery Sizov committed
18
    end
19 20 21 22 23 24 25 26

    it 'does not perform any moves if all issues have their relative_position set' do
      issue.update!(relative_position: 1)

      expect(issue).not_to receive(:save)

      Issue.move_to_end([issue])
    end
Valery Sizov's avatar
Valery Sizov committed
27 28
  end

Valery Sizov's avatar
Valery Sizov committed
29
  describe '#max_relative_position' do
Valery Sizov's avatar
Valery Sizov committed
30 31 32 33 34
    it 'returns maximum position' do
      expect(issue.max_relative_position).to eq issue1.relative_position
    end
  end

35 36 37 38 39
  describe '#prev_relative_position' do
    it 'returns previous position if there is an issue above' do
      expect(issue1.prev_relative_position).to eq issue.relative_position
    end

40 41
    it 'returns nil if there is no issue above' do
      expect(issue.prev_relative_position).to eq nil
42 43 44 45 46 47 48 49
    end
  end

  describe '#next_relative_position' do
    it 'returns next position if there is an issue below' do
      expect(issue.next_relative_position).to eq issue1.relative_position
    end

50 51
    it 'returns nil if there is no issue below' do
      expect(issue1.next_relative_position).to eq nil
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
    end
  end

  describe '#move_before' do
    it 'moves issue before' do
      [issue1, issue].each(&:move_to_end)

      issue.move_before(issue1)

      expect(issue.relative_position).to be < issue1.relative_position
    end
  end

  describe '#move_after' do
    it 'moves issue after' do
      [issue, issue1].each(&:move_to_end)
Valery Sizov's avatar
Valery Sizov committed
68

69
      issue.move_after(issue1)
Valery Sizov's avatar
Valery Sizov committed
70

71
      expect(issue.relative_position).to be > issue1.relative_position
Valery Sizov's avatar
Valery Sizov committed
72 73 74 75
    end
  end

  describe '#move_to_end' do
76 77 78 79 80 81
    before do
      [issue, issue1].each do |issue|
        issue.move_to_end && issue.save
      end
    end

Valery Sizov's avatar
Valery Sizov committed
82 83 84 85 86 87 88
    it 'moves issue to the end' do
      new_issue.move_to_end

      expect(new_issue.relative_position).to be > issue1.relative_position
    end
  end

89
  describe '#shift_after?' do
90 91 92 93 94 95
    before do
      [issue, issue1].each do |issue|
        issue.move_to_end && issue.save
      end
    end

96 97 98 99 100 101 102 103 104 105 106 107 108 109
    it 'returns true' do
      issue.update(relative_position: issue1.relative_position - 1)

      expect(issue.shift_after?).to be_truthy
    end

    it 'returns false' do
      issue.update(relative_position: issue1.relative_position - 2)

      expect(issue.shift_after?).to be_falsey
    end
  end

  describe '#shift_before?' do
110 111 112 113 114 115
    before do
      [issue, issue1].each do |issue|
        issue.move_to_end && issue.save
      end
    end

116 117 118 119 120 121 122 123 124 125 126 127 128
    it 'returns true' do
      issue.update(relative_position: issue1.relative_position + 1)

      expect(issue.shift_before?).to be_truthy
    end

    it 'returns false' do
      issue.update(relative_position: issue1.relative_position + 2)

      expect(issue.shift_before?).to be_falsey
    end
  end

Valery Sizov's avatar
Valery Sizov committed
129
  describe '#move_between' do
130 131 132 133 134 135
    before do
      [issue, issue1].each do |issue|
        issue.move_to_end && issue.save
      end
    end

Valery Sizov's avatar
Valery Sizov committed
136 137 138 139 140 141 142
    it 'positions issue between two other' do
      new_issue.move_between(issue, issue1)

      expect(new_issue.relative_position).to be > issue.relative_position
      expect(new_issue.relative_position).to be < issue1.relative_position
    end

Valery Sizov's avatar
Valery Sizov committed
143 144
    it 'positions issue between on top' do
      new_issue.move_between(nil, issue)
Valery Sizov's avatar
Valery Sizov committed
145

Valery Sizov's avatar
Valery Sizov committed
146
      expect(new_issue.relative_position).to be < issue.relative_position
Valery Sizov's avatar
Valery Sizov committed
147 148
    end

Valery Sizov's avatar
Valery Sizov committed
149 150
    it 'positions issue between to end' do
      new_issue.move_between(issue1, nil)
Valery Sizov's avatar
Valery Sizov committed
151

Valery Sizov's avatar
Valery Sizov committed
152
      expect(new_issue.relative_position).to be > issue1.relative_position
Valery Sizov's avatar
Valery Sizov committed
153 154
    end

Valery Sizov's avatar
Valery Sizov committed
155 156
    it 'positions issues even when after and before positions are the same' do
      issue1.update relative_position: issue.relative_position
Valery Sizov's avatar
Valery Sizov committed
157

Valery Sizov's avatar
Valery Sizov committed
158
      new_issue.move_between(issue, issue1)
Valery Sizov's avatar
Valery Sizov committed
159

Valery Sizov's avatar
Valery Sizov committed
160 161
      expect(new_issue.relative_position).to be > issue.relative_position
      expect(issue.relative_position).to be < issue1.relative_position
Valery Sizov's avatar
Valery Sizov committed
162
    end
163 164 165 166 167 168 169 170 171 172

    it 'positions issues between other two if distance is 1' do
      issue1.update relative_position: issue.relative_position + 1

      new_issue.move_between(issue, issue1)

      expect(new_issue.relative_position).to be > issue.relative_position
      expect(issue.relative_position).to be < issue1.relative_position
    end

173 174 175
    it 'positions issue in the middle of other two if distance is big enough' do
      issue.update relative_position: 6000
      issue1.update relative_position: 10000
176 177 178

      new_issue.move_between(issue, issue1)

179 180 181 182 183 184 185 186
      expect(new_issue.relative_position).to eq(8000)
    end

    it 'positions issue closer to the middle if we are at the very top' do
      issue1.update relative_position: 6000

      new_issue.move_between(nil, issue1)

187
      expect(new_issue.relative_position).to eq(6000 - RelativePositioning::IDEAL_DISTANCE)
188 189 190 191 192 193 194 195
    end

    it 'positions issue closer to the middle if we are at the very bottom' do
      issue.update relative_position: 6000
      issue1.update relative_position: nil

      new_issue.move_between(issue, nil)

196
      expect(new_issue.relative_position).to eq(6000 + RelativePositioning::IDEAL_DISTANCE)
197 198 199 200 201 202 203 204 205 206
    end

    it 'positions issue in the middle of other two if distance is not big enough' do
      issue.update relative_position: 100
      issue1.update relative_position: 400

      new_issue.move_between(issue, issue1)

      expect(new_issue.relative_position).to eq(250)
    end
207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240

    it 'positions issue in the middle of other two is there is no place' do
      issue.update relative_position: 100
      issue1.update relative_position: 101

      new_issue.move_between(issue, issue1)

      expect(new_issue.relative_position).to be_between(issue.relative_position, issue1.relative_position)
    end

    it 'uses rebalancing if there is no place' do
      issue.update relative_position: 100
      issue1.update relative_position: 101
      issue2 = create(:issue, relative_position: 102, project: project)
      new_issue.update relative_position: 103

      new_issue.move_between(issue1, issue2)
      new_issue.save!

      expect(new_issue.relative_position).to be_between(issue1.relative_position, issue2.relative_position)
      expect(issue.reload.relative_position).not_to eq(100)
    end

    it 'positions issue right if we pass none-sequential parameters' do
      issue.update relative_position: 99
      issue1.update relative_position: 101
      issue2 = create(:issue, relative_position: 102, project: project)
      new_issue.update relative_position: 103

      new_issue.move_between(issue, issue2)
      new_issue.save!

      expect(new_issue.relative_position).to be(100)
    end
Valery Sizov's avatar
Valery Sizov committed
241 242
  end
end