diff --git a/lib/wizard.rb b/lib/wizard.rb index f85d9f008ab..7624fbc4d4d 100644 --- a/lib/wizard.rb +++ b/lib/wizard.rb @@ -54,6 +54,25 @@ class Wizard end end + def remove_step(step_id) + i = @steps.index { |step| step.id == step_id } + return if i.nil? + + step = @steps.delete_at(i) + + step.previous.next = step.next if step.previous + + while step = step.next + step.index -= 1 + if step.index == 0 + step.previous = nil + @first_step = step + else + step.previous = @steps[step.index - 1] + end + end + end + def self.exclude_step(step) @@excluded_steps << step end diff --git a/spec/lib/wizard/wizard_spec.rb b/spec/lib/wizard/wizard_spec.rb index 53ed5f98a0a..9938724941b 100644 --- a/spec/lib/wizard/wizard_spec.rb +++ b/spec/lib/wizard/wizard_spec.rb @@ -56,6 +56,68 @@ RSpec.describe Wizard do end end + describe "remove_step" do + let(:user) { Fabricate.build(:moderator) } + let(:wizard) { Wizard.new(user) } + let(:step1) { wizard.create_step("first-step") } + let(:step2) { wizard.create_step("second-step") } + let(:step3) { wizard.create_step("third-step") } + + before do + wizard.append_step(step1) + wizard.append_step(step2) + wizard.append_step(step3) + end + + it "does nothing if step id doesn't match any steps" do + wizard.remove_step("nope") + expect(wizard.steps).to contain_exactly(step1, step2, step3) + expect(wizard.start).to eq(step1) + end + + it "can remove the first step" do + wizard.remove_step(step1.id) + expect(wizard.steps).to contain_exactly(step2, step3) + expect(step2.index).to eq(0) + expect(step2.previous).to be_blank + expect(step2.next).to eq(step3) + + expect(step3.index).to eq(1) + expect(step3.previous).to eq(step2) + expect(step3.next).to be_blank + + expect(wizard.start).to eq(step2) + end + + it "can remove a middle step" do + wizard.remove_step(step2.id) + expect(wizard.steps).to contain_exactly(step1, step3) + expect(step1.index).to eq(0) + expect(step1.previous).to be_blank + expect(step1.next).to eq(step3) + + expect(step3.index).to eq(1) + expect(step3.previous).to eq(step1) + expect(step3.next).to be_blank + + expect(wizard.start).to eq(step1) + end + + it "can remove the last step" do + wizard.remove_step(step3.id) + expect(wizard.steps).to contain_exactly(step1, step2) + expect(step1.index).to eq(0) + expect(step1.previous).to be_blank + expect(step1.next).to eq(step2) + + expect(step2.index).to eq(1) + expect(step2.previous).to eq(step1) + expect(step2.next).to be_blank + + expect(wizard.start).to eq(step1) + end + end + describe ".exclude_step" do let(:user) { Fabricate.build(:moderator) } let(:wizard) { Wizard.new(user) }