#  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 Subscriber::GroupController do
  before { sign_in(people(:top_leader)) }

  let(:list) { mailing_lists(:leaders) }
  let(:group) { list.group }

  context "GET query" do
    subject { response.body }

    [["with static_name", true], ["with database name", false]].each do |c, s|
      context c do
        let(:static_name) { s }
        let(:label) { group.static_name ? group.class.label : group.name }

        around do |example|
          group.class.static_name = static_name

          example.run

          group.class.static_name = false
        end

        # TODO: Postgres discuss this issue with Niklas (SearchStrategies)
        context "top group" do
          before do
            get :query, params: {q: "bot", group_id: group.id, mailing_list_id: list.id}
          end

          it { is_expected.to match(/#{label} → Bottom One/) }
          xit { is_expected.to match(/Bottom One → Group 11/) }
          xit { is_expected.to match(/Bottom One → Group 12/) }
          it { is_expected.to match(/#{label} → Bottom Two/) }
          xit { is_expected.to match(/Bottom Two → Group 21/) }
          xit { is_expected.not_to match(/Bottom One → Group 111/) }

          context "archived bottom layer" do
            before do
              groups(:bottom_layer_one).save!
              groups(:bottom_layer_one).archive!
              get :query, params: {q: "bot", group_id: group.id, mailing_list_id: list.id}
            end

            it { is_expected.to_not match(/Top → Bottom One/) }
            it { is_expected.to_not match(/Bottom One → Group 11/) }
            it { is_expected.to_not match(/Bottom One → Group 12/) }
          end
        end

        context "bottom layer" do
          let(:group) { groups(:bottom_layer_one) }
          let(:list) { MailingList.create!(group: group, name: "bottom_layer") }

          before do
            Group::BottomLayer::Leader.create!(group: group, person: people(:top_leader))
            get :query, params: {q: "bot", group_id: group.id, mailing_list_id: list.id}
          end

          it "does not include sister group or their descendants" do
            is_expected.to match(/Top → #{label}/)
            is_expected.not_to match(/Top → Bottom Two/)
            is_expected.not_to match(/Bottom Two → Group 21/)
          end
        end
      end
    end
  end

  context "GET roles.js" do
    it "load role types" do
      get :roles, xhr: true, params: {
        group_id: group.id,
        mailing_list_id: list.id,
        subscription: {subscriber_id: groups(:bottom_layer_one)}
      }, format: :js

      expect(assigns(:role_types).root).to eq(Group::BottomLayer)
    end

    it "does not load role types for nil group" do
      get :roles, xhr: true, params: {
        group_id: group.id,
        mailing_list_id: list.id
      }, format: :js

      expect(assigns(:role_types)).to be_nil
    end
  end

  context "POST create" do
    it "without subscriber_id replaces error" do
      post :create, params: {
        group_id: group.id,
        mailing_list_id: list.id
      }

      is_expected.to render_template("crud/new")
      expect(assigns(:subscription).errors[:subscriber_id]).to be_blank
      expect(assigns(:subscription).errors[:subscriber_type]).to be_blank
      expect(assigns(:subscription).errors[:base].size).to eq(1)
    end

    it "create subscription with role types" do
      expect do
        expect do
          post :create, params: {
            group_id: group.id,
            mailing_list_id: list.id,
            subscription: {subscriber_id: groups(:bottom_layer_one),
                           role_types: [Group::BottomLayer::Leader, Group::BottomGroup::Leader]}
          }
        end.to change { Subscription.count }.by(1)
      end.to change { RelatedRoleType.count }.by(2)

      is_expected.to redirect_to(group_mailing_list_subscriptions_path(group, list))
    end
  end
end
