# frozen_string_literal: true

require 'spec_helper'

module Calagator
  describe Venue::Search, type: :model do
    describe '#venues' do
      before do
        @open_venue = create(:venue,
                            title: 'Open Town',
                            description: 'baz',
                            wifi: false,
                            tag_list: %w[foo])
        @closed_venue = create(:venue,
                              title: 'Closed Down',
                              closed: true,
                              wifi: false,
                              tag_list: %w[bar])
        @wifi_venue = create(:venue,
                            title: 'Internetful',
                            wifi: true,
                            tag_list: %w[foo bar])
      end

      describe 'with no parameters' do
        subject { described_class.new }

        it 'does not include closed venues' do
          expect(subject.venues).to match_array([@open_venue, @wifi_venue])
        end

        it 'does not declare results' do
          expect(subject).not_to be_results
        end
      end

      describe 'and showing all venues' do
        it 'includes closed venues when asked to with the include_closed parameter' do
          subject = described_class.new all: '1', include_closed: '1'
          expect(subject.venues).to match_array([@open_venue, @closed_venue, @wifi_venue])
        end

        it 'includes ONLY closed venues when asked to with the closed parameter' do
          subject = described_class.new all: '1', closed: '1'
          expect(subject.venues).to eq([@closed_venue])
        end

        it 'declares results' do
          subject = described_class.new all: '1'
          expect(subject).to be_results
        end
      end

      describe 'when searching' do
        describe 'for public wifi (and no keyword)' do
          it 'onlies include results with public wifi' do
            subject = described_class.new query: '', wifi: '1'
            expect(subject.venues).to eq([@wifi_venue])
          end

          it 'declares results' do
            subject = described_class.new query: '', wifi: '1'
            expect(subject).to be_results
          end
        end

        describe 'when searching by keyword' do
          it 'finds venues by title' do
            subject = described_class.new query: 'Open Town'
            expect(subject.venues).to eq([@open_venue])
          end

          it 'finds venues by description' do
            subject = described_class.new query: 'baz'
            expect(subject.venues).to eq([@open_venue])
          end

          describe 'and requiring public wifi' do
            it 'does not find venues without public wifi' do
              subject = described_class.new query: 'baz', wifi: '1'
              expect(subject.venues).to be_empty
            end
          end

          it 'declares results' do
            subject = described_class.new query: 'Open Town'
            expect(subject).to be_results
          end
        end
      end

      it 'is able to return events matching specific tag' do
        subject = described_class.new tag: 'foo'
        expect(subject.venues).to match_array([@open_venue, @wifi_venue])
      end

      it 'declares results' do
        subject = described_class.new tag: 'foo'
        expect(subject).to be_results
      end

      describe 'handling exceptions' do
        subject(:venue_search) { described_class.new }

        before { allow(Venue).to receive(:non_duplicates).and_raise(ActiveRecord::StatementInvalid, 'bad times') }

        before { venue_search.venues }

        it 'sets a failure message' do
          expect(venue_search.failure_message).to eq('There was an error completing your search.')
        end

        it 'is a hard failure' do
          expect(venue_search).to be_hard_failure
        end
      end
    end
  end
end
