forty_facets 0.1.9.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.ruby-version +1 -1
- data/CHANGELOG +12 -0
- data/forty_facets.gemspec +2 -2
- data/lib/forty_facets/filter/facet_filter_definition.rb +29 -23
- data/lib/forty_facets/filter/range_filter_definition.rb +26 -9
- data/lib/forty_facets/version.rb +3 -1
- data/test/fixtures.rb +5 -1
- data/test/smoke_test.rb +99 -74
- data/test/test_helper.rb +8 -0
- metadata +13 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b199beee6e5f6cb3ce5024427b3d21b3458c2f8b94e362e02132d30bf89e0b56
|
4
|
+
data.tar.gz: 8e4f12b0498ecd4f307b916615f32d1f22602757484f396bdac9e6545ea62a53
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 297c5f1d5dcef25897f877e9af20bf35af4e4642dc73c145ac42c6e3de2b1cfb6a504f70f46221853f32b38fbca0bbe66315f0fb06a9f40861b200a75c92b513
|
7
|
+
data.tar.gz: b484abb4c5ee26c000cdc97da161a515a73f3321d2191b8ff45961962c2f01c7f4dd50b38b266023c83bd9dbc627c1f7b240db0ae881297e7a97c5ae436cc37d
|
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
3.1.2
|
data/CHANGELOG
ADDED
data/forty_facets.gemspec
CHANGED
@@ -18,11 +18,11 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
21
|
-
spec.add_development_dependency "bundler"
|
21
|
+
spec.add_development_dependency "bundler"
|
22
22
|
spec.add_development_dependency "rake"
|
23
23
|
spec.add_development_dependency "minitest"
|
24
24
|
spec.add_development_dependency "sqlite3"
|
25
25
|
spec.add_development_dependency "coveralls"
|
26
|
-
spec.add_development_dependency "activerecord", "~>
|
26
|
+
spec.add_development_dependency "activerecord", "~> 7.0"
|
27
27
|
spec.add_development_dependency "byebug" # travis doenst like byebug
|
28
28
|
end
|
@@ -1,6 +1,7 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module FortyFacets
|
2
4
|
class FacetFilterDefinition < FilterDefinition
|
3
|
-
|
4
5
|
class FacetFilter < Filter
|
5
6
|
def values
|
6
7
|
@values ||= Array.wrap(value).sort.uniq
|
@@ -12,12 +13,12 @@ module FortyFacets
|
|
12
13
|
order_accessor = definition.options[:order]
|
13
14
|
if order_accessor
|
14
15
|
if order_accessor.is_a?(Proc)
|
15
|
-
facet.sort_by!{|facet_value| order_accessor.call(facet_value.entity) }
|
16
|
+
facet.sort_by! { |facet_value| order_accessor.call(facet_value.entity) }
|
16
17
|
else
|
17
|
-
facet.sort_by!{|facet_value| facet_value.entity.send(order_accessor) }
|
18
|
+
facet.sort_by! { |facet_value| facet_value.entity.send(order_accessor) }
|
18
19
|
end
|
19
20
|
else
|
20
|
-
facet.sort_by!{|facet_value| -facet_value.count }
|
21
|
+
facet.sort_by! { |facet_value| -facet_value.count }
|
21
22
|
end
|
22
23
|
facet
|
23
24
|
end
|
@@ -25,7 +26,7 @@ module FortyFacets
|
|
25
26
|
|
26
27
|
class AssociationFacetFilter < FacetFilter
|
27
28
|
def selected
|
28
|
-
@selected ||= definition.association.klass.find(Array.wrap(values).reject(&:blank?))
|
29
|
+
@selected ||= definition.association.klass.unscoped.find(Array.wrap(values).reject(&:blank?))
|
29
30
|
end
|
30
31
|
|
31
32
|
def remove(entity)
|
@@ -49,12 +50,14 @@ module FortyFacets
|
|
49
50
|
def selected
|
50
51
|
entity = definition.origin_class
|
51
52
|
column = entity.columns_hash[definition.attribute.to_s]
|
52
|
-
|
53
|
+
type = entity.connection.lookup_cast_type_from_column(column)
|
54
|
+
values.map { |value| type.serialize(value) }
|
53
55
|
end
|
54
56
|
|
55
57
|
def build_scope
|
56
|
-
return
|
57
|
-
|
58
|
+
return proc { |base| base } if empty?
|
59
|
+
|
60
|
+
proc do |base|
|
58
61
|
base.joins(definition.joins).where(definition.qualified_column_name => value)
|
59
62
|
end
|
60
63
|
end
|
@@ -90,8 +93,9 @@ module FortyFacets
|
|
90
93
|
|
91
94
|
class BelongsToFilter < AssociationFacetFilter
|
92
95
|
def build_scope
|
93
|
-
return
|
94
|
-
|
96
|
+
return proc { |base| base } if empty?
|
97
|
+
|
98
|
+
proc do |base|
|
95
99
|
base.joins(definition.joins).where(definition.qualified_column_name => values)
|
96
100
|
end
|
97
101
|
end
|
@@ -101,7 +105,7 @@ module FortyFacets
|
|
101
105
|
query = "#{my_column} AS foreign_id, count(#{my_column}) AS occurrences"
|
102
106
|
counts = without.result(skip_ordering: true).distinct.joins(definition.joins).select(query).group(my_column)
|
103
107
|
counts.includes_values = []
|
104
|
-
entities_by_id = definition.association.klass.find(counts.map(&:foreign_id)).group_by(&:id)
|
108
|
+
entities_by_id = definition.association.klass.unscoped.find(counts.map(&:foreign_id)).group_by(&:id)
|
105
109
|
|
106
110
|
facet = counts.map do |count|
|
107
111
|
facet_entity = entities_by_id[count.foreign_id].first
|
@@ -115,8 +119,9 @@ module FortyFacets
|
|
115
119
|
|
116
120
|
class HasManyFilter < AssociationFacetFilter
|
117
121
|
def build_scope
|
118
|
-
return
|
119
|
-
|
122
|
+
return proc { |base| base } if empty?
|
123
|
+
|
124
|
+
proc do |base|
|
120
125
|
base_table = definition.origin_class.table_name
|
121
126
|
|
122
127
|
primary_key_column = "#{base_table}.#{definition.origin_class.primary_key}"
|
@@ -130,15 +135,15 @@ module FortyFacets
|
|
130
135
|
def facet
|
131
136
|
base_table = definition.search.root_class.table_name
|
132
137
|
join_name = [definition.association.name.to_s, base_table.to_s].sort.join('_')
|
133
|
-
foreign_id_col = definition.association.name.to_s.singularize
|
134
|
-
my_column = join_name
|
138
|
+
foreign_id_col = "#{definition.association.name.to_s.singularize}_id"
|
139
|
+
my_column = "#{join_name}.#{foreign_id_col}"
|
135
140
|
counts = without.result(skip_ordering: true)
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
141
|
+
.distinct
|
142
|
+
.joins(definition.joins)
|
143
|
+
.select("#{my_column} as foreign_id, count(#{my_column}) as occurrences")
|
144
|
+
.group(my_column)
|
140
145
|
counts.includes_values = []
|
141
|
-
entities_by_id = definition.association.klass.find(counts.map(&:foreign_id)).group_by(&:id)
|
146
|
+
entities_by_id = definition.association.klass.unscoped.find(counts.map(&:foreign_id)).group_by(&:id)
|
142
147
|
|
143
148
|
facet = counts.map do |count|
|
144
149
|
facet_entity = entities_by_id[count.foreign_id].first
|
@@ -152,11 +157,12 @@ module FortyFacets
|
|
152
157
|
|
153
158
|
def build_filter(search_instance, param_value)
|
154
159
|
if association
|
155
|
-
|
160
|
+
case association.macro
|
161
|
+
when :belongs_to
|
156
162
|
BelongsToFilter.new(self, search_instance, param_value)
|
157
|
-
|
163
|
+
when :has_many
|
158
164
|
HasManyFilter.new(self, search_instance, param_value)
|
159
|
-
|
165
|
+
when :has_and_belongs_to_many
|
160
166
|
HasManyFilter.new(self, search_instance, param_value)
|
161
167
|
else
|
162
168
|
raise "Unsupported association type: #{association.macro}"
|
@@ -1,27 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module FortyFacets
|
2
4
|
class RangeFilterDefinition < FilterDefinition
|
3
5
|
class RangeFilter < Filter
|
6
|
+
RANGE_REGEX = /(\d*) - (\d*)/
|
7
|
+
|
4
8
|
def build_scope
|
5
|
-
return
|
9
|
+
return proc { |base| base } if empty?
|
6
10
|
|
7
|
-
|
8
|
-
base.joins(definition.joins)
|
9
|
-
|
11
|
+
proc do |base|
|
12
|
+
scope = base.joins(definition.joins)
|
13
|
+
scope = scope.where("#{definition.qualified_column_name} >= ?", min_value) if min_value.present?
|
14
|
+
scope = scope.where("#{definition.qualified_column_name} <= ?", max_value) if max_value.present?
|
15
|
+
scope
|
10
16
|
end
|
11
17
|
end
|
12
18
|
|
13
19
|
def min_value
|
14
|
-
|
15
|
-
|
20
|
+
min, _max = range_values
|
21
|
+
min
|
16
22
|
end
|
17
23
|
|
18
24
|
def max_value
|
19
|
-
|
20
|
-
|
25
|
+
_min, max = range_values
|
26
|
+
max
|
21
27
|
end
|
22
28
|
|
23
29
|
def absolute_interval
|
24
|
-
@abosultes ||=
|
30
|
+
@abosultes ||=
|
31
|
+
without
|
32
|
+
.result
|
33
|
+
.reorder('')
|
34
|
+
.select("min(#{definition.qualified_column_name}) AS min, max(#{definition.qualified_column_name}) as max")
|
35
|
+
.order("min(#{definition.qualified_column_name})")
|
36
|
+
.first
|
25
37
|
end
|
26
38
|
|
27
39
|
def absolute_min
|
@@ -32,6 +44,11 @@ module FortyFacets
|
|
32
44
|
absolute_interval.max
|
33
45
|
end
|
34
46
|
|
47
|
+
private
|
48
|
+
|
49
|
+
def range_values
|
50
|
+
value&.match(RANGE_REGEX)&.captures
|
51
|
+
end
|
35
52
|
end
|
36
53
|
|
37
54
|
def build_filter(search_instance, value)
|
data/lib/forty_facets/version.rb
CHANGED
data/test/fixtures.rb
CHANGED
@@ -14,6 +14,7 @@ ActiveRecord::Schema.define do
|
|
14
14
|
t.string :status
|
15
15
|
t.string :name
|
16
16
|
t.string :description
|
17
|
+
t.datetime :deleted_at
|
17
18
|
end
|
18
19
|
|
19
20
|
create_table :producers do |t|
|
@@ -79,10 +80,13 @@ end
|
|
79
80
|
class Studio < ActiveRecord::Base
|
80
81
|
belongs_to :country
|
81
82
|
has_and_belongs_to_many :producers
|
83
|
+
|
84
|
+
default_scope ->{ where(deleted_at: nil) }
|
85
|
+
scope :with_deleted, ->{ unscope(where: :deleted_at) }
|
82
86
|
end
|
83
87
|
|
84
88
|
class Movie < ActiveRecord::Base
|
85
|
-
belongs_to :studio
|
89
|
+
belongs_to :studio, ->{ with_deleted }
|
86
90
|
has_and_belongs_to_many :genres
|
87
91
|
has_and_belongs_to_many :actors
|
88
92
|
has_and_belongs_to_many :writers
|
data/test/smoke_test.rb
CHANGED
@@ -1,46 +1,49 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'coveralls'
|
2
4
|
Coveralls.wear!
|
3
5
|
|
4
|
-
require
|
6
|
+
require 'minitest/autorun'
|
7
|
+
require 'test_helper'
|
5
8
|
require 'logger'
|
6
|
-
#require 'byebug'# travis doenst like byebug
|
9
|
+
# require 'byebug'# travis doenst like byebug
|
7
10
|
require_relative '../lib/forty_facets'
|
8
11
|
|
9
|
-
#silence_warnings do
|
12
|
+
# silence_warnings do
|
10
13
|
require_relative 'fixtures'
|
11
|
-
#end
|
14
|
+
# end
|
12
15
|
|
13
16
|
class MovieSearch < FortyFacets::FacetSearch
|
14
17
|
model 'Movie'
|
15
18
|
|
16
19
|
text :title, name: 'Title'
|
17
20
|
facet :studio, name: 'Studio'
|
18
|
-
facet :year, order:
|
21
|
+
facet :year, order: proc { |year| -year }
|
19
22
|
facet :genres, name: 'Genre'
|
20
23
|
facet :actors, name: 'Actor'
|
21
24
|
range :price, name: 'Price'
|
22
25
|
facet :writers, name: 'Writer'
|
23
|
-
facet [
|
24
|
-
facet [
|
25
|
-
facet [
|
26
|
+
facet %i[studio country], name: 'Country'
|
27
|
+
facet %i[studio status], name: 'Studio status'
|
28
|
+
facet %i[studio producers], name: 'Producers'
|
26
29
|
sql_facet({ uschis: "studios.name = 'Uschi'", non_uschis: "studios.name != 'USCHI'" },
|
27
|
-
{ name:
|
28
|
-
sql_facet({ classic:
|
29
|
-
{ name:
|
30
|
-
sql_facet({ classic:
|
31
|
-
{ name:
|
32
|
-
text [
|
30
|
+
{ name: 'Uschis', path: %i[studio uschis], joins: [:studio] })
|
31
|
+
sql_facet({ classic: 'year <= 1980', non_classic: 'year > 1980' },
|
32
|
+
{ name: 'Classic', path: :classic })
|
33
|
+
sql_facet({ classic: 'year <= 1980', non_classic: 'year > 1980' },
|
34
|
+
{ name: 'Classic' })
|
35
|
+
text %i[studio description], name: 'Studio Description'
|
33
36
|
scope :classics, name: 'Name classics'
|
34
37
|
scope :year_lte, name: 'Year less than or equal', pass_value: true
|
35
38
|
custom :needs_complex_filtering
|
36
39
|
end
|
37
40
|
|
38
41
|
class SmokeTest < Minitest::Test
|
39
|
-
|
40
42
|
def test_sql_facet_with_belongs_to
|
41
|
-
search = MovieSearch.new({'studio-uschis' => {}})
|
43
|
+
search = MovieSearch.new({ 'studio-uschis' => {} })
|
42
44
|
assert_equal Movie.count, search.result.size
|
43
|
-
assert_equal search.filter([
|
45
|
+
assert_equal search.filter(%i[studio uschis]).facet,
|
46
|
+
[FortyFacets::FacetValue.new(:uschis, 0, false), FortyFacets::FacetValue.new(:non_uschis, 40, false)]
|
44
47
|
end
|
45
48
|
|
46
49
|
def test_it_finds_all_movies
|
@@ -49,57 +52,57 @@ class SmokeTest < Minitest::Test
|
|
49
52
|
end
|
50
53
|
|
51
54
|
def test_scope_filter
|
52
|
-
search = MovieSearch.new(
|
55
|
+
search = MovieSearch.new('search' => {})
|
53
56
|
assert_equal 40, search.result.size
|
54
57
|
assert search.filter(:classic).facet.include? FortyFacets::FacetValue.new(:classic, 6, false)
|
55
58
|
assert search.filter(:classic).facet.include? FortyFacets::FacetValue.new(:non_classic, 34, false)
|
56
59
|
|
57
|
-
search = MovieSearch.new(
|
60
|
+
search = MovieSearch.new('search' => { 'classic' => 'classic' })
|
58
61
|
assert_equal 6, search.result.size
|
59
62
|
assert search.filter(:classic).facet.include? FortyFacets::FacetValue.new(:classic, 6, true)
|
60
63
|
assert search.filter(:classic).facet.include? FortyFacets::FacetValue.new(:non_classic, 34, false)
|
61
64
|
|
62
|
-
search = MovieSearch.new(
|
65
|
+
search = MovieSearch.new('search' => { 'classic' => 'non_classic' })
|
63
66
|
assert_equal 34, search.result.size
|
64
67
|
assert search.filter(:classic).facet.include? FortyFacets::FacetValue.new(:classic, 6, false)
|
65
68
|
assert search.filter(:classic).facet.include? FortyFacets::FacetValue.new(:non_classic, 34, true)
|
66
69
|
|
67
|
-
search = MovieSearch.new(
|
70
|
+
search = MovieSearch.new('search' => { 'classic' => %w[non_classic classic] })
|
68
71
|
assert_equal 40, search.result.size
|
69
72
|
assert search.filter(:classic).facet.include? FortyFacets::FacetValue.new(:classic, 6, true)
|
70
73
|
assert search.filter(:classic).facet.include? FortyFacets::FacetValue.new(:non_classic, 34, true)
|
71
74
|
end
|
72
75
|
|
73
76
|
def test_scope_filter_without_path
|
74
|
-
search = MovieSearch.new(
|
77
|
+
search = MovieSearch.new('search' => {})
|
75
78
|
assert_equal 40, search.result.size
|
76
|
-
assert search.filter([
|
77
|
-
assert search.filter([
|
79
|
+
assert search.filter(%i[classic non_classic]).facet.include? FortyFacets::FacetValue.new(:classic, 6, false)
|
80
|
+
assert search.filter(%i[classic non_classic]).facet.include? FortyFacets::FacetValue.new(:non_classic, 34, false)
|
78
81
|
|
79
|
-
search = MovieSearch.new(
|
82
|
+
search = MovieSearch.new('search' => { 'classic-non_classic' => 'classic' })
|
80
83
|
assert_equal 6, search.result.size
|
81
|
-
assert search.filter([
|
82
|
-
assert search.filter([
|
84
|
+
assert search.filter(%i[classic non_classic]).facet.include? FortyFacets::FacetValue.new(:classic, 6, true)
|
85
|
+
assert search.filter(%i[classic non_classic]).facet.include? FortyFacets::FacetValue.new(:non_classic, 34, false)
|
83
86
|
|
84
|
-
search = MovieSearch.new(
|
87
|
+
search = MovieSearch.new('search' => { 'classic-non_classic' => 'non_classic' })
|
85
88
|
assert_equal 34, search.result.size
|
86
|
-
assert search.filter([
|
87
|
-
assert search.filter([
|
89
|
+
assert search.filter(%i[classic non_classic]).facet.include? FortyFacets::FacetValue.new(:classic, 6, false)
|
90
|
+
assert search.filter(%i[classic non_classic]).facet.include? FortyFacets::FacetValue.new(:non_classic, 34, true)
|
88
91
|
|
89
|
-
search = MovieSearch.new(
|
92
|
+
search = MovieSearch.new('search' => { 'classic-non_classic' => %w[non_classic classic] })
|
90
93
|
assert_equal 40, search.result.size
|
91
|
-
assert search.filter([
|
92
|
-
assert search.filter([
|
94
|
+
assert search.filter(%i[classic non_classic]).facet.include? FortyFacets::FacetValue.new(:classic, 6, true)
|
95
|
+
assert search.filter(%i[classic non_classic]).facet.include? FortyFacets::FacetValue.new(:non_classic, 34, true)
|
93
96
|
end
|
94
97
|
|
95
98
|
def test_text_filter
|
96
|
-
search = MovieSearch.new({'search' => { 'title' => 'ipsum' }})
|
99
|
+
search = MovieSearch.new({ 'search' => { 'title' => 'ipsum' } })
|
97
100
|
assert_equal 1, search.result.size
|
98
101
|
assert_equal 'ipsum', search.result.first.title
|
99
102
|
end
|
100
103
|
|
101
104
|
def test_year_filter
|
102
|
-
search = MovieSearch.new({'search' => { 'year' => '2011' }})
|
105
|
+
search = MovieSearch.new({ 'search' => { 'year' => '2011' } })
|
103
106
|
assert_equal [2011], search.result.map(&:year).uniq
|
104
107
|
|
105
108
|
facet = search.filter(:year).facet
|
@@ -107,34 +110,43 @@ class SmokeTest < Minitest::Test
|
|
107
110
|
end
|
108
111
|
|
109
112
|
def test_range_filter
|
110
|
-
search = MovieSearch.new({'search' => {'price' => '0 - 20'}})
|
113
|
+
search = MovieSearch.new({ 'search' => { 'price' => '0 - 20' } })
|
111
114
|
assert_equal Movie.count, search.result.size
|
112
115
|
|
113
|
-
search = MovieSearch.new({'search' => {'price' => '
|
114
|
-
assert_equal Movie.
|
116
|
+
search = MovieSearch.new({ 'search' => { 'price' => '5 - 10' } })
|
117
|
+
assert_equal Movie.where('price >= ? AND price <= ?', 5, 10).count, search.result.size
|
118
|
+
|
119
|
+
search = MovieSearch.new({ 'search' => { 'price' => '5 - ' } })
|
120
|
+
assert_equal Movie.where('price >= ?', 5).count, search.result.size
|
121
|
+
|
122
|
+
search = MovieSearch.new({ 'search' => { 'price' => ' - 5' } })
|
123
|
+
assert_equal Movie.where('price <= ?', 5).count, search.result.size
|
124
|
+
|
125
|
+
search = MovieSearch.new({ 'search' => { 'price' => '' } })
|
126
|
+
assert_equal Movie.count, search.result.size
|
115
127
|
end
|
116
128
|
|
117
129
|
def test_text_filter_via_belongs_to
|
118
130
|
description = Studio.first.description
|
119
|
-
search = MovieSearch.new({'search' => { 'studio-description' => description }})
|
131
|
+
search = MovieSearch.new({ 'search' => { 'studio-description' => description } })
|
120
132
|
|
121
|
-
assert_equal Movie.all.
|
133
|
+
assert_equal Movie.all.select { |m| m.studio.description == description }.size, search.result.size
|
122
134
|
assert_equal description, search.result.first.studio.description
|
123
135
|
end
|
124
136
|
|
125
137
|
def test_country_filter
|
126
|
-
search = MovieSearch.new('search' => { 'studio-country' => Country.first.id.to_s})
|
127
|
-
assert_equal [Country.first], search.result.map{|m| m.studio.country}.uniq
|
138
|
+
search = MovieSearch.new('search' => { 'studio-country' => Country.first.id.to_s })
|
139
|
+
assert_equal [Country.first], search.result.map { |m| m.studio.country }.uniq
|
128
140
|
assert_equal Movie.count / 2, search.result.count
|
129
141
|
|
130
|
-
search = MovieSearch.new('search' => { 'studio-country' => Country.last.id.to_s})
|
131
|
-
assert_equal [Country.last], search.result.map{|m| m.studio.country}.uniq
|
142
|
+
search = MovieSearch.new('search' => { 'studio-country' => Country.last.id.to_s })
|
143
|
+
assert_equal [Country.last], search.result.map { |m| m.studio.country }.uniq
|
132
144
|
assert_equal Movie.count / 2, search.result.count
|
133
145
|
end
|
134
146
|
|
135
147
|
def test_selected_country_filter
|
136
|
-
search = MovieSearch.new('search' => { 'studio-country' => Country.first.id.to_s})
|
137
|
-
filter = search.filter([
|
148
|
+
search = MovieSearch.new('search' => { 'studio-country' => Country.first.id.to_s })
|
149
|
+
filter = search.filter(%i[studio country])
|
138
150
|
assert_equal FortyFacets::FacetFilterDefinition::BelongsToFilter, filter.class
|
139
151
|
assert_equal [Country.first], filter.selected
|
140
152
|
|
@@ -142,17 +154,16 @@ class SmokeTest < Minitest::Test
|
|
142
154
|
end
|
143
155
|
|
144
156
|
def test_studio_status_filter
|
145
|
-
search = MovieSearch.new('search' => { 'studio-status' => 'active'})
|
146
|
-
assert_equal ['active'], search.result.map{|m| m.studio.status}.uniq
|
157
|
+
search = MovieSearch.new('search' => { 'studio-status' => 'active' })
|
158
|
+
assert_equal ['active'], search.result.map { |m| m.studio.status }.uniq
|
147
159
|
assert_equal Movie.count / 2, search.result.count
|
148
160
|
|
149
|
-
filter = search.filter([
|
161
|
+
filter = search.filter(%i[studio status])
|
150
162
|
assert_equal ['active'], filter.selected
|
151
163
|
end
|
152
164
|
|
153
165
|
def test_year_add_remove_filter
|
154
|
-
|
155
|
-
search = MovieSearch.new()
|
166
|
+
search = MovieSearch.new
|
156
167
|
|
157
168
|
search = search.filter(:year).add(2010)
|
158
169
|
assert_equal Movie.where(year: 2010).count, search.result.count
|
@@ -165,7 +176,7 @@ class SmokeTest < Minitest::Test
|
|
165
176
|
end
|
166
177
|
|
167
178
|
def test_selected_year_filter
|
168
|
-
search = MovieSearch.new
|
179
|
+
search = MovieSearch.new
|
169
180
|
|
170
181
|
search = search.filter(:year).add(2010)
|
171
182
|
assert_equal [2010], search.filter(:year).selected
|
@@ -174,9 +185,9 @@ class SmokeTest < Minitest::Test
|
|
174
185
|
assert_equal [2010, 2011], search.filter(:year).selected
|
175
186
|
|
176
187
|
facet = search.filter(:year).facet
|
177
|
-
assert facet.find{|fv| fv.entity == 2010}.selected
|
178
|
-
assert facet.find{|fv| fv.entity == 2011}.selected
|
179
|
-
assert !facet.find{|fv| fv.entity == 2012}.selected
|
188
|
+
assert facet.find { |fv| fv.entity == 2010 }.selected
|
189
|
+
assert facet.find { |fv| fv.entity == 2011 }.selected
|
190
|
+
assert !facet.find { |fv| fv.entity == 2012 }.selected
|
180
191
|
end
|
181
192
|
|
182
193
|
def test_belongs_to_filter
|
@@ -185,13 +196,27 @@ class SmokeTest < Minitest::Test
|
|
185
196
|
studio = first_facet_value.entity
|
186
197
|
assert_kind_of Studio, studio
|
187
198
|
|
188
|
-
movies_with_studio = Movie.where(studio:
|
199
|
+
movies_with_studio = Movie.where(studio:)
|
189
200
|
search_with_studio = blank_search.filter(:studio).add(studio)
|
190
201
|
|
191
202
|
assert_equal movies_with_studio.size, search_with_studio.result.size
|
192
203
|
assert_equal movies_with_studio.size, first_facet_value.count
|
193
204
|
end
|
194
205
|
|
206
|
+
def test_belongs_to_filter_with_default_scope
|
207
|
+
wrap_in_db_transaction do
|
208
|
+
deleted_studio = Studio.create!(name: 'Deleted studio', status: 'active')
|
209
|
+
Movie.create!(studio: deleted_studio)
|
210
|
+
deleted_studio.update!(deleted_at: Time.now)
|
211
|
+
|
212
|
+
blank_search = MovieSearch.new
|
213
|
+
|
214
|
+
assert_equal(
|
215
|
+
5, blank_search.filter(:studio).facet.length
|
216
|
+
)
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
195
220
|
def test_sort_by_proc
|
196
221
|
blank_search = MovieSearch.new
|
197
222
|
facet_entities = blank_search.filter(:year).facet.map(&:entity)
|
@@ -201,7 +226,7 @@ class SmokeTest < Minitest::Test
|
|
201
226
|
def test_has_many
|
202
227
|
blank_search = MovieSearch.new
|
203
228
|
genre = Genre.first
|
204
|
-
expected = Movie.order(:id).select{|m| m.genres.include?(genre)}
|
229
|
+
expected = Movie.order(:id).select { |m| m.genres.include?(genre) }
|
205
230
|
assert blank_search.filter(:genres).is_a?(FortyFacets::FacetFilterDefinition::HasManyFilter)
|
206
231
|
search = blank_search.filter(:genres).add(genre)
|
207
232
|
actual = search.result
|
@@ -212,9 +237,9 @@ class SmokeTest < Minitest::Test
|
|
212
237
|
def test_hast_many_via_belongs_to
|
213
238
|
blank_search = MovieSearch.new
|
214
239
|
producer = Producer.first
|
215
|
-
expected = Movie.order(:id).select{|m| m.studio.producers.include? producer}
|
216
|
-
assert blank_search.filter([
|
217
|
-
search = blank_search.filter([
|
240
|
+
expected = Movie.order(:id).select { |m| m.studio.producers.include? producer }
|
241
|
+
assert blank_search.filter(%i[studio producers]).is_a?(FortyFacets::FacetFilterDefinition::HasManyFilter)
|
242
|
+
search = blank_search.filter(%i[studio producers]).add(producer)
|
218
243
|
actual = search.result
|
219
244
|
|
220
245
|
assert_equal expected.size, actual.size
|
@@ -223,7 +248,7 @@ class SmokeTest < Minitest::Test
|
|
223
248
|
def test_has_many_writers
|
224
249
|
blank_search = MovieSearch.new
|
225
250
|
writer = Writer.first
|
226
|
-
expected = Movie.order(:id).select{|m| m.writers.include?(writer)}
|
251
|
+
expected = Movie.order(:id).select { |m| m.writers.include?(writer) }
|
227
252
|
assert blank_search.filter(:writers).is_a?(FortyFacets::FacetFilterDefinition::HasManyFilter)
|
228
253
|
search = blank_search.filter(:writers).add(writer)
|
229
254
|
actual = search.result
|
@@ -236,8 +261,8 @@ class SmokeTest < Minitest::Test
|
|
236
261
|
genre = Genre.first
|
237
262
|
actor = Actor.first
|
238
263
|
expected = Movie.order(:id)
|
239
|
-
|
240
|
-
|
264
|
+
.select { |m| m.genres.include?(genre) }
|
265
|
+
.select { |m| m.actors.include?(actor) }
|
241
266
|
assert blank_search.filter(:genres).is_a?(FortyFacets::FacetFilterDefinition::HasManyFilter)
|
242
267
|
search_with_genre = blank_search.filter(:genres).add(genre)
|
243
268
|
search_with_genre_and_actor = search_with_genre.filter(:actors).add(actor)
|
@@ -252,11 +277,11 @@ class SmokeTest < Minitest::Test
|
|
252
277
|
|
253
278
|
search.filter(:writers).facet.each do |facet_value|
|
254
279
|
writer = facet_value.entity
|
255
|
-
expected = Movie.order(:id).select{|m| m.writers.include?(writer)}.count
|
256
|
-
assert_equal expected, facet_value.count,
|
280
|
+
expected = Movie.order(:id).select { |m| m.writers.include?(writer) }.count
|
281
|
+
assert_equal expected, facet_value.count,
|
282
|
+
'The amount of movies for a writer should match the number indicated in the facet'
|
257
283
|
assert_equal writer.id == selected_writer.id, facet_value.selected
|
258
284
|
end
|
259
|
-
|
260
285
|
end
|
261
286
|
|
262
287
|
def test_has_many_facet_values_genres
|
@@ -265,11 +290,11 @@ class SmokeTest < Minitest::Test
|
|
265
290
|
|
266
291
|
search.filter(:genres).facet.each do |facet_value|
|
267
292
|
genre = facet_value.entity
|
268
|
-
expected = Movie.order(:id).select{|m| m.genres.include?(genre)}.count
|
269
|
-
assert_equal expected, facet_value.count,
|
293
|
+
expected = Movie.order(:id).select { |m| m.genres.include?(genre) }.count
|
294
|
+
assert_equal expected, facet_value.count,
|
295
|
+
'The amount of movies for a genre should match the number indicated in the facet'
|
270
296
|
assert_equal genre.id == selected_genre.id, facet_value.selected
|
271
297
|
end
|
272
|
-
|
273
298
|
end
|
274
299
|
|
275
300
|
def test_includes_does_not_blow_up
|
@@ -278,14 +303,15 @@ class SmokeTest < Minitest::Test
|
|
278
303
|
search.filter(:studio).facet.reject(&:selected).to_a
|
279
304
|
end
|
280
305
|
|
281
|
-
def
|
282
|
-
search_with_scope = MovieSearch.new
|
306
|
+
def test_activating_scope_filter
|
307
|
+
search_with_scope = MovieSearch.new.filter(:classics).add('1')
|
283
308
|
assert search_with_scope.result.count < Movie.count, 'Activating the scope should yield a smaller set of movies'
|
284
309
|
end
|
285
310
|
|
286
311
|
def test_scope_filter_with_params
|
287
|
-
search_with_scope = MovieSearch.new
|
288
|
-
assert search_with_scope.result.count < Movie.count,
|
312
|
+
search_with_scope = MovieSearch.new.filter(:year_lte).add(1980)
|
313
|
+
assert search_with_scope.result.count < Movie.count,
|
314
|
+
'Activating the scope with filter should yield a smaller set of movies'
|
289
315
|
end
|
290
316
|
|
291
317
|
def test_custom_filter
|
@@ -294,5 +320,4 @@ class SmokeTest < Minitest::Test
|
|
294
320
|
|
295
321
|
assert_equal 'foo', new_search.filter(:needs_complex_filtering).value
|
296
322
|
end
|
297
|
-
|
298
323
|
end
|
data/test/test_helper.rb
CHANGED
metadata
CHANGED
@@ -1,29 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: forty_facets
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1
|
4
|
+
version: 0.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Axel Tetzlaff
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-06-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '0'
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - "
|
24
|
+
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
26
|
+
version: '0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rake
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -86,14 +86,14 @@ dependencies:
|
|
86
86
|
requirements:
|
87
87
|
- - "~>"
|
88
88
|
- !ruby/object:Gem::Version
|
89
|
-
version: '
|
89
|
+
version: '7.0'
|
90
90
|
type: :development
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
94
|
- - "~>"
|
95
95
|
- !ruby/object:Gem::Version
|
96
|
-
version: '
|
96
|
+
version: '7.0'
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
98
|
name: byebug
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -121,6 +121,7 @@ files:
|
|
121
121
|
- ".ruby-gemset"
|
122
122
|
- ".ruby-version"
|
123
123
|
- ".travis.yml"
|
124
|
+
- CHANGELOG
|
124
125
|
- Gemfile
|
125
126
|
- LICENSE.txt
|
126
127
|
- README.md
|
@@ -146,7 +147,7 @@ homepage: https://github.com/fortytools/forty_facets
|
|
146
147
|
licenses:
|
147
148
|
- MIT
|
148
149
|
metadata: {}
|
149
|
-
post_install_message:
|
150
|
+
post_install_message:
|
150
151
|
rdoc_options: []
|
151
152
|
require_paths:
|
152
153
|
- lib
|
@@ -161,9 +162,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
161
162
|
- !ruby/object:Gem::Version
|
162
163
|
version: '0'
|
163
164
|
requirements: []
|
164
|
-
|
165
|
-
|
166
|
-
signing_key:
|
165
|
+
rubygems_version: 3.3.7
|
166
|
+
signing_key:
|
167
167
|
specification_version: 4
|
168
168
|
summary: Library for building facet searches for active_record models
|
169
169
|
test_files:
|