require 'rails_helper'
require 'wizard'

describe Wizard do
  before do
    SiteSetting.wizard_enabled = true
  end

  context "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') do |step|
        expect(step).to be_present
      end

      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 "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') do |step|
        step.add_field(id: 'element', type: 'text')
      end

      wizard.append_step('second') do |step|
        step.add_field(id: 'another_element', type: 'text')
      end

      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') do |step|
        step.add_field(id: 'name', type: 'text')
      end
      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 "is false for a developer" do
      developer = Fabricate(:admin)
      Developer.create!(user_id: developer.id)

      expect(build_simple(developer).requires_completion?).to eq(false)
    end

    it "it's false when the wizard is disabled" do
      SiteSetting.wizard_enabled = false
      admin = Fabricate(:admin)
      expect(build_simple(admin).requires_completion?).to eq(false)
    end

    it "it's true for the first admin who logs in" do
      admin = Fabricate(:admin)
      second_admin = Fabricate(:admin, auth_token_updated_at: Time.now)

      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(Fabricate(: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(Fabricate(:admin))
      expect(wizard.requires_completion?).to eq(false)
    end

  end

end
