# frozen_string_literal: true require 'coveralls' Coveralls.wear! require 'minitest/autorun' require 'test_helper' require 'logger' # require 'byebug'# travis doenst like byebug require_relative '../lib/forty_facets' # silence_warnings do require_relative 'fixtures' # end class MovieSearch < FortyFacets::FacetSearch model 'Movie' text :title, name: 'Title' facet :studio, name: 'Studio' facet :year, order: proc { |year| -year } facet :genres, name: 'Genre' facet :actors, name: 'Actor' range :price, name: 'Price' facet :writers, name: 'Writer' facet %i[studio country], name: 'Country' facet %i[studio status], name: 'Studio status' facet %i[studio producers], name: 'Producers' sql_facet({ uschis: "studios.name = 'Uschi'", non_uschis: "studios.name != 'USCHI'" }, { name: 'Uschis', path: %i[studio uschis], joins: [:studio] }) sql_facet({ classic: 'year <= 1980', non_classic: 'year > 1980' }, { name: 'Classic', path: :classic }) sql_facet({ classic: 'year <= 1980', non_classic: 'year > 1980' }, { name: 'Classic' }) text %i[studio description], name: 'Studio Description' scope :classics, name: 'Name classics' scope :year_lte, name: 'Year less than or equal', pass_value: true custom :needs_complex_filtering end class SmokeTest < Minitest::Test def test_sql_facet_with_belongs_to search = MovieSearch.new({ 'studio-uschis' => {} }) assert_equal Movie.count, search.result.size assert_equal search.filter(%i[studio uschis]).facet, [FortyFacets::FacetValue.new(:uschis, 0, false), FortyFacets::FacetValue.new(:non_uschis, 40, false)] end def test_it_finds_all_movies search = MovieSearch.new({}) assert_equal Movie.all.size, search.result.size end def test_scope_filter search = MovieSearch.new('search' => {}) assert_equal 40, search.result.size assert search.filter(:classic).facet.include? FortyFacets::FacetValue.new(:classic, 6, false) assert search.filter(:classic).facet.include? FortyFacets::FacetValue.new(:non_classic, 34, false) search = MovieSearch.new('search' => { 'classic' => 'classic' }) assert_equal 6, search.result.size assert search.filter(:classic).facet.include? FortyFacets::FacetValue.new(:classic, 6, true) assert search.filter(:classic).facet.include? FortyFacets::FacetValue.new(:non_classic, 34, false) search = MovieSearch.new('search' => { 'classic' => 'non_classic' }) assert_equal 34, search.result.size assert search.filter(:classic).facet.include? FortyFacets::FacetValue.new(:classic, 6, false) assert search.filter(:classic).facet.include? FortyFacets::FacetValue.new(:non_classic, 34, true) search = MovieSearch.new('search' => { 'classic' => %w[non_classic classic] }) assert_equal 40, search.result.size assert search.filter(:classic).facet.include? FortyFacets::FacetValue.new(:classic, 6, true) assert search.filter(:classic).facet.include? FortyFacets::FacetValue.new(:non_classic, 34, true) end def test_scope_filter_without_path search = MovieSearch.new('search' => {}) assert_equal 40, search.result.size assert search.filter(%i[classic non_classic]).facet.include? FortyFacets::FacetValue.new(:classic, 6, false) assert search.filter(%i[classic non_classic]).facet.include? FortyFacets::FacetValue.new(:non_classic, 34, false) search = MovieSearch.new('search' => { 'classic-non_classic' => 'classic' }) assert_equal 6, search.result.size assert search.filter(%i[classic non_classic]).facet.include? FortyFacets::FacetValue.new(:classic, 6, true) assert search.filter(%i[classic non_classic]).facet.include? FortyFacets::FacetValue.new(:non_classic, 34, false) search = MovieSearch.new('search' => { 'classic-non_classic' => 'non_classic' }) assert_equal 34, search.result.size assert search.filter(%i[classic non_classic]).facet.include? FortyFacets::FacetValue.new(:classic, 6, false) assert search.filter(%i[classic non_classic]).facet.include? FortyFacets::FacetValue.new(:non_classic, 34, true) search = MovieSearch.new('search' => { 'classic-non_classic' => %w[non_classic classic] }) assert_equal 40, search.result.size assert search.filter(%i[classic non_classic]).facet.include? FortyFacets::FacetValue.new(:classic, 6, true) assert search.filter(%i[classic non_classic]).facet.include? FortyFacets::FacetValue.new(:non_classic, 34, true) end def test_text_filter search = MovieSearch.new({ 'search' => { 'title' => 'ipsum' } }) assert_equal 1, search.result.size assert_equal 'ipsum', search.result.first.title end def test_year_filter search = MovieSearch.new({ 'search' => { 'year' => '2011' } }) assert_equal [2011], search.result.map(&:year).uniq facet = search.filter(:year).facet assert_equal Movie.count, facet.map(&:count).sum end def test_range_filter search = MovieSearch.new({ 'search' => { 'price' => '0 - 20' } }) assert_equal Movie.count, search.result.size search = MovieSearch.new({ 'search' => { 'price' => '5 - 10' } }) assert_equal Movie.where('price >= ? AND price <= ?', 5, 10).count, search.result.size search = MovieSearch.new({ 'search' => { 'price' => '5 - ' } }) assert_equal Movie.where('price >= ?', 5).count, search.result.size search = MovieSearch.new({ 'search' => { 'price' => ' - 5' } }) assert_equal Movie.where('price <= ?', 5).count, search.result.size search = MovieSearch.new({ 'search' => { 'price' => '' } }) assert_equal Movie.count, search.result.size end def test_text_filter_via_belongs_to description = Studio.first.description search = MovieSearch.new({ 'search' => { 'studio-description' => description } }) assert_equal Movie.all.select { |m| m.studio.description == description }.size, search.result.size assert_equal description, search.result.first.studio.description end def test_country_filter search = MovieSearch.new('search' => { 'studio-country' => Country.first.id.to_s }) assert_equal [Country.first], search.result.map { |m| m.studio.country }.uniq assert_equal Movie.count / 2, search.result.count search = MovieSearch.new('search' => { 'studio-country' => Country.last.id.to_s }) assert_equal [Country.last], search.result.map { |m| m.studio.country }.uniq assert_equal Movie.count / 2, search.result.count end def test_selected_country_filter search = MovieSearch.new('search' => { 'studio-country' => Country.first.id.to_s }) filter = search.filter(%i[studio country]) assert_equal FortyFacets::FacetFilterDefinition::BelongsToFilter, filter.class assert_equal [Country.first], filter.selected assert_equal Movie.count / 2, filter.facet.reject(&:selected).first.count end def test_studio_status_filter search = MovieSearch.new('search' => { 'studio-status' => 'active' }) assert_equal ['active'], search.result.map { |m| m.studio.status }.uniq assert_equal Movie.count / 2, search.result.count filter = search.filter(%i[studio status]) assert_equal ['active'], filter.selected end def test_year_add_remove_filter search = MovieSearch.new search = search.filter(:year).add(2010) assert_equal Movie.where(year: 2010).count, search.result.count search = search.filter(:year).add(2011) assert_equal Movie.where(year: [2010, 2011]).count, search.result.count search = search.filter(:year).remove(2010) assert_equal Movie.where(year: 2011).count, search.result.count end def test_selected_year_filter search = MovieSearch.new search = search.filter(:year).add(2010) assert_equal [2010], search.filter(:year).selected search = search.filter(:year).add(2011) assert_equal [2010, 2011], search.filter(:year).selected facet = search.filter(:year).facet assert facet.find { |fv| fv.entity == 2010 }.selected assert facet.find { |fv| fv.entity == 2011 }.selected assert !facet.find { |fv| fv.entity == 2012 }.selected end def test_belongs_to_filter blank_search = MovieSearch.new first_facet_value = blank_search.filter(:studio).facet.first studio = first_facet_value.entity assert_kind_of Studio, studio movies_with_studio = Movie.where(studio:) search_with_studio = blank_search.filter(:studio).add(studio) assert_equal movies_with_studio.size, search_with_studio.result.size assert_equal movies_with_studio.size, first_facet_value.count end def test_belongs_to_filter_with_default_scope wrap_in_db_transaction do deleted_studio = Studio.create!(name: 'Deleted studio', status: 'active') Movie.create!(studio: deleted_studio) deleted_studio.update!(deleted_at: Time.now) blank_search = MovieSearch.new assert_equal( 5, blank_search.filter(:studio).facet.length ) end end def test_sort_by_proc blank_search = MovieSearch.new facet_entities = blank_search.filter(:year).facet.map(&:entity) assert_equal Movie.all.map(&:year).sort.uniq.reverse, facet_entities end def test_has_many blank_search = MovieSearch.new genre = Genre.first expected = Movie.order(:id).select { |m| m.genres.include?(genre) } assert blank_search.filter(:genres).is_a?(FortyFacets::FacetFilterDefinition::HasManyFilter) search = blank_search.filter(:genres).add(genre) actual = search.result assert_equal expected.size, actual.size end def test_hast_many_via_belongs_to blank_search = MovieSearch.new producer = Producer.first expected = Movie.order(:id).select { |m| m.studio.producers.include? producer } assert blank_search.filter(%i[studio producers]).is_a?(FortyFacets::FacetFilterDefinition::HasManyFilter) search = blank_search.filter(%i[studio producers]).add(producer) actual = search.result assert_equal expected.size, actual.size end def test_has_many_writers blank_search = MovieSearch.new writer = Writer.first expected = Movie.order(:id).select { |m| m.writers.include?(writer) } assert blank_search.filter(:writers).is_a?(FortyFacets::FacetFilterDefinition::HasManyFilter) search = blank_search.filter(:writers).add(writer) actual = search.result assert_equal expected.size, actual.size end def test_has_many_combo blank_search = MovieSearch.new genre = Genre.first actor = Actor.first expected = Movie.order(:id) .select { |m| m.genres.include?(genre) } .select { |m| m.actors.include?(actor) } assert blank_search.filter(:genres).is_a?(FortyFacets::FacetFilterDefinition::HasManyFilter) search_with_genre = blank_search.filter(:genres).add(genre) search_with_genre_and_actor = search_with_genre.filter(:actors).add(actor) actual = search_with_genre_and_actor.result assert_equal expected.size, actual.size end def test_has_many_facet_values_writers selected_writer = Writer.first search = MovieSearch.new.filter(:writers).add(selected_writer) search.filter(:writers).facet.each do |facet_value| writer = facet_value.entity expected = Movie.order(:id).select { |m| m.writers.include?(writer) }.count assert_equal expected, facet_value.count, 'The amount of movies for a writer should match the number indicated in the facet' assert_equal writer.id == selected_writer.id, facet_value.selected end end def test_has_many_facet_values_genres selected_genre = Genre.first search = MovieSearch.new.filter(:genres).add(selected_genre) search.filter(:genres).facet.each do |facet_value| genre = facet_value.entity expected = Movie.order(:id).select { |m| m.genres.include?(genre) }.count assert_equal expected, facet_value.count, 'The amount of movies for a genre should match the number indicated in the facet' assert_equal genre.id == selected_genre.id, facet_value.selected end end def test_includes_does_not_blow_up selected_genre = Genre.first search = MovieSearch.new({}, Movie.all.includes(:studio)).filter(:genres).add(selected_genre) search.filter(:studio).facet.reject(&:selected).to_a end def test_activating_scope_filter search_with_scope = MovieSearch.new.filter(:classics).add('1') assert search_with_scope.result.count < Movie.count, 'Activating the scope should yield a smaller set of movies' end def test_scope_filter_with_params search_with_scope = MovieSearch.new.filter(:year_lte).add(1980) assert search_with_scope.result.count < Movie.count, 'Activating the scope with filter should yield a smaller set of movies' end def test_custom_filter search = MovieSearch.new new_search = search.filter(:needs_complex_filtering).set('foo') assert_equal 'foo', new_search.filter(:needs_complex_filtering).value end end