require "spec_helper"

describe Tags::MergeController do
  let(:top_leader) { people(:top_leader) }
  let(:bottom_member) { people(:bottom_member) }

  let(:tag1) { Fabricate(:tag) }
  let(:tag2) { Fabricate(:tag) }
  let!(:tag3) { Fabricate(:tag) }

  let!(:tag1_owner) { fabricate_tagged_person([tag1]) }
  let!(:tag2_owner) { fabricate_tagged_person([tag2]) }
  let!(:all_tag_owner) { fabricate_tagged_person([tag1, tag2]) }

  before { sign_in(top_leader) }

  describe "GET #new" do
    it "suggests new tag name based on tagging count" do
      get :new, xhr: true, params: {ids: [tag2.id, tag3.id].join(",")}

      expect(assigns(:name)).to eq tag2.name
      expect(assigns(:tag_names)).to eq [tag3.name, tag2.name].join(", ")
      expect(assigns(:src_tag_ids)).to eq [tag3.id]
    end

    it "is not possible to merge tags without permission" do
      sign_in(bottom_member)

      expect do
        get :new, params: {ids: [tag2.id, tag1.id].join(",")}
      end.to raise_error(CanCan::AccessDenied)
    end
  end

  describe "POST #create" do
    it "merges tags" do
      post :create, params: {tags_merge: {src_tag_ids: tag1.id, dst_tag_id: tag2.id, name: tag2.name}}

      expect(tag1_owner.reload.tags.to_a).to eq([tag2])
      expect(tag2_owner.reload.tags.to_a).to eq([tag2])
      expect(all_tag_owner.reload.tags.to_a).to eq([tag2])

      expect(tag2.reload.taggings_count).to eq(3)

      expect(ActsAsTaggableOn::Tag.where(id: tag1.id)).not_to exist

      is_expected.to redirect_to tags_path
      expect(flash[:notice]).to eq "Die Tags wurden erfolgreich zusammengeführt."
    end

    it "merges multiple tags" do
      post :create, params: {tags_merge: {src_tag_ids: [tag3.id, tag1.id].join(","), dst_tag_id: tag2.id, name: tag2.name}}

      expect(tag1_owner.reload.tags.to_a).to eq([tag2])
      expect(tag2_owner.reload.tags.to_a).to eq([tag2])
      expect(all_tag_owner.reload.tags.to_a).to eq([tag2])

      expect(tag2.reload.taggings_count).to eq(3)

      expect(ActsAsTaggableOn::Tag.where(id: tag1.id)).not_to exist
      expect(ActsAsTaggableOn::Tag.where(id: tag3.id)).not_to exist

      is_expected.to redirect_to tags_path

      expect(flash[:notice]).to eq "Die Tags wurden erfolgreich zusammengeführt."
    end

    it "is not possible to merge tags without permission" do
      sign_in(bottom_member)

      expect do
        post :create, params: {tags_merge: {src_tag_ids: tag2.id, dst_tag_id: tag1.id, name: tag2.name}}
      end.to raise_error(CanCan::AccessDenied)

      expect(tag1_owner.reload.tags.to_a).to eq([tag1])
      expect(tag2_owner.reload.tags.to_a).to eq([tag2])
      expect(all_tag_owner.reload.tags.to_a).to match_array([tag1, tag2])
    end
  end

  private

  def fabricate_tagged_person(tags)
    person = Fabricate(:person)
    person.update!(tags: tags)
    person
  end
end
