#  Copyright (c) 2012-2015, Pfadibewegung 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 Person::AddRequest::Creator::Event do
  let(:primary_layer) { person.primary_group.layer_group }
  let(:person) { Fabricate(Group::BottomLayer::Member.name, group: groups(:bottom_layer_two)).person }
  let(:requester) { Fabricate(Group::BottomLayer::Leader.name, group: groups(:bottom_layer_one)).person }

  let(:event) { Fabricate(:event, groups: [groups(:bottom_layer_one)]) }
  let(:entity) do
    Fabricate.build(Event::Role::Participant.name,
      participation: Fabricate.build(:event_participation, event: event, participant: person))
  end

  let(:ability) { Ability.new(requester) }

  subject { Person::AddRequest::Creator::Event.new(entity, ability) }

  before { primary_layer.update_column(:require_person_add_requests, true) }

  context "#required" do
    it "is true if primary layer activated requests" do
      expect(subject).to be_required
    end

    it "is true if deleted role already exists" do
      Fabricate(Group::BottomGroup::Member.name, group: groups(:bottom_group_one_one), person: person,
        start_on: 2.years.ago, end_on: 1.year.ago)
      expect(subject).to be_required
    end

    it "is false if primary layer deactivated requests" do
      primary_layer.update_column(:require_person_add_requests, false)
      expect(subject).not_to be_required
    end

    it "is false if role is invalid" do
      entity = Fabricate.build(Event::Role::Participant.name,
        participation: Fabricate.build(:event_participation, event: event))
      creator = Person::AddRequest::Creator::Event.new(entity, ability)
      expect(creator).not_to be_required
    end

    it "is false if person has no primary group" do
      person.update_column(:primary_group_id, nil)
      expect(subject).not_to be_required
    end

    it "is false if requester can already show the person" do
      Fabricate(Group::BottomLayer::Member.name, group: groups(:bottom_layer_two), person: requester)
      expect(subject).not_to be_required
    end

    it "is false if person already participates in event" do
      Fabricate(Event::Role::Cook.name, participation: entity.participation)
      entity.participation.reload
      expect(subject).not_to be_required
    end
  end

  context "#create_request" do
    it "creates event request" do
      subject.create_request

      request = subject.request
      expect(request).to be_persisted
      expect(request.body).to eq(event)
      expect(request.role_type).to eq(entity.type)
      expect(request.requester).to eq(requester)
      expect(request.person).to eq(person)
    end

    it "creates group request if deleted role already exists" do
      Fabricate(Group::BottomGroup::Member.name, group: groups(:bottom_group_one_one), person: person,
        start_on: 2.years.ago, end_on: 1.year.ago)

      expect do
        subject.create_request
      end.to change { Person::AddRequest.count }.by(1)
      expect(subject.request).to be_persisted
    end

    it "schedules emails" do
      expect do
        subject.create_request
      end.to change { Delayed::Job.count }.by(1)
    end

    it "does not persist if request already exists" do
      Person::AddRequest::Event.create!(
        person: person,
        requester: requester,
        body: event,
        role_type: Event::Role::Speaker.sti_name
      )

      expect do
        subject.create_request
      end.not_to change { Delayed::Job.count }
      expect(subject.request).to be_new_record
      expect(subject.error_message).to match(/Person wurde bereits angefragt./)
    end
  end
end
