#  Copyright (c) 2012-2013, Jungwacht Blauring Schweiz. This file is part of
#  hitobito and licensed under the Affero General Public License version 3
#  or later. See the COPYING file at the top-level directory or at
#  https://github.com/hitobito/hitobito.

require "spec_helper"
describe Group::Mover do
  let(:move) { Group::Mover.new(group) }

  describe "#candidates" do
    subject { Group::Mover.new(group) }

    context "top_group" do
      let(:group) { groups(:top_group) }

      its(:candidates) { is_expected.to be_blank }
    end

    context "bottom_layer_one" do
      let(:group) { groups(:bottom_layer_one) }

      its(:candidates) { is_expected.to be_blank }
    end

    context "bottom_layer_two" do
      let(:group) { groups(:bottom_layer_two) }

      its(:candidates) { is_expected.to be_blank }
    end

    context "bottom_group_one_one" do
      let(:group) { groups(:bottom_group_one_one) }

      its(:candidates) { is_expected.to match_array groups_for(:bottom_layer_two, :bottom_group_one_two) }
    end

    context "bottom_group_one_two" do
      let(:group) { groups(:bottom_group_one_two) }

      its(:candidates) { is_expected.to match_array groups_for(:bottom_layer_two, :bottom_group_one_one) }
    end

    context "bottom_group_two_one" do
      let(:group) { groups(:bottom_group_two_one) }

      its(:candidates) { is_expected.to match_array groups_for(:bottom_layer_one) }
    end

    context "bottom_group_one_one_one" do
      let(:group) { groups(:bottom_group_one_one_one) }

      its(:candidates) {
        is_expected.to match_array groups_for(:bottom_layer_one, :bottom_layer_two, :bottom_group_one_two)
      }
    end

    def groups_for(*args)
      args.map { |arg| groups(arg) }
    end
  end

  context "#perform" do
    let(:group) { groups(:bottom_group_one_one) }
    let(:target) { groups(:bottom_layer_two) }

    context "moved group" do
      subject { group.reload }

      before { move.perform(target) }

      its(:parent) { is_expected.to eq target }
      its(:layer_group_id) { is_expected.to eq target.id }

      it "nested set should still be valid" do
        expect(Group).to be_valid
      end

      it "updates layer groups of children" do
        expect(groups(:bottom_group_one_one_one).layer_group_id).to eq(target.id)
      end
    end

    context "association count" do
      before do
        event = Fabricate(:event, groups: [group])
        Fabricate(:event_participation, event: event)
        Fabricate(Group::BottomGroup::Member.name.to_s, group: group)
      end

      [Group, Role, Person, Event, Event::Participation].each do |model|
        it "does not change #{model} count" do
          expect { move.perform(target) }.not_to change(model, :count)
        end
      end
    end
  end
end
