Back to Repositories

Testing Search Result Ordering Mechanisms in searchkick

This test suite validates the ordering functionality in Searchkick, examining various sorting mechanisms for search results. It covers different ordering patterns including hash-based, string-based, and multiple field ordering, along with special cases like unmapped types and script-based sorting.

Test Coverage Overview

The test suite provides comprehensive coverage of Searchkick’s ordering capabilities, testing multiple sorting scenarios and data types.

  • Hash-based ordering with ascending/descending options
  • String-based simple ordering
  • Multiple field ordering with priority handling
  • Unmapped type handling
  • Geolocation-based ordering
  • Script-based custom ordering

Implementation Analysis

The tests utilize Minitest framework with a systematic approach to validating search result ordering. Each test case follows a pattern of storing test data, executing searches with different order parameters, and asserting the expected sequence.

The implementation leverages both direct assertion methods and relation-based verifications, ensuring ordering works correctly across different interface levels.

Technical Details

Testing tools and components:

  • Minitest as the testing framework
  • Custom assertions: assert_order and assert_order_relation
  • Searchkick integration methods
  • Product model with searchable attributes
  • Index refresh capabilities for consistency

Best Practices Demonstrated

The test suite exemplifies several testing best practices for search functionality.

  • Isolated test cases for each ordering type
  • Comprehensive edge case coverage
  • Consistent data setup and teardown
  • Clear test naming conventions
  • Multiple assertion methods for robust validation

ankane/searchkick

test/order_test.rb

            
require_relative "test_helper"

class OrderTest < Minitest::Test
  def test_hash
    store_names ["Product A", "Product B", "Product C", "Product D"]
    assert_order "product", ["Product D", "Product C", "Product B", "Product A"], order: {name: :desc}
    assert_order_relation ["Product D", "Product C", "Product B", "Product A"], Product.search("product").order(name: :desc)
  end

  def test_string
    store_names ["Product A", "Product B", "Product C", "Product D"]
    assert_order "product", ["Product A", "Product B", "Product C", "Product D"], order: "name"
    assert_order_relation ["Product A", "Product B", "Product C", "Product D"], Product.search("product").order("name")
  end

  def test_multiple
    store [
      {name: "Product A", color: "blue", store_id: 1},
      {name: "Product B", color: "red", store_id: 3},
      {name: "Product C", color: "red", store_id: 2}
    ]
    assert_order "product", ["Product A", "Product B", "Product C"], order: {color: :asc, store_id: :desc}
    assert_order_relation ["Product A", "Product B", "Product C"], Product.search("product").order(color: :asc, store_id: :desc)
    assert_order_relation ["Product A", "Product B", "Product C"], Product.search("product").order(:color, store_id: :desc)
    assert_order_relation ["Product A", "Product B", "Product C"], Product.search("product").order(color: :asc).order(store_id: :desc)
    assert_order_relation ["Product B", "Product C", "Product A"], Product.search("product").order(color: :asc).reorder(store_id: :desc)
  end

  def test_unmapped_type
    Product.searchkick_index.refresh
    assert_order "product", [], order: {not_mapped: {unmapped_type: "long"}}
    assert_order_relation [], Product.search("product").order(not_mapped: {unmapped_type: "long"})
  end

  def test_array
    store [{name: "San Francisco", latitude: 37.7833, longitude: -122.4167}]
    assert_order "francisco", ["San Francisco"], order: [{_geo_distance: {location: "0,0"}}]
    assert_order_relation ["San Francisco"], Product.search("francisco").order([{_geo_distance: {location: "0,0"}}])
  end

  def test_script
    store_names ["Red", "Green", "Blue"]
    order = {_script: {type: "number", script: {source: "doc['name'].value.length() * -1"}}}
    assert_order "*", ["Green", "Blue", "Red"], order: order
    assert_order_relation ["Green", "Blue", "Red"], Product.search("*").order(order)
  end
end