stub_solr

overrided StubSessionProxy with AR queries to mimic sunspot


License
MIT
Install
gem install stub_solr -v 0.0.4

Documentation

StubSolr

CircleCI Codacy Badge

Sunspot.session = Sunspot::Rails::StubSessionProxy.new(Sunspot.session) is enough for most of cases but if you want more than allow_any_instance_of(Sunspot::Rails::StubSessionProxy::Search).to receive(:results).and_return(myExpectedResults) this gem can be helpful. kaminari for pagination and plain AR to mimic resutls.

this gem depends on 2.2.x version of sunspot, sunspot_rails.

Installation

Add this line to your application's Gemfile:

gem 'stub_solr'

Usage

test_helper file should have require 'stub_solr'. Given a sunspot search block as following codes,

class ActivitiesController < ApplicationController
  def search
    ...
    search = Sunspot.search Excercise, Activity do
      any_of do
        with :blocked, false
        without :exhausted, true
      end

      if min && max
        any_of do
          all_of do
            with :start_limit_number, nil
            with(:end_limit_number).less_than_or_equal_to max
          end
          all_of do
            with :end_limit_number, nil
            with(:start_limit_number).greater_than_or_equal_to min
          end
          all_of do
            without(:start_limit_number, nil)
            without(:end_limit_number, nil)
            with(:start_limit_number).greater_than_or_equal_to min
            with(:end_limit_number).less_than_or_equal_to max
          end
        end
      end
      ## search by text
      fulltext params[:search] if params[:search].present?
      order_by :created_at, :asc
      paginate page: page, per_page: per_page
    end
    ...
  end
end

You can write expected results like this. use concat for any_of block and array_1 & array_2 for all_of block.

class ActivitiesControllerTest < ActionDispatch::IntegrationTest
  def setup
    Sunspot.session = Sunspot::Rails::StubSessionProxy.new(
      Sunspot.session, Activity.all.to_a.concat(Excercise.all.to_a)
    )
    super
  end

  def teardown
    Sunspot.session = ::Sunspot.session.original_session
    super
  end
  
  test 'filter with number range' do
    pool_1 = Activity.where(blocked: false).to_a.concat(Activity.where(exhausted: false).to_a).uniq
    target_1 = Activity.where("end_limit_number <= ? AND start_limit_number = ?", 18, nil).to_a
    target_2 = Activity.where("start_limit_number >= ? AND end_limit_number = ?", 3, nil).to_a
    target_3 = Activity.where("start_limit_number >= ?", 3).where("end_limit_number <= ?", 18).to_a
    pool_2 = target_1.concat(target_2).concat(target_3)
    expected = pool_1 & pool_2

    get search_activities_url(params: { limits: [3, 18] })
    res = ActiveSupport::JSON.decode(response.body)["activities"]
    res.size.must_equal expected.size
  end
end

For searching, it finds all string / text fields for given classes and use them.

For range search like greater_than, it uses array to check an attribute is for range search. by default, it's %w[time month created_at start end] but you can change that.

  def setup
    Sunspot.session = Sunspot::Rails::StubSessionProxy.new(
      Sunspot.session, Activity.all.to_a.concat(Excercise.all.to_a)
    )
    Sunspot.session.set_range_fields(%w[time month created_at departure arrival])
    super
  end

Development

bundle install
rake test

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/jaigouk/stub_solr.

License

The gem is available as open source under the terms of the MIT License.