require 'spec_helper' module Calagator describe Event::Search, :type => :model do let(:events) { double } before { allow(Event).to receive(:search).and_return(events) } before { allow(Event).to receive(:search_tag).and_return(events) } let(:search_params) { {} } subject(:event_search) { Event::Search.new(search_params) } describe "by keyword" do let(:search_params) { {query: "myquery"} } it "should find all events matching the keyword, ordered by date" do event_search.events expect(Event).to have_received(:search).with("myquery", skip_old: false, order: "date") end context "limited to current events" do let(:search_params) { {query: "myquery", current: "1"} } it "should be able to only return current events" do event_search.events expect(Event).to have_received(:search).with("myquery", order: "date", skip_old: true) end end context "with an invalid order" do let(:search_params) { {query: "myquery", order: "kittens"} } it "should set a failure message as a warning" do expect(event_search.failure_message).to eq("Unknown ordering option \"kittens\", sorting by date instead.") end it "should not be a hard failure" do expect(event_search).not_to be_hard_failure end end context "when the search encounters an error" do before { allow(Event).to receive(:search).and_raise(ActiveRecord::StatementInvalid, "bad times") } before { event_search.events } it "should set a failure message" do expect(event_search.failure_message).to eq("There was an error completing your search.") end it "should be a hard failure" do expect(event_search).to be_hard_failure end it "should return no events" do expect(event_search.events).to be_empty end end end describe "by tag" do let(:search_params) { {tag: "foo"} } it "should find all events matching the tag, ordered by date" do event_search.events expect(Event).to have_received(:search_tag).with("foo", current: false, order: "date") end context "with an invalid order" do let(:search_params) { {tag: "omg", order: "kittens"} } it "should set a failure message as a warning" do expect(event_search.failure_message).to eq("Unknown ordering option \"kittens\", sorting by date instead.") end it "should not be a hard failure" do expect(subject).not_to be_hard_failure end end context "attempting to order by score" do let(:search_params) { {tag: "omg", order: "score"} } it "should set a failure message as a warning" do expect(event_search.failure_message).to eq("You cannot sort tags by score") end it "should not be a hard failure" do expect(event_search).not_to be_hard_failure end end context "when the tag search encounters an error" do before { allow(Event).to receive(:search_tag).and_raise(ActiveRecord::StatementInvalid.new("bad times")) } before { event_search.events } it "should set a failure message" do expect(event_search.failure_message).to eq("There was an error completing your search.") end it "should be a hard failure" do expect(event_search).to be_hard_failure end it "should return no events" do expect(event_search.events).to be_empty end end end describe "#grouped_events" do let(:past_event) { double(:event, current?: false) } let(:current_event) { double(:event, current?: true) } let(:events) { [past_event, current_event] } let(:search_params) { {query: "ruby"} } it "groups events into a hash by currentness" do expect(event_search.grouped_events).to eq({ past: [past_event], current: [current_event], }) end context "when passed the 'current' option" do let(:search_params) { {query: "ruby", current: "true"} } it "discards past events" do expect(event_search.grouped_events).to eq({ past: [], current: [current_event], }) end end context "when passing 'date' to the order option" do let(:search_params) { {query: "ruby", order: "date"} } let(:other_past_event) { double(:event, current?: false) } let(:events) { [current_event, past_event, other_past_event] } it "orders past events by date desc" do expect(event_search.grouped_events).to eq({ current: [current_event], past: [past_event, other_past_event], }) end end end describe "hard failures" do context "when given neither search query nor tag" do let(:search_params) { {} } it "should set a failure message" do expect(event_search.failure_message).to eq("You must enter a search query") end it "should be a hard failure" do expect(event_search).to be_hard_failure end it "should return no events" do expect(event_search.events).to be_empty end end context "when given both search query and tag" do let(:search_params) { {query: "omg", tag: "bbq"} } it "should set a failure message" do expect(event_search.failure_message).to eq("You can't search by tag and query at the same time") end it "should be a hard failure" do expect(event_search).to be_hard_failure end it "should return no events" do expect(event_search.events).to be_empty end end end end end