2

It seems very interesting for me: in development mode TS work with queries easy, but in testing I get an error.

Here is my test:

describe 'GET #index' do
  subject { get :index }

  let!(:products) { Fabricate.times(10, :product) }

  before(:all) do
    ThinkingSphinx::Test.init
    ThinkingSphinx::Test.index
    # sleeping for some time
    ThinkingSphinx::Test.start
  end

  after(:all) do
    ThinkingSphinx::Test.stop
  end

  it { expect(subject).to render_template(:index) }
  it { expect{subject}.to change{ assigns(:search).try(:products) }.to match_array(products) }
end

Here is my controller:

def index
  @search = Query::Products.new(params.merge({
    kind_cd: Product.product,
    contractor: current_contractor
  }))
end

Here is my Service Object:

class Query::Products

  def initialize(params)
    @params = params
    process_products
    process_categories # error in this method
    process_properties
    process_brands
    process_prices
  end

private

  def process_products
    # ... other code

    @product_facets = Product.facets(query_string, common_search_options)
  end

  def common_search_options
    {
      order: ordering,
      ranker: :bm25,
      with: {
        price_type_for_search => min_price_conditions..max_price_conditions,
        kind_cd: @params[:kind_cd],
        brand_id: [*@params[:brand_ids]],
        category_ids: categories_for_search,
        property_value_ids: [*@params[:property_value_ids]],
      }
    }
  end

  def query_string
    @params[:query].present? ? Riddle.escape(@params[:query] + '*') : ''
  end

  def price_type_for_contractor
    @price_type_for_contractor ||= PriceType.for(@params[:contractor])
  end

  def price_type_for_search
    @price_type_for_search ||= "price_type_#{price_type_for_contractor.id}".to_sym
  end

  def min_price_conditions
    @min_price_conditions ||= @params[:min_price_limit].try(:to_f) || Price.where(price_type: price_type_for_contractor).minimum(:value)
  end

  def max_price_conditions
    @max_price_conditions ||= @params[:max_price_limit].try(:to_f) || Price.where(price_type: price_type_for_contractor).maximum(:value)
  end

  def ordering
    (@params[:order_by] == 'new') ? :created_at : price_type_for_search
  end

  def categories_for_search
    @params[:category_ids] || @params[:category_id] || []
  end

  def process_categories
    category_ids = if @params[:available_category_ids]
      Category.find(@params[:available_category_ids])
    elsif @params[:category_id]
      @category = Category.find(@params[:category_id])
      @category.children.ids
    else
      @product_facets[:direct_category_id].keys # errors here, see @product_facets definition
    end

    @categories = Category.where(id: category_ids)
  end

And I get the error

 Failure/Error: subject { get :index }
 ThinkingSphinx::SyntaxError:
   sphinxql: syntax error, unexpected AND, expecting CONST_INT or CONST_FLOAT or '-' near 'AND  AND `kind_cd` = 0 AND `sphinx_deleted` = 0 GROUP BY `sphinx_internal_class` ORDER BY `price_type_3` ASC LIMIT 0, 1000 OPTION ranker=bm25, max_matches=1000; SHOW META; SELECT *, @groupby, @count FROM `product_core` WHERE `price_type_3` BETWEEN  AND  AND `kind_cd` = 0 AND `sphinx_deleted` = 0 GROUP BY `direct_category_id` ORDER BY `price_type_3` ASC LIMIT 0, 1000 OPTION ranker=bm25, max_matches=1000; SHOW META; SELEC
./app/services/query/products.rb:76:in `process_categories'

In development mode I don't get the error. Why I have this trouble?

Dave Schweisguth
  • 36,475
  • 10
  • 98
  • 121
Alex Antonov
  • 14,134
  • 7
  • 65
  • 142
  • In your test log file, can you find the Sphinx queries that are causing the problem? – pat Jul 02 '14 at 10:48
  • If you're testing your controller you really should be mocking any external objects. Provide a mocked response rather than a real response from your service object and ensure that the controller behaves correctly based on that fixed response. Anything else would be an integration test, and isn't suited to be tested within a controller spec. – Jon Jul 02 '14 at 22:07
  • @pat, sorry for huge delay. Where I can find logs? – Alex Antonov Jul 18 '14 at 11:27
  • RAILS_APP/log/test.log - in there, you should see SphinxQL queries for Sphinx (which look very similar to SQL, but it's not quite the same). – pat Jul 18 '14 at 13:57

1 Answers1

0

I found my trouble!

The error was on transactional fixtures. Disabling them solved my problem.

Here's more detailed: How to test ThinkingSphinx using RSpec

Community
  • 1
  • 1
Alex Antonov
  • 14,134
  • 7
  • 65
  • 142