# frozen_string_literal: true

#  Copyright (c) 2022, 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 Calendars::Events do
  around do |example|
    subgroup_previous, subgroup.class.event_types = subgroup.class.event_types.clone, [Event, Event::Course]
    example.run
    subgroup.class.event_types = subgroup_previous
  end

  let(:layer) { groups(:bottom_layer_one) }
  let(:subgroup) { groups(:bottom_group_one_one) }
  let(:subsubgroup) { groups(:bottom_group_one_one_one) }

  let(:layer_event) { Fabricate(:event, groups: [layer]) }
  let(:layer_course) { Fabricate(:course, groups: [layer]) }
  let(:subgroup_event) { Fabricate(:event, groups: [subgroup]) }
  let(:subgroup_course) { Fabricate(:course, groups: [subgroup]) }
  let(:subsubgroup_event) { Fabricate(:event, groups: [subsubgroup]) }
  let(:subsubgroup_course) { Fabricate(:course, groups: [subsubgroup]) }

  let(:calendar) { Fabricate(:calendar, group: layer) }

  subject { Calendars::Events.new(calendar).events }

  context "with included calendar group" do
    context "layer" do
      let!(:calendar_group) { calendar.included_calendar_groups.first.tap { |g| g.update(group: layer) } }

      context "including all event types" do
        before { calendar_group.update(event_type: nil) }

        context "without subgroups" do
          before { calendar_group.update(with_subgroups: false) }

          it { is_expected.to include(layer_event) }
          it { is_expected.to include(layer_course) }
          it { is_expected.not_to include(subgroup_event) }
          it { is_expected.not_to include(subgroup_course) }
          it { is_expected.not_to include(subsubgroup_event) }
          it { is_expected.not_to include(subsubgroup_course) }

          context "with excluded calendar group" do
            let(:excluded_calendar_group) { Fabricate(:calendar_group, excluded: true, calendar: calendar) }

            context "layer" do
              before { excluded_calendar_group.update(group: layer) }

              context "excluding all event types" do
                before { excluded_calendar_group.update(event_type: nil) }

                context "excluding also subgroups" do
                  before { excluded_calendar_group.update(with_subgroups: true) }

                  it { is_expected.not_to include(layer_event) }
                  it { is_expected.not_to include(layer_course) }
                  it { is_expected.not_to include(subgroup_event) }
                  it { is_expected.not_to include(subgroup_course) }
                  it { is_expected.not_to include(subsubgroup_event) }
                  it { is_expected.not_to include(subsubgroup_course) }
                end

                context "not excluding subgroups" do
                  before { excluded_calendar_group.update(with_subgroups: false) }

                  it { is_expected.not_to include(layer_event) }
                  it { is_expected.not_to include(layer_course) }
                  it { is_expected.not_to include(subgroup_event) }
                  it { is_expected.not_to include(subgroup_course) }
                  it { is_expected.not_to include(subsubgroup_event) }
                  it { is_expected.not_to include(subsubgroup_course) }
                end
              end

              context "excluding only plain events" do
                before { excluded_calendar_group.update(event_type: Event.name) }

                context "excluding also subgroups" do
                  before { excluded_calendar_group.update(with_subgroups: true) }

                  it { is_expected.not_to include(layer_event) }
                  it { is_expected.to include(layer_course) }
                  it { is_expected.not_to include(subgroup_event) }
                  it { is_expected.not_to include(subgroup_course) }
                  it { is_expected.not_to include(subsubgroup_event) }
                  it { is_expected.not_to include(subsubgroup_course) }
                end

                context "not excluding subgroups" do
                  before { excluded_calendar_group.update(with_subgroups: false) }

                  it { is_expected.not_to include(layer_event) }
                  it { is_expected.to include(layer_course) }
                  it { is_expected.not_to include(subgroup_event) }
                  it { is_expected.not_to include(subgroup_course) }
                  it { is_expected.not_to include(subsubgroup_event) }
                  it { is_expected.not_to include(subsubgroup_course) }
                end
              end

              context "excluding only courses" do
                before { excluded_calendar_group.update(event_type: Event::Course.name) }

                context "excluding also subgroups" do
                  before { excluded_calendar_group.update(with_subgroups: true) }

                  it { is_expected.to include(layer_event) }
                  it { is_expected.not_to include(layer_course) }
                  it { is_expected.not_to include(subgroup_event) }
                  it { is_expected.not_to include(subgroup_course) }
                  it { is_expected.not_to include(subsubgroup_event) }
                  it { is_expected.not_to include(subsubgroup_course) }
                end

                context "not excluding subgroups" do
                  before { excluded_calendar_group.update(with_subgroups: false) }

                  it { is_expected.to include(layer_event) }
                  it { is_expected.not_to include(layer_course) }
                  it { is_expected.not_to include(subgroup_event) }
                  it { is_expected.not_to include(subgroup_course) }
                  it { is_expected.not_to include(subsubgroup_event) }
                  it { is_expected.not_to include(subsubgroup_course) }
                end
              end
            end

            context "subgroup makes no difference" do
              before { excluded_calendar_group.update(group: subgroup, event_type: nil, with_subgroups: true) }

              it { is_expected.to include(layer_event) }
              it { is_expected.to include(layer_course) }
              it { is_expected.not_to include(subgroup_event) }
              it { is_expected.not_to include(subgroup_course) }
              it { is_expected.not_to include(subsubgroup_event) }
              it { is_expected.not_to include(subsubgroup_course) }
            end
          end
        end

        context "with subgroups" do
          before { calendar_group.update(with_subgroups: true) }

          it { is_expected.to include(layer_event) }
          it { is_expected.to include(layer_course) }
          it { is_expected.to include(subgroup_event) }
          it { is_expected.to include(subgroup_course) }
          it { is_expected.to include(subsubgroup_event) }
          it { is_expected.to include(subsubgroup_course) }

          context "with excluded calendar group" do
            let(:excluded_calendar_group) { Fabricate(:calendar_group, excluded: true, calendar: calendar) }

            context "layer" do
              before { excluded_calendar_group.update(group: layer) }

              context "excluding all event types" do
                before { excluded_calendar_group.update(event_type: nil) }

                context "excluding also subgroups" do
                  before { excluded_calendar_group.update(with_subgroups: true) }

                  it { is_expected.not_to include(layer_event) }
                  it { is_expected.not_to include(layer_course) }
                  it { is_expected.not_to include(subgroup_event) }
                  it { is_expected.not_to include(subgroup_course) }
                  it { is_expected.not_to include(subsubgroup_event) }
                  it { is_expected.not_to include(subsubgroup_course) }
                end

                context "not excluding subgroups" do
                  before { excluded_calendar_group.update(with_subgroups: false) }

                  it { is_expected.not_to include(layer_event) }
                  it { is_expected.not_to include(layer_course) }
                  it { is_expected.to include(subgroup_event) }
                  it { is_expected.to include(subgroup_course) }
                  it { is_expected.to include(subsubgroup_event) }
                  it { is_expected.to include(subsubgroup_course) }
                end
              end

              context "excluding only plain events" do
                before { excluded_calendar_group.update(event_type: Event.name) }

                context "excluding also subgroups" do
                  before { excluded_calendar_group.update(with_subgroups: true) }

                  it { is_expected.not_to include(layer_event) }
                  it { is_expected.to include(layer_course) }
                  it { is_expected.not_to include(subgroup_event) }
                  it { is_expected.to include(subgroup_course) }
                  it { is_expected.not_to include(subsubgroup_event) }
                  it { is_expected.to include(subsubgroup_course) }
                end

                context "not excluding subgroups" do
                  before { excluded_calendar_group.update(with_subgroups: false) }

                  it { is_expected.not_to include(layer_event) }
                  it { is_expected.to include(layer_course) }
                  it { is_expected.to include(subgroup_event) }
                  it { is_expected.to include(subgroup_course) }
                  it { is_expected.to include(subsubgroup_event) }
                  it { is_expected.to include(subsubgroup_course) }
                end
              end

              context "excluding only courses" do
                before { excluded_calendar_group.update(event_type: Event::Course.name) }

                context "excluding also subgroups" do
                  before { excluded_calendar_group.update(with_subgroups: true) }

                  it { is_expected.to include(layer_event) }
                  it { is_expected.not_to include(layer_course) }
                  it { is_expected.to include(subgroup_event) }
                  it { is_expected.not_to include(subgroup_course) }
                  it { is_expected.to include(subsubgroup_event) }
                  it { is_expected.not_to include(subsubgroup_course) }
                end

                context "not excluding subgroups" do
                  before { excluded_calendar_group.update(with_subgroups: false) }

                  it { is_expected.to include(layer_event) }
                  it { is_expected.not_to include(layer_course) }
                  it { is_expected.to include(subgroup_event) }
                  it { is_expected.to include(subgroup_course) }
                  it { is_expected.to include(subsubgroup_event) }
                  it { is_expected.to include(subsubgroup_course) }
                end
              end
            end

            context "subgroup" do
              before { excluded_calendar_group.update(group: subgroup) }

              context "excluding all event types" do
                before { excluded_calendar_group.update(event_type: nil) }

                context "excluding also subsubgroups" do
                  before { excluded_calendar_group.update(with_subgroups: true) }

                  it { is_expected.to include(layer_event) }
                  it { is_expected.to include(layer_course) }
                  it { is_expected.not_to include(subgroup_event) }
                  it { is_expected.not_to include(subgroup_course) }
                  it { is_expected.not_to include(subsubgroup_event) }
                  it { is_expected.not_to include(subsubgroup_course) }
                end

                context "not excluding subsubgroups" do
                  before { excluded_calendar_group.update(with_subgroups: false) }

                  it { is_expected.to include(layer_event) }
                  it { is_expected.to include(layer_course) }
                  it { is_expected.not_to include(subgroup_event) }
                  it { is_expected.not_to include(subgroup_course) }
                  it { is_expected.to include(subsubgroup_event) }
                  it { is_expected.to include(subsubgroup_course) }
                end
              end

              context "excluding only plain events" do
                before { excluded_calendar_group.update(event_type: Event.name) }

                context "excluding also subsubgroups" do
                  before { excluded_calendar_group.update(with_subgroups: true) }

                  it { is_expected.to include(layer_event) }
                  it { is_expected.to include(layer_course) }
                  it { is_expected.not_to include(subgroup_event) }
                  it { is_expected.to include(subgroup_course) }
                  it { is_expected.not_to include(subsubgroup_event) }
                  it { is_expected.to include(subsubgroup_course) }
                end

                context "not excluding subsubgroups" do
                  before { excluded_calendar_group.update(with_subgroups: false) }

                  it { is_expected.to include(layer_event) }
                  it { is_expected.to include(layer_course) }
                  it { is_expected.not_to include(subgroup_event) }
                  it { is_expected.to include(subgroup_course) }
                  it { is_expected.to include(subsubgroup_event) }
                  it { is_expected.to include(subsubgroup_course) }
                end
              end

              context "excluding only courses" do
                before { excluded_calendar_group.update(event_type: Event::Course.name) }

                context "excluding also subsubgroups" do
                  before { excluded_calendar_group.update(with_subgroups: true) }

                  it { is_expected.to include(layer_event) }
                  it { is_expected.to include(layer_course) }
                  it { is_expected.to include(subgroup_event) }
                  it { is_expected.not_to include(subgroup_course) }
                  it { is_expected.to include(subsubgroup_event) }
                  it { is_expected.not_to include(subsubgroup_course) }
                end

                context "not excluding subsubgroups" do
                  before { excluded_calendar_group.update(with_subgroups: false) }

                  it { is_expected.to include(layer_event) }
                  it { is_expected.to include(layer_course) }
                  it { is_expected.to include(subgroup_event) }
                  it { is_expected.not_to include(subgroup_course) }
                  it { is_expected.to include(subsubgroup_event) }
                  it { is_expected.to include(subsubgroup_course) }
                end
              end
            end
          end

          context "" do
            let(:tag_hello) { ActsAsTaggableOn::Tag.find_by(name: "hello") }
            let(:tag_world) { ActsAsTaggableOn::Tag.find_by(name: "world") }

            before do
              layer_event.update!(tag_list: "hello, world")
              layer_course.update!(tag_list: "foo")
              subgroup_event.update!(tag_list: "world, foo")
              subgroup_course.update!(tag_list: "hello, foo")
              subsubgroup_event.update!(tag_list: "")
              subsubgroup_course.update!(tag_list: "hello")
            end

            context "filtering by a single tag" do
              let!(:included_tag_hello) { Fabricate(:calendar_tag, excluded: false, calendar: calendar, tag: tag_hello) }

              it { is_expected.to include(layer_event) }
              it { is_expected.not_to include(layer_course) }
              it { is_expected.not_to include(subgroup_event) }
              it { is_expected.to include(subgroup_course) }
              it { is_expected.not_to include(subsubgroup_event) }
              it { is_expected.to include(subsubgroup_course) }
            end

            context "filtering by multiple tags includes all events containing any of the tags" do
              let!(:included_tag_hello) { Fabricate(:calendar_tag, excluded: false, calendar: calendar, tag: tag_hello) }
              let!(:included_tag_world) { Fabricate(:calendar_tag, excluded: false, calendar: calendar, tag: tag_world) }

              it { is_expected.to include(layer_event) }
              it { is_expected.not_to include(layer_course) }
              it { is_expected.to include(subgroup_event) }
              it { is_expected.to include(subgroup_course) }
              it { is_expected.not_to include(subsubgroup_event) }
              it { is_expected.to include(subsubgroup_course) }
            end

            context "excluding a single tag" do
              let!(:excluded_tag_hello) { Fabricate(:calendar_tag, excluded: true, calendar: calendar, tag: tag_hello) }

              it { is_expected.not_to include(layer_event) }
              it { is_expected.to include(layer_course) }
              it { is_expected.to include(subgroup_event) }
              it { is_expected.not_to include(subgroup_course) }
              it { is_expected.to include(subsubgroup_event) }
              it { is_expected.not_to include(subsubgroup_course) }
            end

            context "excluding multiple tags leaves only events containing none of the tags" do
              let!(:excluded_tag_hello) { Fabricate(:calendar_tag, excluded: true, calendar: calendar, tag: tag_hello) }
              let!(:excluded_tag_world) { Fabricate(:calendar_tag, excluded: true, calendar: calendar, tag: tag_world) }

              it { is_expected.not_to include(layer_event) }
              it { is_expected.to include(layer_course) }
              it { is_expected.not_to include(subgroup_event) }
              it { is_expected.not_to include(subgroup_course) }
              it { is_expected.to include(subsubgroup_event) }
              it { is_expected.not_to include(subsubgroup_course) }
            end

            context "including and excluding some tags, excluding takes precedence" do
              let!(:included_tag_hello) { Fabricate(:calendar_tag, excluded: false, calendar: calendar, tag: tag_hello) }
              let!(:excluded_tag_world) { Fabricate(:calendar_tag, excluded: true, calendar: calendar, tag: tag_world) }

              it { is_expected.not_to include(layer_event) }
              it { is_expected.not_to include(layer_course) }
              it { is_expected.not_to include(subgroup_event) }
              it { is_expected.to include(subgroup_course) }
              it { is_expected.not_to include(subsubgroup_event) }
              it { is_expected.to include(subsubgroup_course) }
            end
          end
        end
      end

      context "including only plain events" do
        before { calendar_group.update(event_type: Event.name) }

        context "without subgroups" do
          before do
            calendar_group.update(with_subgroups: false)
          end

          it { is_expected.to include(layer_event) }
          it { is_expected.not_to include(layer_course) }
          it { is_expected.not_to include(subgroup_event) }
          it { is_expected.not_to include(subgroup_course) }
          it { is_expected.not_to include(subsubgroup_event) }
          it { is_expected.not_to include(subsubgroup_course) }

          context "with excluded calendar group" do
            let(:excluded_calendar_group) { Fabricate(:calendar_group, excluded: true, calendar: calendar) }

            context "layer" do
              before { excluded_calendar_group.update(group: layer) }

              context "excluding all event types" do
                before { excluded_calendar_group.update(event_type: nil) }

                context "excluding also subgroups" do
                  before { excluded_calendar_group.update(with_subgroups: true) }

                  it { is_expected.not_to include(layer_event) }
                  it { is_expected.not_to include(layer_course) }
                  it { is_expected.not_to include(subgroup_event) }
                  it { is_expected.not_to include(subgroup_course) }
                  it { is_expected.not_to include(subsubgroup_event) }
                  it { is_expected.not_to include(subsubgroup_course) }
                end

                context "not excluding subgroups" do
                  before { excluded_calendar_group.update(with_subgroups: false) }

                  it { is_expected.not_to include(layer_event) }
                  it { is_expected.not_to include(layer_course) }
                  it { is_expected.not_to include(subgroup_event) }
                  it { is_expected.not_to include(subgroup_course) }
                  it { is_expected.not_to include(subsubgroup_event) }
                  it { is_expected.not_to include(subsubgroup_course) }
                end
              end

              context "excluding only plain events" do
                before { excluded_calendar_group.update(event_type: Event.name) }

                context "excluding also subgroups" do
                  before { excluded_calendar_group.update(with_subgroups: true) }

                  it { is_expected.not_to include(layer_event) }
                  it { is_expected.not_to include(layer_course) }
                  it { is_expected.not_to include(subgroup_event) }
                  it { is_expected.not_to include(subgroup_course) }
                  it { is_expected.not_to include(subsubgroup_event) }
                  it { is_expected.not_to include(subsubgroup_course) }
                end

                context "not excluding subgroups" do
                  before { excluded_calendar_group.update(with_subgroups: false) }

                  it { is_expected.not_to include(layer_event) }
                  it { is_expected.not_to include(layer_course) }
                  it { is_expected.not_to include(subgroup_event) }
                  it { is_expected.not_to include(subgroup_course) }
                  it { is_expected.not_to include(subsubgroup_event) }
                  it { is_expected.not_to include(subsubgroup_course) }
                end
              end

              context "excluding only courses makes no difference" do
                before { excluded_calendar_group.update(event_type: Event::Course.name, with_subgroups: true) }

                it { is_expected.to include(layer_event) }
                it { is_expected.not_to include(layer_course) }
                it { is_expected.not_to include(subgroup_event) }
                it { is_expected.not_to include(subgroup_course) }
                it { is_expected.not_to include(subsubgroup_event) }
                it { is_expected.not_to include(subsubgroup_course) }
              end
            end

            context "subgroup makes no difference" do
              before { excluded_calendar_group.update(group: subgroup, event_type: nil, with_subgroups: true) }

              it { is_expected.to include(layer_event) }
              it { is_expected.not_to include(layer_course) }
              it { is_expected.not_to include(subgroup_event) }
              it { is_expected.not_to include(subgroup_course) }
              it { is_expected.not_to include(subsubgroup_event) }
              it { is_expected.not_to include(subsubgroup_course) }
            end
          end
        end

        context "with subgroups" do
          before { calendar_group.update(with_subgroups: true) }

          it { is_expected.to include(layer_event) }
          it { is_expected.not_to include(layer_course) }
          it { is_expected.to include(subgroup_event) }
          it { is_expected.not_to include(subgroup_course) }
          it { is_expected.to include(subsubgroup_event) }
          it { is_expected.not_to include(subsubgroup_course) }

          context "with excluded calendar group" do
            let(:excluded_calendar_group) { Fabricate(:calendar_group, excluded: true, calendar: calendar) }

            context "layer" do
              before { excluded_calendar_group.update(group: layer) }

              context "excluding all event types" do
                before { excluded_calendar_group.update(event_type: nil) }

                context "excluding also subsubgroups" do
                  before { excluded_calendar_group.update(with_subgroups: true) }

                  it { is_expected.not_to include(layer_event) }
                  it { is_expected.not_to include(layer_course) }
                  it { is_expected.not_to include(subgroup_event) }
                  it { is_expected.not_to include(subgroup_course) }
                  it { is_expected.not_to include(subsubgroup_event) }
                  it { is_expected.not_to include(subsubgroup_course) }
                end

                context "not excluding subgroups" do
                  before { excluded_calendar_group.update(with_subgroups: false) }

                  it { is_expected.not_to include(layer_event) }
                  it { is_expected.not_to include(layer_course) }
                  it { is_expected.to include(subgroup_event) }
                  it { is_expected.not_to include(subgroup_course) }
                  it { is_expected.to include(subsubgroup_event) }
                  it { is_expected.not_to include(subsubgroup_course) }
                end
              end

              context "excluding only plain events" do
                before { excluded_calendar_group.update(event_type: Event.name) }

                context "excluding also subsubgroups" do
                  before { excluded_calendar_group.update(with_subgroups: true) }

                  it { is_expected.not_to include(layer_event) }
                  it { is_expected.not_to include(layer_course) }
                  it { is_expected.not_to include(subgroup_event) }
                  it { is_expected.not_to include(subgroup_course) }
                  it { is_expected.not_to include(subsubgroup_event) }
                  it { is_expected.not_to include(subsubgroup_course) }
                end

                context "not excluding subgroups" do
                  before { excluded_calendar_group.update(with_subgroups: false) }

                  it { is_expected.not_to include(layer_event) }
                  it { is_expected.not_to include(layer_course) }
                  it { is_expected.to include(subgroup_event) }
                  it { is_expected.not_to include(subgroup_course) }
                  it { is_expected.to include(subsubgroup_event) }
                  it { is_expected.not_to include(subsubgroup_course) }
                end
              end

              context "excluding only courses" do
                before { excluded_calendar_group.update(event_type: Event::Course.name) }

                context "excluding also subgroups" do
                  before { excluded_calendar_group.update(with_subgroups: true) }

                  it { is_expected.to include(layer_event) }
                  it { is_expected.not_to include(layer_course) }
                  it { is_expected.to include(subgroup_event) }
                  it { is_expected.not_to include(subgroup_course) }
                  it { is_expected.to include(subsubgroup_event) }
                  it { is_expected.not_to include(subsubgroup_course) }
                end

                context "not excluding subgroups" do
                  before { excluded_calendar_group.update(with_subgroups: false) }

                  it { is_expected.to include(layer_event) }
                  it { is_expected.not_to include(layer_course) }
                  it { is_expected.to include(subgroup_event) }
                  it { is_expected.not_to include(subgroup_course) }
                  it { is_expected.to include(subsubgroup_event) }
                  it { is_expected.not_to include(subsubgroup_course) }
                end
              end
            end

            context "subgroup" do
              before { excluded_calendar_group.update(group: subgroup) }

              context "excluding all event types" do
                before { excluded_calendar_group.update(event_type: nil) }

                context "excluding also subsubgroups" do
                  before { excluded_calendar_group.update(with_subgroups: true) }

                  it { is_expected.to include(layer_event) }
                  it { is_expected.not_to include(layer_course) }
                  it { is_expected.not_to include(subgroup_event) }
                  it { is_expected.not_to include(subgroup_course) }
                  it { is_expected.not_to include(subsubgroup_event) }
                  it { is_expected.not_to include(subsubgroup_course) }
                end

                context "not excluding subsubgroups" do
                  before { excluded_calendar_group.update(with_subgroups: false) }

                  it { is_expected.to include(layer_event) }
                  it { is_expected.not_to include(layer_course) }
                  it { is_expected.not_to include(subgroup_event) }
                  it { is_expected.not_to include(subgroup_course) }
                  it { is_expected.to include(subsubgroup_event) }
                  it { is_expected.not_to include(subsubgroup_course) }
                end
              end

              context "excluding only plain events" do
                before { excluded_calendar_group.update(event_type: Event.name) }

                context "excluding also subsubgroups" do
                  before { excluded_calendar_group.update(with_subgroups: true) }

                  it { is_expected.to include(layer_event) }
                  it { is_expected.not_to include(layer_course) }
                  it { is_expected.not_to include(subgroup_event) }
                  it { is_expected.not_to include(subgroup_course) }
                  it { is_expected.not_to include(subsubgroup_event) }
                  it { is_expected.not_to include(subsubgroup_course) }
                end

                context "not excluding subsubgroups" do
                  before { excluded_calendar_group.update(with_subgroups: false) }

                  it { is_expected.to include(layer_event) }
                  it { is_expected.not_to include(layer_course) }
                  it { is_expected.not_to include(subgroup_event) }
                  it { is_expected.not_to include(subgroup_course) }
                  it { is_expected.to include(subsubgroup_event) }
                  it { is_expected.not_to include(subsubgroup_course) }
                end
              end

              context "excluding only courses makes no difference" do
                before { excluded_calendar_group.update(event_type: Event::Course.name, with_subgroups: true) }

                it { is_expected.to include(layer_event) }
                it { is_expected.not_to include(layer_course) }
                it { is_expected.to include(subgroup_event) }
                it { is_expected.not_to include(subgroup_course) }
                it { is_expected.to include(subsubgroup_event) }
                it { is_expected.not_to include(subsubgroup_course) }
              end
            end
          end
        end
      end

      context "including only courses" do
        before { calendar_group.update(event_type: Event::Course.name) }

        context "without subgroups" do
          before { calendar_group.update(with_subgroups: false) }

          it { is_expected.not_to include(layer_event) }
          it { is_expected.to include(layer_course) }
          it { is_expected.not_to include(subgroup_event) }
          it { is_expected.not_to include(subgroup_course) }
          it { is_expected.not_to include(subsubgroup_event) }
          it { is_expected.not_to include(subsubgroup_course) }

          context "with excluded calendar group" do
            let(:excluded_calendar_group) { Fabricate(:calendar_group, excluded: true, calendar: calendar) }

            context "layer" do
              before { excluded_calendar_group.update(group: layer) }

              context "excluding all event types" do
                before { excluded_calendar_group.update(event_type: nil) }

                context "excluding also subgroups" do
                  before { excluded_calendar_group.update(with_subgroups: true) }

                  it { is_expected.not_to include(layer_event) }
                  it { is_expected.not_to include(layer_course) }
                  it { is_expected.not_to include(subgroup_event) }
                  it { is_expected.not_to include(subgroup_course) }
                  it { is_expected.not_to include(subsubgroup_event) }
                  it { is_expected.not_to include(subsubgroup_course) }
                end

                context "not excluding subgroups" do
                  before { excluded_calendar_group.update(with_subgroups: false) }

                  it { is_expected.not_to include(layer_event) }
                  it { is_expected.not_to include(layer_course) }
                  it { is_expected.not_to include(subgroup_event) }
                  it { is_expected.not_to include(subgroup_course) }
                  it { is_expected.not_to include(subsubgroup_event) }
                  it { is_expected.not_to include(subsubgroup_course) }
                end
              end

              context "excluding only plain events makes no difference" do
                before { excluded_calendar_group.update(event_type: Event.name, with_subgroups: true) }

                it { is_expected.not_to include(layer_event) }
                it { is_expected.to include(layer_course) }
                it { is_expected.not_to include(subgroup_event) }
                it { is_expected.not_to include(subgroup_course) }
                it { is_expected.not_to include(subsubgroup_event) }
                it { is_expected.not_to include(subsubgroup_course) }
              end

              context "excluding only courses" do
                before { excluded_calendar_group.update(event_type: Event::Course.name) }

                context "excluding also subgroups" do
                  before { excluded_calendar_group.update(with_subgroups: true) }

                  it { is_expected.not_to include(layer_event) }
                  it { is_expected.not_to include(layer_course) }
                  it { is_expected.not_to include(subgroup_event) }
                  it { is_expected.not_to include(subgroup_course) }
                  it { is_expected.not_to include(subsubgroup_event) }
                  it { is_expected.not_to include(subsubgroup_course) }
                end

                context "not excluding subgroups" do
                  before { excluded_calendar_group.update(with_subgroups: false) }

                  it { is_expected.not_to include(layer_event) }
                  it { is_expected.not_to include(layer_course) }
                  it { is_expected.not_to include(subgroup_event) }
                  it { is_expected.not_to include(subgroup_course) }
                  it { is_expected.not_to include(subsubgroup_event) }
                  it { is_expected.not_to include(subsubgroup_course) }
                end
              end
            end

            context "subgroup makes no difference" do
              before { excluded_calendar_group.update(group: subgroup, event_type: nil, with_subgroups: true) }

              it { is_expected.not_to include(layer_event) }
              it { is_expected.to include(layer_course) }
              it { is_expected.not_to include(subgroup_event) }
              it { is_expected.not_to include(subgroup_course) }
              it { is_expected.not_to include(subsubgroup_event) }
              it { is_expected.not_to include(subsubgroup_course) }
            end
          end
        end

        context "with subgroups" do
          before { calendar_group.update(with_subgroups: true) }

          it { is_expected.not_to include(layer_event) }
          it { is_expected.to include(layer_course) }
          it { is_expected.not_to include(subgroup_event) }
          it { is_expected.to include(subgroup_course) }
          it { is_expected.not_to include(subsubgroup_event) }
          it { is_expected.to include(subsubgroup_course) }

          context "with excluded calendar group" do
            let(:excluded_calendar_group) { Fabricate(:calendar_group, excluded: true, calendar: calendar) }

            context "layer" do
              before { excluded_calendar_group.update(group: layer) }

              context "excluding all event types" do
                before { excluded_calendar_group.update(event_type: nil) }

                context "excluding also subgroups" do
                  before { excluded_calendar_group.update(with_subgroups: true) }

                  it { is_expected.not_to include(layer_event) }
                  it { is_expected.not_to include(layer_course) }
                  it { is_expected.not_to include(subgroup_event) }
                  it { is_expected.not_to include(subgroup_course) }
                  it { is_expected.not_to include(subsubgroup_event) }
                  it { is_expected.not_to include(subsubgroup_course) }
                end

                context "not excluding subgroups" do
                  before { excluded_calendar_group.update(with_subgroups: false) }

                  it { is_expected.not_to include(layer_event) }
                  it { is_expected.not_to include(layer_course) }
                  it { is_expected.not_to include(subgroup_event) }
                  it { is_expected.to include(subgroup_course) }
                  it { is_expected.not_to include(subsubgroup_event) }
                  it { is_expected.to include(subsubgroup_course) }
                end
              end

              context "excluding only plain events" do
                before { excluded_calendar_group.update(event_type: Event.name) }

                context "excluding also subgroups" do
                  before { excluded_calendar_group.update(with_subgroups: true) }

                  it { is_expected.not_to include(layer_event) }
                  it { is_expected.to include(layer_course) }
                  it { is_expected.not_to include(subgroup_event) }
                  it { is_expected.to include(subgroup_course) }
                  it { is_expected.not_to include(subsubgroup_event) }
                  it { is_expected.to include(subsubgroup_course) }
                end

                context "not excluding subgroups" do
                  before { excluded_calendar_group.update(with_subgroups: false) }

                  it { is_expected.not_to include(layer_event) }
                  it { is_expected.to include(layer_course) }
                  it { is_expected.not_to include(subgroup_event) }
                  it { is_expected.to include(subgroup_course) }
                  it { is_expected.not_to include(subsubgroup_event) }
                  it { is_expected.to include(subsubgroup_course) }
                end
              end

              context "excluding only courses" do
                before { excluded_calendar_group.update(event_type: Event::Course.name) }

                context "excluding also subgroups" do
                  before { excluded_calendar_group.update(with_subgroups: true) }

                  it { is_expected.not_to include(layer_event) }
                  it { is_expected.not_to include(layer_course) }
                  it { is_expected.not_to include(subgroup_event) }
                  it { is_expected.not_to include(subgroup_course) }
                  it { is_expected.not_to include(subsubgroup_event) }
                  it { is_expected.not_to include(subsubgroup_course) }
                end

                context "not excluding subgroups" do
                  before { excluded_calendar_group.update(with_subgroups: false) }

                  it { is_expected.not_to include(layer_event) }
                  it { is_expected.not_to include(layer_course) }
                  it { is_expected.not_to include(subgroup_event) }
                  it { is_expected.to include(subgroup_course) }
                  it { is_expected.not_to include(subsubgroup_event) }
                  it { is_expected.to include(subsubgroup_course) }
                end
              end
            end

            context "subgroup" do
              before { excluded_calendar_group.update(group: subgroup) }

              context "excluding all event types" do
                before { excluded_calendar_group.update(event_type: nil) }

                context "excluding also subsubgroups" do
                  before { excluded_calendar_group.update(with_subgroups: true) }

                  it { is_expected.not_to include(layer_event) }
                  it { is_expected.to include(layer_course) }
                  it { is_expected.not_to include(subgroup_event) }
                  it { is_expected.not_to include(subgroup_course) }
                  it { is_expected.not_to include(subsubgroup_event) }
                  it { is_expected.not_to include(subsubgroup_course) }
                end

                context "not excluding subsubgroups" do
                  before { excluded_calendar_group.update(with_subgroups: false) }

                  it { is_expected.not_to include(layer_event) }
                  it { is_expected.to include(layer_course) }
                  it { is_expected.not_to include(subgroup_event) }
                  it { is_expected.not_to include(subgroup_course) }
                  it { is_expected.not_to include(subsubgroup_event) }
                  it { is_expected.to include(subsubgroup_course) }
                end
              end

              context "excluding only plain events makes no difference" do
                before { excluded_calendar_group.update(event_type: Event.name, with_subgroups: true) }

                it { is_expected.not_to include(layer_event) }
                it { is_expected.to include(layer_course) }
                it { is_expected.not_to include(subgroup_event) }
                it { is_expected.to include(subgroup_course) }
                it { is_expected.not_to include(subsubgroup_event) }
                it { is_expected.to include(subsubgroup_course) }
              end

              context "excluding only courses" do
                before { excluded_calendar_group.update(event_type: Event::Course.name) }

                context "excluding also subsubgroups" do
                  before { excluded_calendar_group.update(with_subgroups: true) }

                  it { is_expected.not_to include(layer_event) }
                  it { is_expected.to include(layer_course) }
                  it { is_expected.not_to include(subgroup_event) }
                  it { is_expected.not_to include(subgroup_course) }
                  it { is_expected.not_to include(subsubgroup_event) }
                  it { is_expected.not_to include(subsubgroup_course) }
                end

                context "not excluding subsubgroups" do
                  before { excluded_calendar_group.update(with_subgroups: false) }

                  it { is_expected.not_to include(layer_event) }
                  it { is_expected.to include(layer_course) }
                  it { is_expected.not_to include(subgroup_event) }
                  it { is_expected.not_to include(subgroup_course) }
                  it { is_expected.not_to include(subsubgroup_event) }
                  it { is_expected.to include(subsubgroup_course) }
                end
              end
            end
          end
        end
      end
    end

    context "subgroup" do
      let!(:calendar_group) { calendar.included_calendar_groups.first.tap { |g| g.update(group: subgroup) } }

      context "including all event types" do
        before { calendar_group.update(event_type: nil) }

        context "without subsubgroups" do
          before { calendar_group.update(with_subgroups: false) }

          it { is_expected.not_to include(layer_event) }
          it { is_expected.not_to include(layer_course) }
          it { is_expected.to include(subgroup_event) }
          it { is_expected.to include(subgroup_course) }
          it { is_expected.not_to include(subsubgroup_event) }
          it { is_expected.not_to include(subsubgroup_course) }

          context "with excluded calendar group" do
            let(:excluded_calendar_group) { Fabricate(:calendar_group, excluded: true, calendar: calendar) }

            context "layer" do
              before { excluded_calendar_group.update(group: layer) }

              context "excluding all event types" do
                before { excluded_calendar_group.update(event_type: nil) }

                context "excluding also subgroups" do
                  before { excluded_calendar_group.update(with_subgroups: true) }

                  it { is_expected.not_to include(layer_event) }
                  it { is_expected.not_to include(layer_course) }
                  it { is_expected.not_to include(subgroup_event) }
                  it { is_expected.not_to include(subgroup_course) }
                  it { is_expected.not_to include(subsubgroup_event) }
                  it { is_expected.not_to include(subsubgroup_course) }
                end

                context "not excluding subgroups" do
                  before { excluded_calendar_group.update(with_subgroups: false) }

                  it { is_expected.not_to include(layer_event) }
                  it { is_expected.not_to include(layer_course) }
                  it { is_expected.to include(subgroup_event) }
                  it { is_expected.to include(subgroup_course) }
                  it { is_expected.not_to include(subsubgroup_event) }
                  it { is_expected.not_to include(subsubgroup_course) }
                end
              end

              context "excluding only plain events" do
                before { excluded_calendar_group.update(event_type: Event.name) }

                context "excluding also subgroups" do
                  before { excluded_calendar_group.update(with_subgroups: true) }

                  it { is_expected.not_to include(layer_event) }
                  it { is_expected.not_to include(layer_course) }
                  it { is_expected.not_to include(subgroup_event) }
                  it { is_expected.to include(subgroup_course) }
                  it { is_expected.not_to include(subsubgroup_event) }
                  it { is_expected.not_to include(subsubgroup_course) }
                end

                context "not excluding subgroups" do
                  before { excluded_calendar_group.update(with_subgroups: false) }

                  it { is_expected.not_to include(layer_event) }
                  it { is_expected.not_to include(layer_course) }
                  it { is_expected.to include(subgroup_event) }
                  it { is_expected.to include(subgroup_course) }
                  it { is_expected.not_to include(subsubgroup_event) }
                  it { is_expected.not_to include(subsubgroup_course) }
                end
              end

              context "excluding only courses" do
                before { excluded_calendar_group.update(event_type: Event::Course.name) }

                context "excluding also subgroups" do
                  before { excluded_calendar_group.update(with_subgroups: true) }

                  it { is_expected.not_to include(layer_event) }
                  it { is_expected.not_to include(layer_course) }
                  it { is_expected.to include(subgroup_event) }
                  it { is_expected.not_to include(subgroup_course) }
                  it { is_expected.not_to include(subsubgroup_event) }
                  it { is_expected.not_to include(subsubgroup_course) }
                end

                context "not excluding subgroups" do
                  before { excluded_calendar_group.update(with_subgroups: false) }

                  it { is_expected.not_to include(layer_event) }
                  it { is_expected.not_to include(layer_course) }
                  it { is_expected.to include(subgroup_event) }
                  it { is_expected.to include(subgroup_course) }
                  it { is_expected.not_to include(subsubgroup_event) }
                  it { is_expected.not_to include(subsubgroup_course) }
                end
              end
            end

            context "subgroup" do
              before { excluded_calendar_group.update(group: subgroup) }

              context "excluding all event types" do
                before { excluded_calendar_group.update(event_type: nil) }

                context "excluding also subsubgroups" do
                  before { excluded_calendar_group.update(with_subgroups: true) }

                  it { is_expected.not_to include(layer_event) }
                  it { is_expected.not_to include(layer_course) }
                  it { is_expected.not_to include(subgroup_event) }
                  it { is_expected.not_to include(subgroup_course) }
                  it { is_expected.not_to include(subsubgroup_event) }
                  it { is_expected.not_to include(subsubgroup_course) }
                end

                context "not excluding subsubgroups" do
                  before { excluded_calendar_group.update(with_subgroups: false) }

                  it { is_expected.not_to include(layer_event) }
                  it { is_expected.not_to include(layer_course) }
                  it { is_expected.not_to include(subgroup_event) }
                  it { is_expected.not_to include(subgroup_course) }
                  it { is_expected.not_to include(subsubgroup_event) }
                  it { is_expected.not_to include(subsubgroup_course) }
                end
              end

              context "excluding only plain events" do
                before { excluded_calendar_group.update(event_type: Event.name) }

                context "excluding also subsubgroups" do
                  before { excluded_calendar_group.update(with_subgroups: true) }

                  it { is_expected.not_to include(layer_event) }
                  it { is_expected.not_to include(layer_course) }
                  it { is_expected.not_to include(subgroup_event) }
                  it { is_expected.to include(subgroup_course) }
                  it { is_expected.not_to include(subsubgroup_event) }
                  it { is_expected.not_to include(subsubgroup_course) }
                end

                context "not excluding subsubgroups" do
                  before { excluded_calendar_group.update(with_subgroups: false) }

                  it { is_expected.not_to include(layer_event) }
                  it { is_expected.not_to include(layer_course) }
                  it { is_expected.not_to include(subgroup_event) }
                  it { is_expected.to include(subgroup_course) }
                  it { is_expected.not_to include(subsubgroup_event) }
                  it { is_expected.not_to include(subsubgroup_course) }
                end
              end

              context "excluding only courses" do
                before { excluded_calendar_group.update(event_type: Event::Course.name) }

                context "excluding also subsubgroups" do
                  before { excluded_calendar_group.update(with_subgroups: true) }

                  it { is_expected.not_to include(layer_event) }
                  it { is_expected.not_to include(layer_course) }
                  it { is_expected.to include(subgroup_event) }
                  it { is_expected.not_to include(subgroup_course) }
                  it { is_expected.not_to include(subsubgroup_event) }
                  it { is_expected.not_to include(subsubgroup_course) }
                end

                context "not excluding subsubgroups" do
                  before { excluded_calendar_group.update(with_subgroups: false) }

                  it { is_expected.not_to include(layer_event) }
                  it { is_expected.not_to include(layer_course) }
                  it { is_expected.to include(subgroup_event) }
                  it { is_expected.not_to include(subgroup_course) }
                  it { is_expected.not_to include(subsubgroup_event) }
                  it { is_expected.not_to include(subsubgroup_course) }
                end
              end
            end

            context "subsubgroup makes no difference" do
              before { excluded_calendar_group.update(group: subsubgroup, event_type: nil, with_subgroups: true) }

              it { is_expected.not_to include(layer_event) }
              it { is_expected.not_to include(layer_course) }
              it { is_expected.to include(subgroup_event) }
              it { is_expected.to include(subgroup_course) }
              it { is_expected.not_to include(subsubgroup_event) }
              it { is_expected.not_to include(subsubgroup_course) }
            end
          end
        end

        context "with subsubgroups" do
          before { calendar_group.update(with_subgroups: true) }

          it { is_expected.not_to include(layer_event) }
          it { is_expected.not_to include(layer_course) }
          it { is_expected.to include(subgroup_event) }
          it { is_expected.to include(subgroup_course) }
          it { is_expected.to include(subsubgroup_event) }
          it { is_expected.to include(subsubgroup_course) }

          context "with excluded calendar group" do
            let(:excluded_calendar_group) { Fabricate(:calendar_group, excluded: true, calendar: calendar) }

            context "layer" do
              before { excluded_calendar_group.update(group: layer) }

              context "excluding all event types" do
                before { excluded_calendar_group.update(event_type: nil) }

                context "excluding also subgroups" do
                  before { excluded_calendar_group.update(with_subgroups: true) }

                  it { is_expected.not_to include(layer_event) }
                  it { is_expected.not_to include(layer_course) }
                  it { is_expected.not_to include(subgroup_event) }
                  it { is_expected.not_to include(subgroup_course) }
                  it { is_expected.not_to include(subsubgroup_event) }
                  it { is_expected.not_to include(subsubgroup_course) }
                end

                context "not excluding subgroups" do
                  before { excluded_calendar_group.update(with_subgroups: false) }

                  it { is_expected.not_to include(layer_event) }
                  it { is_expected.not_to include(layer_course) }
                  it { is_expected.to include(subgroup_event) }
                  it { is_expected.to include(subgroup_course) }
                  it { is_expected.to include(subsubgroup_event) }
                  it { is_expected.to include(subsubgroup_course) }
                end
              end

              context "excluding only plain events" do
                before { excluded_calendar_group.update(event_type: Event.name) }

                context "excluding also subgroups" do
                  before { excluded_calendar_group.update(with_subgroups: true) }

                  it { is_expected.not_to include(layer_event) }
                  it { is_expected.not_to include(layer_course) }
                  it { is_expected.not_to include(subgroup_event) }
                  it { is_expected.to include(subgroup_course) }
                  it { is_expected.not_to include(subsubgroup_event) }
                  it { is_expected.to include(subsubgroup_course) }
                end

                context "not excluding subgroups" do
                  before { excluded_calendar_group.update(with_subgroups: false) }

                  it { is_expected.not_to include(layer_event) }
                  it { is_expected.not_to include(layer_course) }
                  it { is_expected.to include(subgroup_event) }
                  it { is_expected.to include(subgroup_course) }
                  it { is_expected.to include(subsubgroup_event) }
                  it { is_expected.to include(subsubgroup_course) }
                end
              end

              context "excluding only courses" do
                before { excluded_calendar_group.update(event_type: Event::Course.name) }

                context "excluding also subgroups" do
                  before { excluded_calendar_group.update(with_subgroups: true) }

                  it { is_expected.not_to include(layer_event) }
                  it { is_expected.not_to include(layer_course) }
                  it { is_expected.to include(subgroup_event) }
                  it { is_expected.not_to include(subgroup_course) }
                  it { is_expected.to include(subsubgroup_event) }
                  it { is_expected.not_to include(subsubgroup_course) }
                end

                context "not excluding subgroups" do
                  before { excluded_calendar_group.update(with_subgroups: false) }

                  it { is_expected.not_to include(layer_event) }
                  it { is_expected.not_to include(layer_course) }
                  it { is_expected.to include(subgroup_event) }
                  it { is_expected.to include(subgroup_course) }
                  it { is_expected.to include(subsubgroup_event) }
                  it { is_expected.to include(subsubgroup_course) }
                end
              end
            end

            context "subgroup" do
              before { excluded_calendar_group.update(group: subgroup) }

              context "excluding all event types" do
                before { excluded_calendar_group.update(event_type: nil) }

                context "excluding also subsubgroups" do
                  before { excluded_calendar_group.update(with_subgroups: true) }

                  it { is_expected.not_to include(layer_event) }
                  it { is_expected.not_to include(layer_course) }
                  it { is_expected.not_to include(subgroup_event) }
                  it { is_expected.not_to include(subgroup_course) }
                  it { is_expected.not_to include(subsubgroup_event) }
                  it { is_expected.not_to include(subsubgroup_course) }
                end

                context "not excluding subsubgroups" do
                  before { excluded_calendar_group.update(with_subgroups: false) }

                  it { is_expected.not_to include(layer_event) }
                  it { is_expected.not_to include(layer_course) }
                  it { is_expected.not_to include(subgroup_event) }
                  it { is_expected.not_to include(subgroup_course) }
                  it { is_expected.to include(subsubgroup_event) }
                  it { is_expected.to include(subsubgroup_course) }
                end
              end

              context "excluding only plain events" do
                before { excluded_calendar_group.update(event_type: Event.name) }

                context "excluding also subsubgroups" do
                  before { excluded_calendar_group.update(with_subgroups: true) }

                  it { is_expected.not_to include(layer_event) }
                  it { is_expected.not_to include(layer_course) }
                  it { is_expected.not_to include(subgroup_event) }
                  it { is_expected.to include(subgroup_course) }
                  it { is_expected.not_to include(subsubgroup_event) }
                  it { is_expected.to include(subsubgroup_course) }
                end

                context "not excluding subsubgroups" do
                  before { excluded_calendar_group.update(with_subgroups: false) }

                  it { is_expected.not_to include(layer_event) }
                  it { is_expected.not_to include(layer_course) }
                  it { is_expected.not_to include(subgroup_event) }
                  it { is_expected.to include(subgroup_course) }
                  it { is_expected.to include(subsubgroup_event) }
                  it { is_expected.to include(subsubgroup_course) }
                end
              end

              context "excluding only courses" do
                before { excluded_calendar_group.update(event_type: Event::Course.name) }

                context "excluding also subsubgroups" do
                  before { excluded_calendar_group.update(with_subgroups: true) }

                  it { is_expected.not_to include(layer_event) }
                  it { is_expected.not_to include(layer_course) }
                  it { is_expected.to include(subgroup_event) }
                  it { is_expected.not_to include(subgroup_course) }
                  it { is_expected.to include(subsubgroup_event) }
                  it { is_expected.not_to include(subsubgroup_course) }
                end

                context "not excluding subsubgroups" do
                  before { excluded_calendar_group.update(with_subgroups: false) }

                  it { is_expected.not_to include(layer_event) }
                  it { is_expected.not_to include(layer_course) }
                  it { is_expected.to include(subgroup_event) }
                  it { is_expected.not_to include(subgroup_course) }
                  it { is_expected.to include(subsubgroup_event) }
                  it { is_expected.to include(subsubgroup_course) }
                end
              end
            end

            context "subsubgroup" do
              before { excluded_calendar_group.update(group: subsubgroup) }

              context "excluding all event types" do
                before { excluded_calendar_group.update(event_type: nil) }

                it { is_expected.not_to include(layer_event) }
                it { is_expected.not_to include(layer_course) }
                it { is_expected.to include(subgroup_event) }
                it { is_expected.to include(subgroup_course) }
                it { is_expected.not_to include(subsubgroup_event) }
                it { is_expected.not_to include(subsubgroup_course) }
              end

              context "excluding only plain events" do
                before { excluded_calendar_group.update(event_type: Event.name) }

                it { is_expected.not_to include(layer_event) }
                it { is_expected.not_to include(layer_course) }
                it { is_expected.to include(subgroup_event) }
                it { is_expected.to include(subgroup_course) }
                it { is_expected.not_to include(subsubgroup_event) }
                it { is_expected.to include(subsubgroup_course) }
              end

              context "excluding only courses" do
                before { excluded_calendar_group.update(event_type: Event::Course.name) }

                it { is_expected.not_to include(layer_event) }
                it { is_expected.not_to include(layer_course) }
                it { is_expected.to include(subgroup_event) }
                it { is_expected.to include(subgroup_course) }
                it { is_expected.to include(subsubgroup_event) }
                it { is_expected.not_to include(subsubgroup_course) }
              end
            end
          end
        end
      end

      context "including only plain events" do
        before { calendar_group.update(event_type: Event.name) }

        context "without subgroups" do
          before do
            calendar_group.update(with_subgroups: false)
          end

          it { is_expected.not_to include(layer_event) }
          it { is_expected.not_to include(layer_course) }
          it { is_expected.to include(subgroup_event) }
          it { is_expected.not_to include(subgroup_course) }
          it { is_expected.not_to include(subsubgroup_event) }
          it { is_expected.not_to include(subsubgroup_course) }

          context "with excluded calendar group" do
            let(:excluded_calendar_group) { Fabricate(:calendar_group, excluded: true, calendar: calendar) }

            context "layer" do
              before { excluded_calendar_group.update(group: layer) }

              context "excluding all event types" do
                before { excluded_calendar_group.update(event_type: nil) }

                context "excluding also subgroups" do
                  before { excluded_calendar_group.update(with_subgroups: true) }

                  it { is_expected.not_to include(layer_event) }
                  it { is_expected.not_to include(layer_course) }
                  it { is_expected.not_to include(subgroup_event) }
                  it { is_expected.not_to include(subgroup_course) }
                  it { is_expected.not_to include(subsubgroup_event) }
                  it { is_expected.not_to include(subsubgroup_course) }
                end

                context "not excluding subgroups" do
                  before { excluded_calendar_group.update(with_subgroups: false) }

                  it { is_expected.not_to include(layer_event) }
                  it { is_expected.not_to include(layer_course) }
                  it { is_expected.to include(subgroup_event) }
                  it { is_expected.not_to include(subgroup_course) }
                  it { is_expected.not_to include(subsubgroup_event) }
                  it { is_expected.not_to include(subsubgroup_course) }
                end
              end

              context "excluding only plain events" do
                before { excluded_calendar_group.update(event_type: Event.name) }

                context "excluding also subgroups" do
                  before { excluded_calendar_group.update(with_subgroups: true) }

                  it { is_expected.not_to include(layer_event) }
                  it { is_expected.not_to include(layer_course) }
                  it { is_expected.not_to include(subgroup_event) }
                  it { is_expected.not_to include(subgroup_course) }
                  it { is_expected.not_to include(subsubgroup_event) }
                  it { is_expected.not_to include(subsubgroup_course) }
                end

                context "not excluding subgroups" do
                  before { excluded_calendar_group.update(with_subgroups: false) }

                  it { is_expected.not_to include(layer_event) }
                  it { is_expected.not_to include(layer_course) }
                  it { is_expected.to include(subgroup_event) }
                  it { is_expected.not_to include(subgroup_course) }
                  it { is_expected.not_to include(subsubgroup_event) }
                  it { is_expected.not_to include(subsubgroup_course) }
                end
              end

              context "excluding only courses makes no difference" do
                before { excluded_calendar_group.update(event_type: Event::Course.name, with_subgroups: true) }

                it { is_expected.not_to include(layer_event) }
                it { is_expected.not_to include(layer_course) }
                it { is_expected.to include(subgroup_event) }
                it { is_expected.not_to include(subgroup_course) }
                it { is_expected.not_to include(subsubgroup_event) }
                it { is_expected.not_to include(subsubgroup_course) }
              end
            end

            context "subgroup" do
              before { excluded_calendar_group.update(group: subgroup) }

              context "excluding all event types" do
                before { excluded_calendar_group.update(event_type: nil) }

                context "excluding also subsubgroups" do
                  before { excluded_calendar_group.update(with_subgroups: true) }

                  it { is_expected.not_to include(layer_event) }
                  it { is_expected.not_to include(layer_course) }
                  it { is_expected.not_to include(subgroup_event) }
                  it { is_expected.not_to include(subgroup_course) }
                  it { is_expected.not_to include(subsubgroup_event) }
                  it { is_expected.not_to include(subsubgroup_course) }
                end

                context "not excluding subsubgroups" do
                  before { excluded_calendar_group.update(with_subgroups: false) }

                  it { is_expected.not_to include(layer_event) }
                  it { is_expected.not_to include(layer_course) }
                  it { is_expected.not_to include(subgroup_event) }
                  it { is_expected.not_to include(subgroup_course) }
                  it { is_expected.not_to include(subsubgroup_event) }
                  it { is_expected.not_to include(subsubgroup_course) }
                end
              end

              context "excluding only plain events" do
                before { excluded_calendar_group.update(event_type: Event.name) }

                context "excluding also subsubgroups" do
                  before { excluded_calendar_group.update(with_subgroups: true) }

                  it { is_expected.not_to include(layer_event) }
                  it { is_expected.not_to include(layer_course) }
                  it { is_expected.not_to include(subgroup_event) }
                  it { is_expected.not_to include(subgroup_course) }
                  it { is_expected.not_to include(subsubgroup_event) }
                  it { is_expected.not_to include(subsubgroup_course) }
                end

                context "not excluding subsubgroups" do
                  before { excluded_calendar_group.update(with_subgroups: false) }

                  it { is_expected.not_to include(layer_event) }
                  it { is_expected.not_to include(layer_course) }
                  it { is_expected.not_to include(subgroup_event) }
                  it { is_expected.not_to include(subgroup_course) }
                  it { is_expected.not_to include(subsubgroup_event) }
                  it { is_expected.not_to include(subsubgroup_course) }
                end
              end

              context "excluding only courses makes no difference" do
                before { excluded_calendar_group.update(event_type: Event::Course.name, with_subgroups: true) }

                it { is_expected.not_to include(layer_event) }
                it { is_expected.not_to include(layer_course) }
                it { is_expected.to include(subgroup_event) }
                it { is_expected.not_to include(subgroup_course) }
                it { is_expected.not_to include(subsubgroup_event) }
                it { is_expected.not_to include(subsubgroup_course) }
              end
            end

            context "subsubgroup makes no difference" do
              before { excluded_calendar_group.update(group: subsubgroup, event_type: nil, with_subgroups: true) }

              it { is_expected.not_to include(layer_event) }
              it { is_expected.not_to include(layer_course) }
              it { is_expected.to include(subgroup_event) }
              it { is_expected.not_to include(subgroup_course) }
              it { is_expected.not_to include(subsubgroup_event) }
              it { is_expected.not_to include(subsubgroup_course) }
            end
          end
        end

        context "with subgroups" do
          before { calendar_group.update(with_subgroups: true) }

          it { is_expected.not_to include(layer_event) }
          it { is_expected.not_to include(layer_course) }
          it { is_expected.to include(subgroup_event) }
          it { is_expected.not_to include(subgroup_course) }
          it { is_expected.to include(subsubgroup_event) }
          it { is_expected.not_to include(subsubgroup_course) }

          context "with excluded calendar group" do
            let(:excluded_calendar_group) { Fabricate(:calendar_group, excluded: true, calendar: calendar) }

            context "layer" do
              before { excluded_calendar_group.update(group: layer) }

              context "excluding all event types" do
                before { excluded_calendar_group.update(event_type: nil) }

                context "excluding also subgroups" do
                  before { excluded_calendar_group.update(with_subgroups: true) }

                  it { is_expected.not_to include(layer_event) }
                  it { is_expected.not_to include(layer_course) }
                  it { is_expected.not_to include(subgroup_event) }
                  it { is_expected.not_to include(subgroup_course) }
                  it { is_expected.not_to include(subsubgroup_event) }
                  it { is_expected.not_to include(subsubgroup_course) }
                end

                context "not excluding subgroups" do
                  before { excluded_calendar_group.update(with_subgroups: false) }

                  it { is_expected.not_to include(layer_event) }
                  it { is_expected.not_to include(layer_course) }
                  it { is_expected.to include(subgroup_event) }
                  it { is_expected.not_to include(subgroup_course) }
                  it { is_expected.to include(subsubgroup_event) }
                  it { is_expected.not_to include(subsubgroup_course) }
                end
              end

              context "excluding only plain events" do
                before { excluded_calendar_group.update(event_type: Event.name) }

                context "excluding also subgroups" do
                  before { excluded_calendar_group.update(with_subgroups: true) }

                  it { is_expected.not_to include(layer_event) }
                  it { is_expected.not_to include(layer_course) }
                  it { is_expected.not_to include(subgroup_event) }
                  it { is_expected.not_to include(subgroup_course) }
                  it { is_expected.not_to include(subsubgroup_event) }
                  it { is_expected.not_to include(subsubgroup_course) }
                end

                context "not excluding subgroups" do
                  before { excluded_calendar_group.update(with_subgroups: false) }

                  it { is_expected.not_to include(layer_event) }
                  it { is_expected.not_to include(layer_course) }
                  it { is_expected.to include(subgroup_event) }
                  it { is_expected.not_to include(subgroup_course) }
                  it { is_expected.to include(subsubgroup_event) }
                  it { is_expected.not_to include(subsubgroup_course) }
                end
              end

              context "excluding only courses makes no difference" do
                before { excluded_calendar_group.update(event_type: Event::Course.name, with_subgroups: true) }

                it { is_expected.not_to include(layer_event) }
                it { is_expected.not_to include(layer_course) }
                it { is_expected.to include(subgroup_event) }
                it { is_expected.not_to include(subgroup_course) }
                it { is_expected.to include(subsubgroup_event) }
                it { is_expected.not_to include(subsubgroup_course) }
              end
            end

            context "subgroup" do
              before { excluded_calendar_group.update(group: subgroup) }

              context "excluding all event types" do
                before { excluded_calendar_group.update(event_type: nil) }

                context "excluding also subsubgroups" do
                  before { excluded_calendar_group.update(with_subgroups: true) }

                  it { is_expected.not_to include(layer_event) }
                  it { is_expected.not_to include(layer_course) }
                  it { is_expected.not_to include(subgroup_event) }
                  it { is_expected.not_to include(subgroup_course) }
                  it { is_expected.not_to include(subsubgroup_event) }
                  it { is_expected.not_to include(subsubgroup_course) }
                end

                context "not excluding subsubgroups" do
                  before { excluded_calendar_group.update(with_subgroups: false) }

                  it { is_expected.not_to include(layer_event) }
                  it { is_expected.not_to include(layer_course) }
                  it { is_expected.not_to include(subgroup_event) }
                  it { is_expected.not_to include(subgroup_course) }
                  it { is_expected.to include(subsubgroup_event) }
                  it { is_expected.not_to include(subsubgroup_course) }
                end
              end

              context "excluding only plain events" do
                before { excluded_calendar_group.update(event_type: Event.name) }

                context "excluding also subsubgroups" do
                  before { excluded_calendar_group.update(with_subgroups: true) }

                  it { is_expected.not_to include(layer_event) }
                  it { is_expected.not_to include(layer_course) }
                  it { is_expected.not_to include(subgroup_event) }
                  it { is_expected.not_to include(subgroup_course) }
                  it { is_expected.not_to include(subsubgroup_event) }
                  it { is_expected.not_to include(subsubgroup_course) }
                end

                context "not excluding subsubgroups" do
                  before { excluded_calendar_group.update(with_subgroups: false) }

                  it { is_expected.not_to include(layer_event) }
                  it { is_expected.not_to include(layer_course) }
                  it { is_expected.not_to include(subgroup_event) }
                  it { is_expected.not_to include(subgroup_course) }
                  it { is_expected.to include(subsubgroup_event) }
                  it { is_expected.not_to include(subsubgroup_course) }
                end
              end

              context "excluding only courses makes no difference" do
                before { excluded_calendar_group.update(event_type: Event::Course.name, with_subgroups: true) }

                it { is_expected.not_to include(layer_event) }
                it { is_expected.not_to include(layer_course) }
                it { is_expected.to include(subgroup_event) }
                it { is_expected.not_to include(subgroup_course) }
                it { is_expected.to include(subsubgroup_event) }
                it { is_expected.not_to include(subsubgroup_course) }
              end
            end

            context "subsubgroup" do
              before { excluded_calendar_group.update(group: subsubgroup) }

              context "excluding all event types" do
                before { excluded_calendar_group.update(event_type: nil) }

                it { is_expected.not_to include(layer_event) }
                it { is_expected.not_to include(layer_course) }
                it { is_expected.to include(subgroup_event) }
                it { is_expected.not_to include(subgroup_course) }
                it { is_expected.not_to include(subsubgroup_event) }
                it { is_expected.not_to include(subsubgroup_course) }
              end

              context "excluding only plain events" do
                before { excluded_calendar_group.update(event_type: Event.name) }

                it { is_expected.not_to include(layer_event) }
                it { is_expected.not_to include(layer_course) }
                it { is_expected.to include(subgroup_event) }
                it { is_expected.not_to include(subgroup_course) }
                it { is_expected.not_to include(subsubgroup_event) }
                it { is_expected.not_to include(subsubgroup_course) }
              end

              context "excluding only courses" do
                before { excluded_calendar_group.update(event_type: Event::Course.name) }

                it { is_expected.not_to include(layer_event) }
                it { is_expected.not_to include(layer_course) }
                it { is_expected.to include(subgroup_event) }
                it { is_expected.not_to include(subgroup_course) }
                it { is_expected.to include(subsubgroup_event) }
                it { is_expected.not_to include(subsubgroup_course) }
              end
            end
          end
        end
      end

      context "including only courses" do
        before { calendar_group.update(event_type: Event::Course.name) }

        context "without subgroups" do
          before { calendar_group.update(with_subgroups: false) }

          it { is_expected.not_to include(layer_event) }
          it { is_expected.not_to include(layer_course) }
          it { is_expected.not_to include(subgroup_event) }
          it { is_expected.to include(subgroup_course) }
          it { is_expected.not_to include(subsubgroup_event) }
          it { is_expected.not_to include(subsubgroup_course) }

          context "with excluded calendar group" do
            let(:excluded_calendar_group) { Fabricate(:calendar_group, excluded: true, calendar: calendar) }

            context "layer" do
              before { excluded_calendar_group.update(group: layer) }

              context "excluding all event types" do
                before { excluded_calendar_group.update(event_type: nil) }

                context "excluding also subgroups" do
                  before { excluded_calendar_group.update(with_subgroups: true) }

                  it { is_expected.not_to include(layer_event) }
                  it { is_expected.not_to include(layer_course) }
                  it { is_expected.not_to include(subgroup_event) }
                  it { is_expected.not_to include(subgroup_course) }
                  it { is_expected.not_to include(subsubgroup_event) }
                  it { is_expected.not_to include(subsubgroup_course) }
                end

                context "not excluding subgroups" do
                  before { excluded_calendar_group.update(with_subgroups: false) }

                  it { is_expected.not_to include(layer_event) }
                  it { is_expected.not_to include(layer_course) }
                  it { is_expected.not_to include(subgroup_event) }
                  it { is_expected.to include(subgroup_course) }
                  it { is_expected.not_to include(subsubgroup_event) }
                  it { is_expected.not_to include(subsubgroup_course) }
                end
              end

              context "excluding only plain events makes no difference" do
                it { is_expected.not_to include(layer_event) }
                it { is_expected.not_to include(layer_course) }
                it { is_expected.not_to include(subgroup_event) }
                it { is_expected.to include(subgroup_course) }
                it { is_expected.not_to include(subsubgroup_event) }
                it { is_expected.not_to include(subsubgroup_course) }
              end

              context "excluding only courses" do
                before { excluded_calendar_group.update(event_type: Event::Course.name) }

                context "excluding also subgroups" do
                  before { excluded_calendar_group.update(with_subgroups: true) }

                  it { is_expected.not_to include(layer_event) }
                  it { is_expected.not_to include(layer_course) }
                  it { is_expected.not_to include(subgroup_event) }
                  it { is_expected.not_to include(subgroup_course) }
                  it { is_expected.not_to include(subsubgroup_event) }
                  it { is_expected.not_to include(subsubgroup_course) }
                end

                context "not excluding subgroups" do
                  before { excluded_calendar_group.update(with_subgroups: false) }

                  it { is_expected.not_to include(layer_event) }
                  it { is_expected.not_to include(layer_course) }
                  it { is_expected.not_to include(subgroup_event) }
                  it { is_expected.to include(subgroup_course) }
                  it { is_expected.not_to include(subsubgroup_event) }
                  it { is_expected.not_to include(subsubgroup_course) }
                end
              end
            end

            context "subgroup" do
              before { excluded_calendar_group.update(group: subgroup) }

              context "excluding all event types" do
                before { excluded_calendar_group.update(event_type: nil) }

                context "excluding also subsubgroups" do
                  before { excluded_calendar_group.update(with_subgroups: true) }

                  it { is_expected.not_to include(layer_event) }
                  it { is_expected.not_to include(layer_course) }
                  it { is_expected.not_to include(subgroup_event) }
                  it { is_expected.not_to include(subgroup_course) }
                  it { is_expected.not_to include(subsubgroup_event) }
                  it { is_expected.not_to include(subsubgroup_course) }
                end

                context "not excluding subsubgroups" do
                  before { excluded_calendar_group.update(with_subgroups: false) }

                  it { is_expected.not_to include(layer_event) }
                  it { is_expected.not_to include(layer_course) }
                  it { is_expected.not_to include(subgroup_event) }
                  it { is_expected.not_to include(subgroup_course) }
                  it { is_expected.not_to include(subsubgroup_event) }
                  it { is_expected.not_to include(subsubgroup_course) }
                end
              end

              context "excluding only plain events makes no difference" do
                before { excluded_calendar_group.update(event_type: Event.name, with_subgroups: true) }

                it { is_expected.not_to include(layer_event) }
                it { is_expected.not_to include(layer_course) }
                it { is_expected.not_to include(subgroup_event) }
                it { is_expected.to include(subgroup_course) }
                it { is_expected.not_to include(subsubgroup_event) }
                it { is_expected.not_to include(subsubgroup_course) }
              end

              context "excluding only courses" do
                before { excluded_calendar_group.update(event_type: Event::Course.name) }

                context "excluding also subsubgroups" do
                  before { excluded_calendar_group.update(with_subgroups: true) }

                  it { is_expected.not_to include(layer_event) }
                  it { is_expected.not_to include(layer_course) }
                  it { is_expected.not_to include(subgroup_event) }
                  it { is_expected.not_to include(subgroup_course) }
                  it { is_expected.not_to include(subsubgroup_event) }
                  it { is_expected.not_to include(subsubgroup_course) }
                end

                context "not excluding subsubgroups" do
                  before { excluded_calendar_group.update(with_subgroups: false) }

                  it { is_expected.not_to include(layer_event) }
                  it { is_expected.not_to include(layer_course) }
                  it { is_expected.not_to include(subgroup_event) }
                  it { is_expected.not_to include(subgroup_course) }
                  it { is_expected.not_to include(subsubgroup_event) }
                  it { is_expected.not_to include(subsubgroup_course) }
                end
              end
            end

            context "subsubgroup makes no difference" do
              before { excluded_calendar_group.update(group: subsubgroup, event_type: nil, with_subgroups: true) }

              it { is_expected.not_to include(layer_event) }
              it { is_expected.not_to include(layer_course) }
              it { is_expected.not_to include(subgroup_event) }
              it { is_expected.to include(subgroup_course) }
              it { is_expected.not_to include(subsubgroup_event) }
              it { is_expected.not_to include(subsubgroup_course) }
            end
          end
        end

        context "with subgroups" do
          before { calendar_group.update(with_subgroups: true) }

          it { is_expected.not_to include(layer_event) }
          it { is_expected.not_to include(layer_course) }
          it { is_expected.not_to include(subgroup_event) }
          it { is_expected.to include(subgroup_course) }
          it { is_expected.not_to include(subsubgroup_event) }
          it { is_expected.to include(subsubgroup_course) }

          context "with excluded calendar group" do
            let(:excluded_calendar_group) { Fabricate(:calendar_group, excluded: true, calendar: calendar) }

            context "layer" do
              before { excluded_calendar_group.update(group: layer) }

              context "excluding all event types" do
                before { excluded_calendar_group.update(event_type: nil) }

                context "excluding also subgroups" do
                  before { excluded_calendar_group.update(with_subgroups: true) }

                  it { is_expected.not_to include(layer_event) }
                  it { is_expected.not_to include(layer_course) }
                  it { is_expected.not_to include(subgroup_event) }
                  it { is_expected.not_to include(subgroup_course) }
                  it { is_expected.not_to include(subsubgroup_event) }
                  it { is_expected.not_to include(subsubgroup_course) }
                end

                context "not excluding subgroups" do
                  before { excluded_calendar_group.update(with_subgroups: false) }

                  it { is_expected.not_to include(layer_event) }
                  it { is_expected.not_to include(layer_course) }
                  it { is_expected.not_to include(subgroup_event) }
                  it { is_expected.to include(subgroup_course) }
                  it { is_expected.not_to include(subsubgroup_event) }
                  it { is_expected.to include(subsubgroup_course) }
                end
              end

              context "excluding only plain events makes no difference" do
                before { excluded_calendar_group.update(event_type: Event.name, with_subgroups: true) }

                it { is_expected.not_to include(layer_event) }
                it { is_expected.not_to include(layer_course) }
                it { is_expected.not_to include(subgroup_event) }
                it { is_expected.to include(subgroup_course) }
                it { is_expected.not_to include(subsubgroup_event) }
                it { is_expected.to include(subsubgroup_course) }
              end

              context "excluding only courses" do
                before { excluded_calendar_group.update(event_type: Event::Course.name) }

                context "excluding also subgroups" do
                  before { excluded_calendar_group.update(with_subgroups: true) }

                  it { is_expected.not_to include(layer_event) }
                  it { is_expected.not_to include(layer_course) }
                  it { is_expected.not_to include(subgroup_event) }
                  it { is_expected.not_to include(subgroup_course) }
                  it { is_expected.not_to include(subsubgroup_event) }
                  it { is_expected.not_to include(subsubgroup_course) }
                end

                context "not excluding subgroups" do
                  before { excluded_calendar_group.update(with_subgroups: false) }

                  it { is_expected.not_to include(layer_event) }
                  it { is_expected.not_to include(layer_course) }
                  it { is_expected.not_to include(subgroup_event) }
                  it { is_expected.to include(subgroup_course) }
                  it { is_expected.not_to include(subsubgroup_event) }
                  it { is_expected.to include(subsubgroup_course) }
                end
              end
            end

            context "subgroup" do
              before { excluded_calendar_group.update(group: subgroup) }

              context "excluding all event types" do
                before { excluded_calendar_group.update(event_type: nil) }

                context "excluding also subsubgroups" do
                  before { excluded_calendar_group.update(with_subgroups: true) }

                  it { is_expected.not_to include(layer_event) }
                  it { is_expected.not_to include(layer_course) }
                  it { is_expected.not_to include(subgroup_event) }
                  it { is_expected.not_to include(subgroup_course) }
                  it { is_expected.not_to include(subsubgroup_event) }
                  it { is_expected.not_to include(subsubgroup_course) }
                end

                context "not excluding subsubgroups" do
                  before { excluded_calendar_group.update(with_subgroups: false) }

                  it { is_expected.not_to include(layer_event) }
                  it { is_expected.not_to include(layer_course) }
                  it { is_expected.not_to include(subgroup_event) }
                  it { is_expected.not_to include(subgroup_course) }
                  it { is_expected.not_to include(subsubgroup_event) }
                  it { is_expected.to include(subsubgroup_course) }
                end
              end

              context "excluding only plain events makes no difference" do
                before { excluded_calendar_group.update(event_type: Event.name, with_subgroups: true) }

                it { is_expected.not_to include(layer_event) }
                it { is_expected.not_to include(layer_course) }
                it { is_expected.not_to include(subgroup_event) }
                it { is_expected.to include(subgroup_course) }
                it { is_expected.not_to include(subsubgroup_event) }
                it { is_expected.to include(subsubgroup_course) }
              end

              context "excluding only courses" do
                before { excluded_calendar_group.update(event_type: Event::Course.name) }

                context "excluding also subsubgroups" do
                  before { excluded_calendar_group.update(with_subgroups: true) }

                  it { is_expected.not_to include(layer_event) }
                  it { is_expected.not_to include(layer_course) }
                  it { is_expected.not_to include(subgroup_event) }
                  it { is_expected.not_to include(subgroup_course) }
                  it { is_expected.not_to include(subsubgroup_event) }
                  it { is_expected.not_to include(subsubgroup_course) }
                end

                context "not excluding subsubgroups" do
                  before { excluded_calendar_group.update(with_subgroups: false) }

                  it { is_expected.not_to include(layer_event) }
                  it { is_expected.not_to include(layer_course) }
                  it { is_expected.not_to include(subgroup_event) }
                  it { is_expected.not_to include(subgroup_course) }
                  it { is_expected.not_to include(subsubgroup_event) }
                  it { is_expected.to include(subsubgroup_course) }
                end
              end
            end

            context "subsubgroup" do
              before { excluded_calendar_group.update(group: subsubgroup) }

              context "excluding all event types" do
                before { excluded_calendar_group.update(event_type: nil) }

                it { is_expected.not_to include(layer_event) }
                it { is_expected.not_to include(layer_course) }
                it { is_expected.not_to include(subgroup_event) }
                it { is_expected.to include(subgroup_course) }
                it { is_expected.not_to include(subsubgroup_event) }
                it { is_expected.not_to include(subsubgroup_course) }
              end

              context "excluding only plain events" do
                before { excluded_calendar_group.update(event_type: Event.name) }

                it { is_expected.not_to include(layer_event) }
                it { is_expected.not_to include(layer_course) }
                it { is_expected.not_to include(subgroup_event) }
                it { is_expected.to include(subgroup_course) }
                it { is_expected.not_to include(subsubgroup_event) }
                it { is_expected.to include(subsubgroup_course) }
              end

              context "excluding only courses" do
                before { excluded_calendar_group.update(event_type: Event::Course.name) }

                it { is_expected.not_to include(layer_event) }
                it { is_expected.not_to include(layer_course) }
                it { is_expected.not_to include(subgroup_event) }
                it { is_expected.to include(subgroup_course) }
                it { is_expected.not_to include(subsubgroup_event) }
                it { is_expected.not_to include(subsubgroup_course) }
              end
            end
          end
        end
      end
    end
  end
end
