searchgasm 0.9.6 → 0.9.7
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.
- data/CHANGELOG +2 -0
- data/Manifest +34 -21
- data/{README.mdown → README.rdoc} +96 -63
- data/Rakefile +1 -1
- data/examples/README.rdoc +4 -0
- data/lib/searchgasm/active_record/associations.rb +40 -42
- data/lib/searchgasm/active_record/base.rb +75 -61
- data/lib/searchgasm/condition/base.rb +127 -0
- data/lib/searchgasm/condition/begins_with.rb +20 -0
- data/lib/searchgasm/condition/child_of.rb +11 -0
- data/lib/searchgasm/condition/contains.rb +20 -0
- data/lib/searchgasm/condition/descendant_of.rb +24 -0
- data/lib/searchgasm/condition/does_not_equal.rb +28 -0
- data/lib/searchgasm/condition/ends_with.rb +20 -0
- data/lib/searchgasm/condition/equals.rb +20 -0
- data/lib/searchgasm/condition/greater_than.rb +25 -0
- data/lib/searchgasm/condition/greater_than_or_equal_to.rb +20 -0
- data/lib/searchgasm/condition/inclusive_descendant_of.rb +13 -0
- data/lib/searchgasm/condition/keywords.rb +33 -0
- data/lib/searchgasm/condition/less_than.rb +25 -0
- data/lib/searchgasm/condition/less_than_or_equal_to.rb +20 -0
- data/lib/searchgasm/condition/sibling_of.rb +16 -0
- data/lib/searchgasm/condition/tree.rb +16 -0
- data/lib/searchgasm/conditions/base.rb +221 -0
- data/lib/searchgasm/conditions/protection.rb +30 -0
- data/lib/searchgasm/config.rb +137 -0
- data/lib/searchgasm/helpers/form_helper.rb +159 -0
- data/lib/searchgasm/helpers/search_helper.rb +178 -0
- data/lib/searchgasm/helpers/utilities_helper.rb +125 -0
- data/lib/searchgasm/search/base.rb +73 -179
- data/lib/searchgasm/search/conditions.rb +42 -166
- data/lib/searchgasm/search/ordering.rb +149 -0
- data/lib/searchgasm/search/pagination.rb +69 -0
- data/lib/searchgasm/search/protection.rb +61 -0
- data/lib/searchgasm/utilities.rb +30 -0
- data/lib/searchgasm/version.rb +44 -47
- data/lib/searchgasm.rb +57 -21
- data/searchgasm.gemspec +71 -46
- data/test/test_active_record_associations.rb +1 -1
- data/test/test_active_record_base.rb +4 -4
- data/test/test_condition.rb +143 -0
- data/test/{test_searchgasm_conditions.rb → test_conditions_base.rb} +43 -33
- data/test/test_search_base.rb +189 -0
- data/test/test_search_ordering.rb +91 -0
- data/test/test_search_pagination.rb +56 -0
- data/test/test_search_protection.rb +35 -0
- metadata +70 -45
- data/lib/searchgasm/search/condition.rb +0 -105
- data/lib/searchgasm/search/condition_types/begins_with_condition.rb +0 -26
- data/lib/searchgasm/search/condition_types/child_of_condition.rb +0 -17
- data/lib/searchgasm/search/condition_types/contains_condition.rb +0 -26
- data/lib/searchgasm/search/condition_types/descendant_of_condition.rb +0 -30
- data/lib/searchgasm/search/condition_types/does_not_equal_condition.rb +0 -34
- data/lib/searchgasm/search/condition_types/ends_with_condition.rb +0 -26
- data/lib/searchgasm/search/condition_types/equals_condition.rb +0 -26
- data/lib/searchgasm/search/condition_types/greater_than_condition.rb +0 -31
- data/lib/searchgasm/search/condition_types/greater_than_or_equal_to_condition.rb +0 -26
- data/lib/searchgasm/search/condition_types/inclusive_descendant_of_condition.rb +0 -19
- data/lib/searchgasm/search/condition_types/keywords_condition.rb +0 -39
- data/lib/searchgasm/search/condition_types/less_than_condition.rb +0 -31
- data/lib/searchgasm/search/condition_types/less_than_or_equal_to_condition.rb +0 -26
- data/lib/searchgasm/search/condition_types/sibling_of_condition.rb +0 -22
- data/lib/searchgasm/search/condition_types/tree_condition.rb +0 -20
- data/lib/searchgasm/search/utilities.rb +0 -34
- data/test/test_searchgasm_base.rb +0 -185
- data/test/test_searchgasm_condition_types.rb +0 -143
@@ -1,26 +0,0 @@
|
|
1
|
-
module BinaryLogic
|
2
|
-
module Searchgasm
|
3
|
-
module Search
|
4
|
-
module ConditionTypes
|
5
|
-
class ContainsCondition < Condition
|
6
|
-
class << self
|
7
|
-
def name_for_column(column)
|
8
|
-
return unless string_column?(column)
|
9
|
-
super
|
10
|
-
end
|
11
|
-
|
12
|
-
def aliases_for_column(column)
|
13
|
-
["#{column.name}_like", "#{column.name}_has"]
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
def to_conditions(value)
|
18
|
-
["#{quoted_table_name}.#{quoted_column_name} LIKE ?", "%#{value}%"]
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
Conditions.register_condition(ConditionTypes::ContainsCondition)
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
@@ -1,30 +0,0 @@
|
|
1
|
-
module BinaryLogic
|
2
|
-
module Searchgasm
|
3
|
-
module Search
|
4
|
-
module ConditionTypes
|
5
|
-
class DescendantOfCondition < TreeCondition
|
6
|
-
def to_conditions(value)
|
7
|
-
# Wish I knew how to do this in SQL
|
8
|
-
root = (value.is_a?(klass) ? value : klass.find(value)) rescue return
|
9
|
-
strs = []
|
10
|
-
subs = []
|
11
|
-
all_children_ids(root).each do |child_id|
|
12
|
-
strs << "#{quoted_table_name}.#{quote_column_name(klass.primary_key)} = ?"
|
13
|
-
subs << child_id
|
14
|
-
end
|
15
|
-
[strs.join(" OR "), *subs]
|
16
|
-
end
|
17
|
-
|
18
|
-
private
|
19
|
-
def all_children_ids(record)
|
20
|
-
ids = record.children.collect { |child| child.send(klass.primary_key) }
|
21
|
-
record.children.each { |child| ids += all_children_ids(child) }
|
22
|
-
ids
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
Conditions.register_condition(ConditionTypes::DescendantOfCondition)
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
@@ -1,34 +0,0 @@
|
|
1
|
-
module BinaryLogic
|
2
|
-
module Searchgasm
|
3
|
-
module Search
|
4
|
-
module ConditionTypes
|
5
|
-
class DoesNotEqualCondition < Condition
|
6
|
-
class << self
|
7
|
-
def aliases_for_column(column)
|
8
|
-
["#{column.name}_is_not", "#{column.name}_not"]
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
|
-
def ignore_blanks?
|
13
|
-
false
|
14
|
-
end
|
15
|
-
|
16
|
-
def to_conditions(value)
|
17
|
-
# Delegate to equals and then change
|
18
|
-
condition = EqualsCondition.new(klass, column)
|
19
|
-
condition.value = value
|
20
|
-
|
21
|
-
sql = condition.sanitize
|
22
|
-
sql.gsub!(/ IS /, " IS NOT ")
|
23
|
-
sql.gsub!(/ BETWEEN /, " NOT BETWEEN ")
|
24
|
-
sql.gsub!(/ IN /, " NOT IN ")
|
25
|
-
sql.gsub!(/=/, "!=")
|
26
|
-
sql
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
Conditions.register_condition(ConditionTypes::DoesNotEqualCondition)
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
@@ -1,26 +0,0 @@
|
|
1
|
-
module BinaryLogic
|
2
|
-
module Searchgasm
|
3
|
-
module Search
|
4
|
-
module ConditionTypes
|
5
|
-
class EndsWithCondition < Condition
|
6
|
-
class << self
|
7
|
-
def name_for_column(column)
|
8
|
-
return unless string_column?(column)
|
9
|
-
super
|
10
|
-
end
|
11
|
-
|
12
|
-
def aliases_for_column(column)
|
13
|
-
["#{column.name}_ew", "#{column.name}_ends", "#{column.name}_end"]
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
def to_conditions(value)
|
18
|
-
["#{quoted_table_name}.#{quoted_column_name} LIKE ?", "%#{value}"]
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
Conditions.register_condition(ConditionTypes::EndsWithCondition)
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
@@ -1,26 +0,0 @@
|
|
1
|
-
module BinaryLogic
|
2
|
-
module Searchgasm
|
3
|
-
module Search
|
4
|
-
module ConditionTypes
|
5
|
-
class EqualsCondition < Condition
|
6
|
-
class << self
|
7
|
-
def aliases_for_column(column)
|
8
|
-
["#{column.name}", "#{column.name}_is"]
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
|
-
def ignore_blanks?
|
13
|
-
false
|
14
|
-
end
|
15
|
-
|
16
|
-
def to_conditions(value)
|
17
|
-
# Let ActiveRecord handle this
|
18
|
-
klass.send(:sanitize_sql_hash_for_conditions, {column.name => value})
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
Conditions.register_condition(ConditionTypes::EqualsCondition)
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
@@ -1,31 +0,0 @@
|
|
1
|
-
module BinaryLogic
|
2
|
-
module Searchgasm
|
3
|
-
module Search
|
4
|
-
module ConditionTypes
|
5
|
-
class GreaterThanCondition < Condition
|
6
|
-
class << self
|
7
|
-
def name_for_column(column)
|
8
|
-
return unless comparable_column?(column)
|
9
|
-
super
|
10
|
-
end
|
11
|
-
|
12
|
-
def aliases_for_column(column)
|
13
|
-
column_names = [column.name]
|
14
|
-
column_names << column.name.gsub(/_at$/, "") if [:datetime, :timestamp, :time, :date].include?(column.type) && column.name =~ /_at$/
|
15
|
-
|
16
|
-
aliases = []
|
17
|
-
column_names.each { |column_name| aliases += ["#{column_name}_gt", "#{column_name}_after"] }
|
18
|
-
aliases
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
def to_conditions(value)
|
23
|
-
["#{quoted_table_name}.#{quoted_column_name} > ?", value]
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
Conditions.register_condition(ConditionTypes::GreaterThanCondition)
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
@@ -1,26 +0,0 @@
|
|
1
|
-
module BinaryLogic
|
2
|
-
module Searchgasm
|
3
|
-
module Search
|
4
|
-
module ConditionTypes
|
5
|
-
class GreaterThanOrEqualToCondition < Condition
|
6
|
-
class << self
|
7
|
-
def name_for_column(column)
|
8
|
-
return unless comparable_column?(column)
|
9
|
-
super
|
10
|
-
end
|
11
|
-
|
12
|
-
def aliases_for_column(column)
|
13
|
-
["#{column.name}_gte", "#{column.name}_at_least"]
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
def to_conditions(value)
|
18
|
-
["#{quoted_table_name}.#{quoted_column_name} >= ?", value]
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
Conditions.register_condition(ConditionTypes::GreaterThanOrEqualToCondition)
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
@@ -1,19 +0,0 @@
|
|
1
|
-
module BinaryLogic
|
2
|
-
module Searchgasm
|
3
|
-
module Search
|
4
|
-
module ConditionTypes
|
5
|
-
class InclusiveDescendantOfCondition < TreeCondition
|
6
|
-
include Search::Utilities
|
7
|
-
|
8
|
-
def to_conditions(value)
|
9
|
-
condition = DescendantOfCondition.new(klass, column)
|
10
|
-
condition.value = value
|
11
|
-
merge_conditions(["#{quoted_table_name}.#{quote_column_name(klass.primary_key)} = ?", (value.is_a?(klass) ? value.send(klass.primary_key) : value)], condition.sanitize, :any => true)
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
Conditions.register_condition(ConditionTypes::InclusiveDescendantOfCondition)
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
@@ -1,39 +0,0 @@
|
|
1
|
-
module BinaryLogic
|
2
|
-
module Searchgasm
|
3
|
-
module Search
|
4
|
-
module ConditionTypes
|
5
|
-
class KeywordsCondition < Condition
|
6
|
-
BLACKLISTED_WORDS = ('a'..'z').to_a + ["about", "an", "are", "as", "at", "be", "by", "com", "de", "en", "for", "from", "how", "in", "is", "it", "la", "of", "on", "or", "that", "the", "the", "this", "to", "und", "was", "what", "when", "where", "who", "will", "with", "www"] # from ranks.nl
|
7
|
-
|
8
|
-
class << self
|
9
|
-
def name_for_column(column)
|
10
|
-
return unless string_column?(column)
|
11
|
-
super
|
12
|
-
end
|
13
|
-
|
14
|
-
def aliases_for_column(column)
|
15
|
-
["#{column.name}_kwords", "#{column.name}_kw"]
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
def to_conditions(value)
|
20
|
-
strs = []
|
21
|
-
subs = []
|
22
|
-
|
23
|
-
search_parts = value.gsub(/,/, " ").split(/ /).collect { |word| word.downcase.gsub(/[^[:alnum:]]/, ''); }.uniq.select { |word| !BLACKLISTED_WORDS.include?(word.downcase) && !word.blank? }
|
24
|
-
return if search_parts.blank?
|
25
|
-
|
26
|
-
search_parts.each do |search_part|
|
27
|
-
strs << "#{quoted_table_name}.#{quoted_column_name} LIKE ?"
|
28
|
-
subs << "%#{search_part}%"
|
29
|
-
end
|
30
|
-
|
31
|
-
[strs.join(" AND "), *subs]
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
Conditions.register_condition(ConditionTypes::KeywordsCondition)
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
@@ -1,31 +0,0 @@
|
|
1
|
-
module BinaryLogic
|
2
|
-
module Searchgasm
|
3
|
-
module Search
|
4
|
-
module ConditionTypes
|
5
|
-
class LessThanCondition < Condition
|
6
|
-
class << self
|
7
|
-
def name_for_column(column)
|
8
|
-
return unless comparable_column?(column)
|
9
|
-
super
|
10
|
-
end
|
11
|
-
|
12
|
-
def aliases_for_column(column)
|
13
|
-
column_names = [column.name]
|
14
|
-
column_names << column.name.gsub(/_at$/, "") if [:datetime, :timestamp, :time, :date].include?(column.type) && column.name =~ /_at$/
|
15
|
-
|
16
|
-
aliases = []
|
17
|
-
column_names.each { |column_name| aliases += ["#{column_name}_lt", "#{column_name}_before"] }
|
18
|
-
aliases
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
def to_conditions(value)
|
23
|
-
["#{quoted_table_name}.#{quoted_column_name} < ?", value]
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
Conditions.register_condition(ConditionTypes::LessThanCondition)
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
@@ -1,26 +0,0 @@
|
|
1
|
-
module BinaryLogic
|
2
|
-
module Searchgasm
|
3
|
-
module Search
|
4
|
-
module ConditionTypes
|
5
|
-
class LessThanOrEqualToCondition < Condition
|
6
|
-
class << self
|
7
|
-
def name_for_column(column)
|
8
|
-
return unless comparable_column?(column)
|
9
|
-
super
|
10
|
-
end
|
11
|
-
|
12
|
-
def aliases_for_column(column)
|
13
|
-
["#{column.name}_lte", "#{column.name}_at_most"]
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
def to_conditions(value)
|
18
|
-
["#{quoted_table_name}.#{quoted_column_name} <= ?", value]
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
Conditions.register_condition(ConditionTypes::LessThanOrEqualToCondition)
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
@@ -1,22 +0,0 @@
|
|
1
|
-
module BinaryLogic
|
2
|
-
module Searchgasm
|
3
|
-
module Search
|
4
|
-
module ConditionTypes
|
5
|
-
class SiblingOfCondition < TreeCondition
|
6
|
-
include Search::Utilities
|
7
|
-
|
8
|
-
def to_conditions(value)
|
9
|
-
parent_association = klass.reflect_on_association(:parent)
|
10
|
-
foreign_key_name = (parent_association && parent_association.options[:foreign_key]) || "parent_id"
|
11
|
-
parent_id = (value.is_a?(klass) ? value : klass.find(value)).send(foreign_key_name)
|
12
|
-
condition = ChildOfCondition.new(klass, column)
|
13
|
-
condition.value = parent_id
|
14
|
-
merge_conditions(["#{quoted_table_name}.#{quote_column_name(klass.primary_key)} != ?", (value.is_a?(klass) ? value.send(klass.primary_key) : value)], condition.sanitize)
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
Conditions.register_condition(ConditionTypes::SiblingOfCondition)
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
@@ -1,20 +0,0 @@
|
|
1
|
-
module BinaryLogic
|
2
|
-
module Searchgasm
|
3
|
-
module Search
|
4
|
-
module ConditionTypes
|
5
|
-
class TreeCondition < Condition
|
6
|
-
class << self
|
7
|
-
def name_for_column(column)
|
8
|
-
nil
|
9
|
-
end
|
10
|
-
|
11
|
-
def name_for_klass(klass)
|
12
|
-
return unless klass.reflect_on_association(:parent) && klass.reflect_on_association(:children)
|
13
|
-
condition_name
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
@@ -1,34 +0,0 @@
|
|
1
|
-
module BinaryLogic
|
2
|
-
module Searchgasm
|
3
|
-
module Search
|
4
|
-
module Utilities
|
5
|
-
private
|
6
|
-
def merge_conditions(*conditions)
|
7
|
-
options = conditions.extract_options!
|
8
|
-
conditions.delete_if { |condition| condition.blank? }
|
9
|
-
return if conditions.blank?
|
10
|
-
return conditions.first if conditions.size == 1
|
11
|
-
|
12
|
-
conditions_strs = []
|
13
|
-
conditions_subs = []
|
14
|
-
|
15
|
-
conditions.each do |condition|
|
16
|
-
next if condition.blank?
|
17
|
-
arr_condition = [condition].flatten
|
18
|
-
conditions_strs << arr_condition.first
|
19
|
-
conditions_subs += arr_condition[1..-1]
|
20
|
-
end
|
21
|
-
|
22
|
-
return if conditions_strs.blank?
|
23
|
-
|
24
|
-
join = options[:any] ? "OR" : "AND"
|
25
|
-
conditions_str = "(#{conditions_strs.join(") #{join} (")})"
|
26
|
-
|
27
|
-
return conditions_str if conditions_subs.blank?
|
28
|
-
|
29
|
-
[conditions_str, *conditions_subs]
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
@@ -1,185 +0,0 @@
|
|
1
|
-
require File.dirname(__FILE__) + '/test_helper.rb'
|
2
|
-
|
3
|
-
class TestSearchgasmBase < Test::Unit::TestCase
|
4
|
-
fixtures :accounts, :users, :orders
|
5
|
-
|
6
|
-
def setup
|
7
|
-
setup_db
|
8
|
-
load_fixtures
|
9
|
-
end
|
10
|
-
|
11
|
-
def teardown
|
12
|
-
teardown_db
|
13
|
-
end
|
14
|
-
|
15
|
-
def test_needed
|
16
|
-
assert BinaryLogic::Searchgasm::Search::Base.needed?(Account, :page => 2, :conditions => {:name => "Ben"})
|
17
|
-
assert !BinaryLogic::Searchgasm::Search::Base.needed?(Account, :conditions => {:name => "Ben"})
|
18
|
-
assert BinaryLogic::Searchgasm::Search::Base.needed?(Account, :limit => 2, :conditions => {:name_contains => "Ben"})
|
19
|
-
assert !BinaryLogic::Searchgasm::Search::Base.needed?(Account, :limit => 2)
|
20
|
-
assert BinaryLogic::Searchgasm::Search::Base.needed?(Account, :per_page => 2)
|
21
|
-
end
|
22
|
-
|
23
|
-
def test_initialize
|
24
|
-
assert_nothing_raised { BinaryLogic::Searchgasm::Search::Base.new(Account) }
|
25
|
-
search = BinaryLogic::Searchgasm::Search::Base.new(Account, :conditions => {:name_like => "binary"}, :page => 2, :limit => 10, :readonly => true)
|
26
|
-
assert_equal Account, search.klass
|
27
|
-
assert_equal "binary", search.conditions.name_like
|
28
|
-
assert_equal 2, search.page
|
29
|
-
assert_equal 10, search.limit
|
30
|
-
assert_equal true, search.readonly
|
31
|
-
end
|
32
|
-
|
33
|
-
def test_setting_first_level_options
|
34
|
-
search = BinaryLogic::Searchgasm::Search::Base.new(Account)
|
35
|
-
|
36
|
-
search.include = :users
|
37
|
-
assert_equal :users, search.include
|
38
|
-
|
39
|
-
search.joins = "test"
|
40
|
-
assert_equal "test", search.joins
|
41
|
-
|
42
|
-
search.page = 5
|
43
|
-
assert_equal 1, search.page # haven't set a limit yet
|
44
|
-
assert_equal nil, search.offset
|
45
|
-
|
46
|
-
search.limit = 20
|
47
|
-
assert_equal search.limit, 20
|
48
|
-
assert_equal search.per_page, 20
|
49
|
-
assert_equal search.page, 5
|
50
|
-
assert_equal search.offset, 100
|
51
|
-
|
52
|
-
search.offset = 50
|
53
|
-
assert_equal search.offset, 50
|
54
|
-
assert_equal search.page, 3
|
55
|
-
|
56
|
-
search.per_page = 2
|
57
|
-
assert_equal search.per_page, 2
|
58
|
-
assert_equal search.limit, 2
|
59
|
-
assert_equal search.page, 25
|
60
|
-
assert_equal search.offset, 50
|
61
|
-
|
62
|
-
search.order = "name ASC"
|
63
|
-
assert_equal search.order, "name ASC"
|
64
|
-
|
65
|
-
search.select = "name"
|
66
|
-
assert_equal search.select, "name"
|
67
|
-
|
68
|
-
search.readonly = true
|
69
|
-
assert_equal search.readonly, true
|
70
|
-
|
71
|
-
search.group = "name"
|
72
|
-
assert_equal search.group, "name"
|
73
|
-
|
74
|
-
search.from = "accounts"
|
75
|
-
assert_equal search.from, "accounts"
|
76
|
-
|
77
|
-
search.lock = true
|
78
|
-
assert_equal search.lock, true
|
79
|
-
end
|
80
|
-
|
81
|
-
def test_conditions
|
82
|
-
search = BinaryLogic::Searchgasm::Search::Base.new(Account)
|
83
|
-
assert_kind_of BinaryLogic::Searchgasm::Search::Conditions, search.conditions
|
84
|
-
assert_equal search.conditions.klass, Account
|
85
|
-
|
86
|
-
search.conditions = {:name_like => "Binary"}
|
87
|
-
assert_kind_of BinaryLogic::Searchgasm::Search::Conditions, search.conditions
|
88
|
-
|
89
|
-
conditions = BinaryLogic::Searchgasm::Search::Conditions.new(Account, :id_greater_than => 8)
|
90
|
-
search.conditions = conditions
|
91
|
-
assert_equal conditions, search.conditions
|
92
|
-
end
|
93
|
-
|
94
|
-
def test_include
|
95
|
-
|
96
|
-
end
|
97
|
-
|
98
|
-
def test_limit
|
99
|
-
|
100
|
-
end
|
101
|
-
|
102
|
-
def test_options
|
103
|
-
|
104
|
-
end
|
105
|
-
|
106
|
-
def test_order_as
|
107
|
-
|
108
|
-
end
|
109
|
-
|
110
|
-
def test_order_by
|
111
|
-
|
112
|
-
end
|
113
|
-
|
114
|
-
def test_page
|
115
|
-
|
116
|
-
end
|
117
|
-
|
118
|
-
def test_sanitize
|
119
|
-
search = BinaryLogic::Searchgasm::Search::Base.new(Account)
|
120
|
-
search.per_page = 2
|
121
|
-
search.conditions.name_like = "Binary"
|
122
|
-
search.conditions.users.id_greater_than = 2
|
123
|
-
search.page = 3
|
124
|
-
search.readonly = true
|
125
|
-
assert_equal search.sanitize, {:include => :users, :offset => 6, :readonly => true, :conditions => ["(\"accounts\".\"name\" LIKE ?) AND (\"users\".\"id\" > ?)", "%Binary%", 2], :limit => 2 }
|
126
|
-
end
|
127
|
-
|
128
|
-
def test_scope
|
129
|
-
|
130
|
-
end
|
131
|
-
|
132
|
-
def test_searching
|
133
|
-
search = BinaryLogic::Searchgasm::Search::Base.new(Account)
|
134
|
-
search.conditions.name_like = "Binary"
|
135
|
-
assert_equal search.all, [Account.find(1), Account.find(3)]
|
136
|
-
assert_equal search.find(:all), [Account.find(1), Account.find(3)]
|
137
|
-
assert_equal search.first, Account.find(1)
|
138
|
-
assert_equal search.find(:first), Account.find(1)
|
139
|
-
|
140
|
-
search.per_page = 20
|
141
|
-
search.page = 2
|
142
|
-
|
143
|
-
assert_equal search.all, []
|
144
|
-
assert_equal search.find(:all), []
|
145
|
-
assert_equal search.first, nil
|
146
|
-
assert_equal search.find(:first), nil
|
147
|
-
|
148
|
-
search.per_page = 0
|
149
|
-
search.page = nil
|
150
|
-
search.conditions.users.first_name_contains = "Ben"
|
151
|
-
search.conditions.users.orders.description_keywords = "products, &*ap#ple $%^&*"
|
152
|
-
assert_equal search.all, [Account.find(1)]
|
153
|
-
assert_equal search.find(:all), [Account.find(1)]
|
154
|
-
assert_equal search.first, Account.find(1)
|
155
|
-
assert_equal search.find(:first), Account.find(1)
|
156
|
-
end
|
157
|
-
|
158
|
-
def test_calculations
|
159
|
-
search = BinaryLogic::Searchgasm::Search::Base.new(Account)
|
160
|
-
search.conditions.name_like = "Binary"
|
161
|
-
assert_equal 2, search.average('id')
|
162
|
-
assert_equal 2, search.calculate(:avg, 'id')
|
163
|
-
assert_equal 3, search.calculate(:max, 'id')
|
164
|
-
assert_equal 2, search.count
|
165
|
-
assert_equal 3, search.maximum('id')
|
166
|
-
assert_equal 1, search.minimum('id')
|
167
|
-
assert_equal 4, search.sum('id')
|
168
|
-
end
|
169
|
-
|
170
|
-
def test_protection
|
171
|
-
assert_raise(ArgumentError) { Account.build_search(:conditions => "(DELETE FROM users)", :page => 2, :per_page => 15) }
|
172
|
-
BinaryLogic::Searchgasm::Search::Base::VULNERABLE_OPTIONS.each { |option| assert_raise(ArgumentError) { Account.build_search(option => "(DELETE FROM users)") } }
|
173
|
-
|
174
|
-
assert_nothing_raised { Account.build_search!(:conditions => "(DELETE FROM users)", :page => 2, :per_page => 15) }
|
175
|
-
BinaryLogic::Searchgasm::Search::Base::VULNERABLE_OPTIONS.each { |option| assert_nothing_raised { Account.build_search!(option => "(DELETE FROM users)") } }
|
176
|
-
|
177
|
-
account = Account.first
|
178
|
-
|
179
|
-
assert_raise(ArgumentError) { account.users.build_search(:conditions => "(DELETE FROM users)", :page => 2, :per_page => 15) }
|
180
|
-
BinaryLogic::Searchgasm::Search::Base::VULNERABLE_OPTIONS.each { |option| assert_raise(ArgumentError) { account.users.build_search(option => "(DELETE FROM users)") } }
|
181
|
-
|
182
|
-
assert_nothing_raised { account.users.build_search!(:conditions => "(DELETE FROM users)", :page => 2, :per_page => 15) }
|
183
|
-
BinaryLogic::Searchgasm::Search::Base::VULNERABLE_OPTIONS.each { |option| assert_nothing_raised { account.users.build_search!(option => "(DELETE FROM users)") } }
|
184
|
-
end
|
185
|
-
end
|