discourse/spec/lib/wizard/wizard_spec.rb
Neil Lalonde 8eda55e639
DEV: add a remove_step method to Wizard (#24063)
Using Wizard.exclude_steps applies to all sites in a multisite cluster.
In order to exclude steps for individual sites at run-time, a new
instance method `remove_step` is being added.
2023-10-24 13:22:55 -04:00

268 lines
8.6 KiB
Ruby

# frozen_string_literal: true
require "wizard"
RSpec.describe Wizard do
fab!(:admin) { Fabricate(:admin) }
before { SiteSetting.wizard_enabled = true }
describe "defaults" do
it "has default values" do
wizard = Wizard.new(Fabricate.build(:moderator))
expect(wizard.steps).to be_empty
expect(wizard.user).to be_present
end
end
describe "append_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") }
it "works with a block format" do
wizard.append_step("wat") { |step| expect(step).to be_present }
expect(wizard.steps.size).to eq(1)
end
it "adds the step correctly" do
expect(step1.index).to be_blank
wizard.append_step(step1)
expect(wizard.steps.size).to eq(1)
expect(wizard.start).to eq(step1)
expect(step1.next).to be_blank
expect(step1.previous).to be_blank
expect(step1.index).to eq(0)
expect(step1.fields).to be_empty
field = step1.add_field(id: "test", type: "text")
expect(step1.fields).to eq([field])
end
it "sequences multiple steps" do
wizard.append_step(step1)
wizard.append_step(step2)
expect(wizard.steps.size).to eq(2)
expect(wizard.start).to eq(step1)
expect(step1.next).to eq(step2)
expect(step1.previous).to be_blank
expect(step2.previous).to eq(step1)
expect(step1.index).to eq(0)
expect(step2.index).to eq(1)
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) }
it "excludes steps even if they are added via append_step" do
wizard.append_step("first") { |step| step.add_field(id: "another_element", type: "text") }
Wizard.exclude_step("random-step123")
wizard.append_step("random-step123") do |step|
step.add_field(id: "another_element", type: "text")
end
wizard.append_step("finished")
expect(wizard.steps.map(&:id)).to eq(%w[first finished])
end
end
describe "#append_step with after specified" do
let(:user) { Fabricate.build(:moderator) }
let(:wizard) { Wizard.new(user) }
it "inserts steps after the proper step" do
wizard.append_step("first") { |step| step.add_field(id: "another_element", type: "text") }
wizard.append_step("second") { |step| step.add_field(id: "another_element", type: "text") }
wizard.append_step("actually-second", after: "first") do |step|
step.add_field(id: "another_element", type: "text")
end
expect(wizard.steps.sort_by(&:index).map(&:id)).to eq(%w[first actually-second second])
expect(wizard.steps.map(&:index).sort).to eq([0, 1, 2])
end
it "inserts steps at the end if the after value does not match an existing step" do
wizard.append_step("first") { |step| step.add_field(id: "another_element", type: "text") }
wizard.append_step("second") { |step| step.add_field(id: "another_element", type: "text") }
wizard.append_step("should_be_last", after: "abcdefghi") do |step|
step.add_field(id: "another_element", type: "text")
end
expect(wizard.steps.sort_by(&:index).map(&:id)).to eq(%w[first second should_be_last])
expect(wizard.steps.map(&:index).sort).to eq([0, 1, 2])
end
it "inserts steps at the end" do
wizard.append_step("first") { |step| step.add_field(id: "another_element", type: "text") }
wizard.append_step("second") { |step| step.add_field(id: "another_element", type: "text") }
wizard.append_step("last", after: "second") do |step|
step.add_field(id: "another_element", type: "text")
end
expect(wizard.steps.sort_by(&:index).map(&:id)).to eq(%w[first second last])
expect(wizard.steps.map(&:index).sort).to eq([0, 1, 2])
end
end
describe "completed?" do
let(:user) { Fabricate.build(:moderator) }
let(:wizard) { Wizard.new(user) }
it "is complete when all steps with fields have logs" do
wizard.append_step("first") { |step| step.add_field(id: "element", type: "text") }
wizard.append_step("second") { |step| step.add_field(id: "another_element", type: "text") }
wizard.append_step("finished")
expect(wizard.start.id).to eq("first")
expect(wizard.completed_steps?("first")).to eq(false)
expect(wizard.completed_steps?("second")).to eq(false)
expect(wizard.completed?).to eq(false)
updater = wizard.create_updater("first", element: "test")
updater.update
expect(wizard.start.id).to eq("second")
expect(wizard.completed_steps?("first")).to eq(true)
expect(wizard.completed?).to eq(false)
updater = wizard.create_updater("second", element: "test")
updater.update
expect(wizard.completed_steps?("first")).to eq(true)
expect(wizard.completed_steps?("second")).to eq(true)
expect(wizard.completed_steps?("finished")).to eq(false)
expect(wizard.completed?).to eq(true)
# Once you've completed the wizard start at the beginning
expect(wizard.start.id).to eq("first")
end
end
describe "#requires_completion?" do
def build_simple(user)
wizard = Wizard.new(user)
wizard.append_step("simple") { |step| step.add_field(id: "name", type: "text") }
wizard
end
it "is false for anonymous" do
expect(build_simple(nil).requires_completion?).to eq(false)
end
it "is false for regular users" do
expect(build_simple(Fabricate.build(:user)).requires_completion?).to eq(false)
end
it "it's false when the wizard is disabled" do
SiteSetting.wizard_enabled = false
expect(build_simple(admin).requires_completion?).to eq(false)
end
it "its false when the wizard is bypassed" do
SiteSetting.bypass_wizard_check = true
expect(build_simple(admin).requires_completion?).to eq(false)
end
it "its automatically bypasses after you reach topic limit" do
Fabricate(:topic)
wizard = build_simple(admin)
wizard.max_topics_to_require_completion = Topic.count - 1
expect(wizard.requires_completion?).to eq(false)
expect(SiteSetting.bypass_wizard_check).to eq(true)
end
it "it's true for the first admin who logs in" do
second_admin = Fabricate(:admin)
UserAuthToken.generate!(user_id: second_admin.id)
expect(build_simple(admin).requires_completion?).to eq(false)
expect(build_simple(second_admin).requires_completion?).to eq(true)
end
it "is false for staff when complete" do
wizard = build_simple(admin)
updater = wizard.create_updater("simple", name: "Evil Trout")
updater.update
expect(wizard.requires_completion?).to eq(false)
# It's also false for another user
wizard = build_simple(admin)
expect(wizard.requires_completion?).to eq(false)
end
end
end