searchgasm 0.9.6 → 0.9.7
Sign up to get free protection for your applications and to get access to all the features.
- 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
|