require "search_flip" require "webmock/rspec" require "active_record" require "factory_bot" require "timecop" require "yaml" require File.expand_path("delegate_matcher", __dir__) WebMock.allow_net_connect! RSpec.configure do |config| config.include FactoryBot::Syntax::Methods config.before do TestIndex.delete_index if TestIndex.index_exists? ProductIndex.match_all.delete Product.delete_all CommentIndex.match_all.delete Comment.delete_all end end ActiveRecord::Base.establish_connection(adapter: "sqlite3", database: ":memory:") SearchFlip::Config[:auto_refresh] = true ActiveRecord::Base.connection.execute "DROP TABLE IF EXISTS products" ActiveRecord::Base.connection.create_table :products do |t| t.string :title t.text :description t.float :price t.string :category t.integer :version, default: 1 t.integer :rank, default: 0 t.integer :user_id t.timestamps null: false end ActiveRecord::Base.connection.add_index :products, :user_id class Product < ActiveRecord::Base belongs_to :user has_many :comments end FactoryBot.define do factory :product end ActiveRecord::Base.connection.execute "DROP TABLE IF EXISTS users" ActiveRecord::Base.connection.create_table :users do |t| t.string :name t.timestamps null: false end class User < ActiveRecord::Base has_many :products end FactoryBot.define do factory :user end ActiveRecord::Base.connection.execute "DROP TABLE IF EXISTS comments" ActiveRecord::Base.connection.create_table :comments do |t| t.text :message t.integer :product_id t.timestamps null: false end ActiveRecord::Base.connection.add_index :comments, :product_id class Comment < ActiveRecord::Base belongs_to :product end FactoryBot.define do factory :comment end class CommentIndex include SearchFlip::Index def self.type_name connection.distribution.nil? && connection.version.to_i < 8 ? "comments" : "_doc" end def self.index_name "comments" end def self.model Comment end def self.serialize(comment) { id: comment.id, message: comment.message } end end CommentIndex.delete_index if CommentIndex.index_exists? CommentIndex.create_index CommentIndex.update_mapping class ProductIndex include SearchFlip::Index def self.mapping if ProductIndex.connection.distribution || ProductIndex.connection.version.to_i >= 5 { properties: { category: { type: "text", fielddata: true }, title: { type: "text", fielddata: true }, description: { type: "text", fielddata: true } } } else {} end end def self.type_name connection.distribution.nil? && connection.version.to_i < 8 ? "products" : "_doc" end def self.index_name "products" end def self.model Product end def self.serialize(product) { id: product.id, title: product.title, description: product.description, category: product.category, price: product.price, rank: product.rank, created_at: product.created_at, updated_at: product.updated_at } end end ProductIndex.delete_index if ProductIndex.index_exists? ProductIndex.create_index ProductIndex.update_mapping class TestIndex include SearchFlip::Index def self.mapping { properties: { test_field: { type: "date" } } } end def self.type_name connection.distribution.nil? && connection.version.to_i < 8 ? "test" : "_doc" end def self.index_name "test" end def self.serialize(object) { id: object.id } end end TestIndex.delete_index if TestIndex.index_exists?