glasses 1.6.2 → 1.7.0

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.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. data/lib/glasses.rb +254 -10
  3. data/lib/glasses/version.rb +1 -1
  4. data/spec/dummy/app/controllers/search_controller.rb +29 -17
  5. data/spec/dummy/app/views/search/full_raw_search_range.html.erb +0 -0
  6. data/spec/dummy/app/views/search/full_search.html.erb +0 -0
  7. data/spec/dummy/app/views/search/full_search_range.html.erb +0 -0
  8. data/spec/dummy/app/views/search/range_search.html.erb +30 -0
  9. data/spec/dummy/app/views/search/raw_full_search.html.erb +0 -0
  10. data/spec/dummy/app/views/search/raw_range_search.html.erb +25 -0
  11. data/spec/dummy/app/views/search/simple_search.html.erb +4 -2
  12. data/spec/dummy/config/routes.rb +3 -54
  13. data/spec/dummy/db/development.sqlite3 +0 -0
  14. data/spec/dummy/db/seeds.rb +2 -1
  15. data/spec/dummy/db/test.sqlite3 +0 -0
  16. data/spec/dummy/log/development.log +2628 -0
  17. data/spec/dummy/log/test.log +42280 -0
  18. data/spec/dummy/tmp/cache/assets/development/sprockets/v3.0/-n4kyDOdRxiiiIJEFA9cId9azJmW5g6hmwbs8SJ4qRg.cache +1 -0
  19. data/spec/dummy/tmp/cache/assets/development/sprockets/v3.0/2SBt5E86bhaTcl7TkcrIXPVQyQtH9yIRArRC_UxPck4.cache +1 -0
  20. data/spec/dummy/tmp/cache/assets/development/sprockets/v3.0/2Tqd0MZWTPMTu8CoqlOCudnpF2UapAVb-1Qd3gZnzWs.cache +0 -0
  21. data/spec/dummy/tmp/cache/assets/development/sprockets/v3.0/4m7rzZ6NLrCLYY8Klx2qByvjsF9EwTrhkqhffC_ddIU.cache +1 -0
  22. data/spec/dummy/tmp/cache/assets/development/sprockets/v3.0/4wucpOHsDYdErjU4sC9i1FT33L-WRugEHtfQdiz-CXY.cache +0 -0
  23. data/spec/dummy/tmp/cache/assets/development/sprockets/v3.0/AE40Tp96RkdOo7EhY00dhAOG17GUBn6QkZxp0HQVRQA.cache +2 -0
  24. data/spec/dummy/tmp/cache/assets/development/sprockets/v3.0/CtIOdYL64ZUZ8_1ALDOZWNEis9WeBXUYTZ95MGCwJxk.cache +2 -0
  25. data/spec/dummy/tmp/cache/assets/development/sprockets/v3.0/DMb_4zR5zBmQGRtZlXIrUCrkOrY-Wzw_ESjc3NoXX6s.cache +1 -0
  26. data/spec/dummy/tmp/cache/assets/development/sprockets/v3.0/FfRbjoX7fHHQqnXiehqlD233T1kj4rzNPybfmQ_GUWI.cache +2 -0
  27. data/spec/dummy/tmp/cache/assets/development/sprockets/v3.0/JlLKJj3SMeXmPLYJvdO955A6OPH9wSTWF3QFOvbaT0k.cache +2 -0
  28. data/spec/dummy/tmp/cache/assets/development/sprockets/v3.0/Mo_r4nJu9qt0iEhVH0CXGZkIh_SCKfu3LoDU6GlMT-U.cache +2 -0
  29. data/spec/dummy/tmp/cache/assets/development/sprockets/v3.0/PjzZwmbYJUPXBPEKfYAIld32mtAk3H0hBz7ONWVqza4.cache +2 -0
  30. data/spec/dummy/tmp/cache/assets/development/sprockets/v3.0/QYBC6SiWic96YuGP27vORM8frM2yoCxYATSeAuu3q3s.cache +2 -0
  31. data/spec/dummy/tmp/cache/assets/development/sprockets/v3.0/QfZ4TPv_vTZ6WmGKJEhbsZ0Ou73XHsnuUlsaYV3ZQEY.cache +1 -0
  32. data/spec/dummy/tmp/cache/assets/development/sprockets/v3.0/XIp7H1NvI9qObEEUnVrJoJ0TgF9dsNRmdw7bkMLyf64.cache +1 -0
  33. data/spec/dummy/tmp/cache/assets/development/sprockets/v3.0/aCkopDHgOZcXcLJcYI3sgc_SuAZhhr9RkRQshzmldF8.cache +1 -0
  34. data/spec/dummy/tmp/cache/assets/development/sprockets/v3.0/bkZWDwb871tTLoM-W80twc_qhQ_ziPfInIfbzCcLnpE.cache +1 -0
  35. data/spec/dummy/tmp/cache/assets/development/sprockets/v3.0/gLJlx0p_IOKb7r9m3hjLdN2jGSicQ_Ns4SS1jWlFDAQ.cache +0 -0
  36. data/spec/dummy/tmp/cache/assets/development/sprockets/v3.0/i9TsnRfu6oqRsV9V2v_6Ulubst2IVveepQEkimUU6QE.cache +1 -0
  37. data/spec/dummy/tmp/cache/assets/development/sprockets/v3.0/iEVE5Kzzv15cyQWfQGEbgnKSSO0xiblZzP-sO26AYGQ.cache +0 -0
  38. data/spec/dummy/tmp/cache/assets/development/sprockets/v3.0/rRXYm5yDdh2lrn8etfERia5zGqWg3_cJ3siQQG6h9UU.cache +0 -0
  39. data/spec/dummy/tmp/cache/assets/development/sprockets/v3.0/t3hd5M5Qs7xWqz8gFCvXf781-4lYaem1SZCLRh47qCc.cache +1 -0
  40. data/spec/dummy/tmp/cache/assets/development/sprockets/v3.0/yHIJ2OseWB_qclWx7fwHLHPAVYOch64QqS8Y07WHhRk.cache +0 -0
  41. data/spec/dummy/tmp/cache/assets/development/sprockets/v3.0/yuW5Zfj9wAku7kLsnPBHwLsetLDeWKm9ju_dm_GLgf0.cache +1 -0
  42. data/spec/features/full_search_form_test.rb +0 -0
  43. data/spec/features/range_search_form_test.rb +79 -0
  44. data/spec/features/search_performance_test_in_app.rb +0 -0
  45. data/spec/features/simple_search_form_test.rb +34 -9
  46. data/spec/glasses_spec.rb +8 -1
  47. data/spec/test_only_methods/example_only_methods.rb +65 -0
  48. data/spec/tests/full_search_test.rb +63 -0
  49. data/spec/tests/parameters_priority_test.rb +51 -0
  50. data/spec/tests/performance_test.rb +0 -0
  51. data/spec/tests/range_search_test.rb +43 -0
  52. data/spec/tests/sanitized_search_test.rb +19 -7
  53. data/spec/tests/search_test.rb +18 -8
  54. metadata +78 -4
  55. data/spec/scratches/example_only_methods.rb +0 -26
@@ -0,0 +1 @@
1
+ I"�file:///Users/otamm/Documents/Code/Ruby/gems/glasses/gem/spec/dummy/app/assets/stylesheets/application.css?type=text/css&pipeline=self&id=4da1c8ce87c7c652239d0e67030d4918f796d37e2f3bce447badc8d2f783aeb1:ET
@@ -0,0 +1 @@
1
+ "%֧�NTZq�בH�L��#p3��Jg!��)
@@ -0,0 +1 @@
1
+ I"�file:///Users/otamm/Documents/Code/Ruby/gems/glasses/gem/spec/dummy/app/assets/stylesheets/application.css?type=text/css&id=6bde0bbabf49d0acbb323983a3903fa84ee1429caee35b736c506b4ad6bf53d4:ET
@@ -0,0 +1,2 @@
1
+ [o:Set:
2
+ @hash{ I"environment-version:ETTI"environment-paths;TTI">processors:type=text/css&file_type=text/css&pipeline=self;TTI"qfile-digest:///Users/otamm/Documents/Code/Ruby/gems/glasses/gem/spec/dummy/app/assets/stylesheets/search.css;TT
@@ -0,0 +1,2 @@
1
+ [o:Set:
2
+ @hash{ I"environment-version:ETTI"environment-paths;TTI"Zprocessors:type=application/javascript&file_type=application/javascript&pipeline=self;TTI"pfile-digest:///Users/otamm/Documents/Code/Ruby/gems/glasses/gem/spec/dummy/app/assets/javascripts/search.js;TT
@@ -0,0 +1 @@
1
+ "%L�m�u���cÀ�]e���m͏��
@@ -0,0 +1,2 @@
1
+ [o:Set:
2
+ @hash{ I"environment-version:ETTI"environment-paths;TTI">processors:type=text/css&file_type=text/css&pipeline=self;TTI"vfile-digest:///Users/otamm/Documents/Code/Ruby/gems/glasses/gem/spec/dummy/app/assets/stylesheets/application.css;TTI"ffile-digest:///Users/otamm/Documents/Code/Ruby/gems/glasses/gem/spec/dummy/app/assets/stylesheets;TTI"qfile-digest:///Users/otamm/Documents/Code/Ruby/gems/glasses/gem/spec/dummy/app/assets/stylesheets/search.css;TT
@@ -0,0 +1,2 @@
1
+ [o:Set:
2
+ @hash{ I"environment-version:ETTI"environment-paths;TTI"Lprocessors:type=application/javascript&file_type=application/javascript;TTI"ufile-digest:///Users/otamm/Documents/Code/Ruby/gems/glasses/gem/spec/dummy/app/assets/javascripts/application.js;TTI"Zprocessors:type=application/javascript&file_type=application/javascript&pipeline=self;TTI"pfile-digest:///Users/otamm/Documents/Code/Ruby/gems/glasses/gem/spec/dummy/app/assets/javascripts/search.js;TTI"ffile-digest:///Users/otamm/Documents/Code/Ruby/gems/glasses/gem/spec/dummy/app/assets/javascripts;TT
@@ -0,0 +1,2 @@
1
+ [o:Set:
2
+ @hash{ I"environment-version:ETTI"environment-paths;TTI"Zprocessors:type=application/javascript&file_type=application/javascript&pipeline=self;TTI"ufile-digest:///Users/otamm/Documents/Code/Ruby/gems/glasses/gem/spec/dummy/app/assets/javascripts/application.js;TTI"ffile-digest:///Users/otamm/Documents/Code/Ruby/gems/glasses/gem/spec/dummy/app/assets/javascripts;TTI"pfile-digest:///Users/otamm/Documents/Code/Ruby/gems/glasses/gem/spec/dummy/app/assets/javascripts/search.js;TT
@@ -0,0 +1,2 @@
1
+ "%����͹mm�
2
+ a�l�|a56���v�6}��(&5
@@ -0,0 +1,2 @@
1
+ [o:Set:
2
+ @hash{ I"environment-version:ETTI"environment-paths;TTI"0processors:type=text/css&file_type=text/css;TTI"vfile-digest:///Users/otamm/Documents/Code/Ruby/gems/glasses/gem/spec/dummy/app/assets/stylesheets/application.css;TTI">processors:type=text/css&file_type=text/css&pipeline=self;TTI"qfile-digest:///Users/otamm/Documents/Code/Ruby/gems/glasses/gem/spec/dummy/app/assets/stylesheets/search.css;TTI"ffile-digest:///Users/otamm/Documents/Code/Ruby/gems/glasses/gem/spec/dummy/app/assets/stylesheets;TT
@@ -0,0 +1 @@
1
+ I"�file:///Users/otamm/Documents/Code/Ruby/gems/glasses/gem/spec/dummy/app/assets/javascripts/application.js?type=application/javascript&pipeline=self&id=7fde357b9eb6873868c89caa44207528dc578512439622fcfd9c3cebcb905cdc:ET
@@ -0,0 +1 @@
1
+ I"�file:///Users/otamm/Documents/Code/Ruby/gems/glasses/gem/spec/dummy/app/assets/javascripts/search.js?type=application/javascript&pipeline=self&id=fa727172541f6e7d9128e043a1734b40da3e3e7eb3909784614b21b100897cec:ET
@@ -0,0 +1 @@
1
+ I"�file:///Users/otamm/Documents/Code/Ruby/gems/glasses/gem/spec/dummy/app/assets/javascripts/application.js?type=application/javascript&id=994fc115aaf0b2f40165a45906d6c62bbfecf910708075a2d5d73e22d9ccfca5:ET
@@ -0,0 +1 @@
1
+ "%�W\�yho9S���ƫ˥��)|�~���(���
@@ -0,0 +1 @@
1
+ "%&P�꽠�9�/sB��k�b~LnJo��UJ��
@@ -0,0 +1 @@
1
+ I"�file:///Users/otamm/Documents/Code/Ruby/gems/glasses/gem/spec/dummy/app/assets/stylesheets/search.css?type=text/css&pipeline=self&id=5a9397f790a4eb98cae05e656658464b83abf79a64d5befc05bc166e496ab495:ET
@@ -0,0 +1 @@
1
+ "%Ѱč@�����6H�uZoX�Z�gbh0W��V
File without changes
@@ -0,0 +1,79 @@
1
+ describe "search with a range constraint within web app", type: :feature do
2
+
3
+ context 'search with params sanitized by ActiveRecord' do
4
+
5
+ before :each do
6
+ visit 'range_search'
7
+ end
8
+
9
+ it 'returns all the results with a field bigger than or equal to some arbitrary value' do
10
+ fill_in 'Minimum Age:', with: '110'
11
+ click_button "Search"
12
+ page.should have_content 'GR8 SUCCESS'
13
+ page.should have_content '3'
14
+ end
15
+
16
+ it 'returns all the results with a field lesser than or equal to some arbitrary value' do
17
+ fill_in 'Maximum Age:', with: '110'
18
+ click_button "Search"
19
+ page.should have_content 'GR8 SUCCESS'
20
+ page.should have_content '8'
21
+ end
22
+
23
+ it 'returns all the results with a field bigger than or equal to some arbitrary value and with another field lesser than or equal to some other arbitrary value' do
24
+ fill_in 'Minimum Age:', with: '20'
25
+ fill_in 'Maximum Age:', with: '110'
26
+ click_button "Search"
27
+ page.should have_content 'GR8 SUCCESS'
28
+ page.should have_content '8'
29
+ end
30
+
31
+ it 'returns all the results which satisfies both "field in the range" and "field with same prefix" conditions' do
32
+ fill_in 'First Name:', with: 'Jane'
33
+ fill_in 'Minimum Age:', with: '110'
34
+ click_button "Search"
35
+ page.should have_content 'GR8 SUCCESS'
36
+ page.should have_content '1'
37
+ end
38
+
39
+ end
40
+
41
+ context 'search without params sanitized by ActiveRecord' do
42
+
43
+ before :each do
44
+ visit 'raw_range_search'
45
+ end
46
+
47
+ it 'returns all the results with a field bigger than or equal to some arbitrary value' do
48
+ fill_in 'Minimum Age:', with: '110'
49
+ click_button "Search"
50
+ page.should have_content 'GR8 SUCCESS'
51
+ page.should have_content '3'
52
+ end
53
+
54
+ it 'returns all the results with a field lesser than or equal to some arbitrary value' do
55
+ fill_in 'Maximum Age:', with: '110'
56
+ click_button "Search"
57
+ page.should have_content 'GR8 SUCCESS'
58
+ page.should have_content '8'
59
+ end
60
+
61
+ it 'returns all the results with a field bigger than or equal to some arbitrary value and with another field lesser than or equal to some other arbitrary value' do
62
+ fill_in 'Minimum Age:', with: '20'
63
+ fill_in 'Maximum Age:', with: '110'
64
+ click_button "Search"
65
+ page.should have_content 'GR8 SUCCESS'
66
+ page.should have_content '8'
67
+ end
68
+
69
+ it 'returns all the results which satisfies both "field in the range" and "field with same prefix" conditions' do
70
+ fill_in 'First Name:', with: 'Jane'
71
+ fill_in 'Minimum Age:', with: '110'
72
+ click_button "Search"
73
+ page.should have_content 'GR8 SUCCESS'
74
+ page.should have_content '1'
75
+ end
76
+
77
+ end
78
+
79
+ end
@@ -1,6 +1,6 @@
1
- describe "a simple search", type: :feature do
1
+ describe "search within web app", type: :feature do
2
2
 
3
- context "search params not sanitized" do
3
+ context "search params sanitized in ActiveRecord" do
4
4
 
5
5
  before :each do
6
6
  visit 'simple_search'
@@ -13,15 +13,40 @@ describe "a simple search", type: :feature do
13
13
  page.should have_content '1'
14
14
  end
15
15
 
16
- it "is vulnerable to SQL injections when no defenses are present" do
17
- fill_in "First Name:", with: "' OR 1 = 1 ) --"
18
- click_button "Search"
19
- page.should have_content "GR8 SUCCESS"
20
- page.should have_content "10 entries"
21
- end
16
+ #it "is vulnerable to SQL injections when no defenses are present" do
17
+ # fill_in "First Name:", with: "' OR 1 = 1 ) --"
18
+ # click_button "Search"
19
+ # page.should have_content "GR8 SUCCESS"
20
+ # page.should have_content "10 entries"
21
+ #end
22
+
23
+ #context "search with a boolean value as one of the params" do
24
+
25
+ it "correctly return values when a boolean value is passed to the form and there are matches" do
26
+ fill_in 'First Name:', with: 'Jane'
27
+ #all('input[type=checkbox]').each { |checkbox| check(checkbox) }
28
+ # forms checkboxes are checked "true" by default.
29
+ click_button 'Search'
30
+ page.should have_content 'GR8 SUCCESS'
31
+ page.should have_content '1'
32
+ end
33
+
34
+ it "correctly return values when a boolean value is passed to the form and there are no matches" do
35
+ fill_in 'First Name:', with: 'Rachel'
36
+ #all('input[type=checkbox]').each { |checkbox| check(checkbox) }
37
+ # forms checkboxes are checked "true" by default.
38
+ click_button 'Search'
39
+ #puts page.body
40
+ page.should have_content 'WOPS'
41
+ page.should have_content '0'
42
+ end
43
+
44
+ #end
22
45
 
23
46
  end
24
47
 
48
+ =begin
49
+ commented out. This part has become redundant.
25
50
  context "search params sanitized in a search method of this gem with built-in defense" do
26
51
 
27
52
  before :each do
@@ -43,6 +68,7 @@ describe "a simple search", type: :feature do
43
68
  end
44
69
 
45
70
  end
71
+ =end
46
72
 
47
73
  context "search params sanitized in a controller method" do
48
74
 
@@ -53,7 +79,6 @@ describe "a simple search", type: :feature do
53
79
  it "correctly searches and displays matches" do
54
80
  fill_in 'First Name:', with: 'Jan'
55
81
  click_button "Search"
56
- puts page.body
57
82
  page.should have_content 'GR8 SUCCESS'
58
83
  page.should have_content '1'
59
84
  end
@@ -2,5 +2,12 @@ require 'spec_helper'
2
2
  #tests in a raw environment with a hash serving as input (the default ruby web app frameworks "params" hash is the emulated input)
3
3
  require 'tests/search_test'
4
4
  require 'tests/sanitized_search_test'
5
+ require 'tests/full_search_test'
6
+ require 'tests/range_search_test'
7
+ require 'tests/performance_test'
8
+ require 'tests/parameters_priority_test'
5
9
  #tests in a simulated webpage environment using Capybara
6
- require 'features/simple_search_form_test'
10
+ require 'features/simple_search_form_test'
11
+ require 'features/full_search_form_test'
12
+ require 'features/range_search_form_test'
13
+ require 'features/search_performance_test_in_app'
@@ -0,0 +1,65 @@
1
+ module BrokenGlasses
2
+ def search_within_range(model_to_search,params_hash)
3
+ params_array = params_hash.to_a
4
+ query = ""
5
+ consecutive_ints = 0
6
+ params_array.each_with_index do |pair, index|
7
+ if !pair[1].empty?
8
+ if pair[0].to_s[key.size-3,key.size] == "_id" || pair[] ~= /\A[-+]?[0-9]+\z/ # checks if value is basically an integer within quotes
9
+
10
+ possible_query = "#{key} = #{val} AND "
11
+ consecutive_ints += 1
12
+ if consecutive_ints % 2 == 0 #check if the case is of an integer field followed by another
13
+
14
+ end
15
+ query += possible_query
16
+ else
17
+ query += "#{key} LIKE '#{val}%' AND " # percent sign matches any string of 0 or more chars.
18
+ end
19
+ end
20
+ end
21
+ if !query.empty?
22
+ query = query[0,query.size-5]
23
+ model_to_search.where(query)
24
+ else
25
+ []
26
+ end
27
+ end
28
+
29
+ def self.full_search_range(model_to_search, params_hash)
30
+ query = []
31
+ query_params = []
32
+ params_hash.each do |key,val|
33
+ if !val.empty?
34
+ key_suffix = key.to_s[key.size-3,key.size]
35
+ if key_suffix == "min"
36
+ query.push("#{key[0,key.size-4]} >= ?")
37
+ query_params.push(val.to_s)
38
+ elsif key_suffix == "max"
39
+ query.push("#{key[0,key.size-4]} <= ?")
40
+ query_params.push(val.to_s)
41
+ elsif key_suffix == "_id"
42
+ query.push("#{key} = ?")
43
+ query_params.push(val.to_s)
44
+ else
45
+ query.push("#{key} LIKE ?") # percent sign matches any string of 0 or more chars.
46
+ query_params.push("%" + val + "%")
47
+ end
48
+ end
49
+ end
50
+ if !query.empty?
51
+ if query.size == 1
52
+ return model_to_search.where(query.pop(), query_params.pop())
53
+ else
54
+ results = model_to_search.where(query.pop(), query_params.pop())
55
+ (results.size).times do |search|
56
+ results = results.where(query.pop(), query_params.pop()) # important to note that ".where()" is not hitting the database on this line.
57
+ end
58
+ return results
59
+ end
60
+ else
61
+ []
62
+ end
63
+ end
64
+
65
+ end
@@ -0,0 +1,63 @@
1
+ describe 'performs a full search on strings, looking for fragments of text instead of prefixes.' do
2
+
3
+ context 'performs a full search that is sanitized by ActiveRecord' do
4
+
5
+ it 'returns results which contain the fragment' do
6
+ (Glasses.full_search(Player, {first_name: "bb"}).size).should == 1
7
+ end
8
+
9
+ it 'returns results which contain the fragment and other parameters' do
10
+ (Glasses.full_search(Player, {first_name: "bb", email: ".com"}).size).should == 1
11
+ end
12
+
13
+ it 'does not return anything when no params match any text fragment for that column' do
14
+ (Glasses.full_search(Player, {first_name: "zidbb"}).size).should == 0
15
+ end
16
+
17
+ it 'does not return anything when there is no record which matches all the params' do
18
+ (Glasses.full_search(Player, {first_name: "zidbb", email: "@"}).size).should == 0
19
+ end
20
+
21
+ it 'returns all the results which satisfies both "field in the range" and "field with text fragment" conditions' do
22
+ (Glasses.full_search_range(Player, {first_name: 'ane', age_min: '110'}).size).should == 1
23
+ end
24
+
25
+ context 'performs a full search which includes a range that is not sanitized by ActiveRecord' do
26
+
27
+ it 'returns all the results which satisfies both "field in the range" and "field with text fragment" conditions' do
28
+ (Glasses.full_search_range(Player, {first_name: 'ane', age_min: '110'}).size).should == 1
29
+ end
30
+
31
+ end
32
+
33
+ end
34
+
35
+ context 'performs a full search that is not sanitized by ActiveRecord' do
36
+
37
+ it 'returns results which contain the fragment' do
38
+ (Glasses.full_raw_search(Player, {first_name: "bb"}).size).should == 1
39
+ end
40
+
41
+ it 'returns results which contain the fragment and other parameters' do
42
+ (Glasses.full_raw_search(Player, {first_name: "bb", email: ".com"}).size).should == 1
43
+ end
44
+
45
+ it 'does not return anything when no params match any text fragment for that column' do
46
+ (Glasses.full_raw_search(Player, {first_name: "zidbb"}).size).should == 0
47
+ end
48
+
49
+ it 'does not return anything when there is no record which matches all the params' do
50
+ (Glasses.full_raw_search(Player, {first_name: "zidbb", email: "@"}).size).should == 0
51
+ end
52
+
53
+ context 'performs a full search which includes a range that is not sanitized by ActiveRecord' do
54
+
55
+ it 'returns all the results which satisfies both "field in the range" and "field with text fragment" conditions' do
56
+ (Glasses.full_raw_search_range(Player, {first_name: 'ane', age_min: '110'}).size).should == 1
57
+ end
58
+
59
+ end
60
+
61
+ end
62
+
63
+ end
@@ -0,0 +1,51 @@
1
+ describe "search params are reordered in a way to give first entrance to quicker queries; the arrays will be .pop()ed, so 'prioritized' == 'last_element' here." do
2
+
3
+ context "params include strings and ints/bools" do
4
+
5
+ it "puts integers before strings" do
6
+ Glasses.prioritize_ints_over_strings(["user_id = ?","first_name LIKE ?", "last_name LIKE ?"], ["666", "Johnny", "Rotten"]).should == [["last_name LIKE ?", "first_name LIKE ?", "user_id = ?"],["Rotten", "Johnny", "666"]]
7
+ end
8
+
9
+ it "puts booleans before strings" do
10
+ Glasses.prioritize_ints_over_strings(["is_cokehead_bool = ?", "first_name LIKE ?", "last_name LIKE ?"], ["1", "Johnny", "Rotten"]).should == [["last_name LIKE ?", "first_name LIKE ?", "is_cokehead_bool = ?"],["Rotten", "Johnny", "1"]]
11
+ end
12
+
13
+ it "puts both integers and booleans before strings" do
14
+ Glasses.prioritize_ints_over_strings(["user_id = ?", "is_cokehead_bool = ?", "first_name LIKE ?", "last_name LIKE ?"], ["666", "1", "Johnny", "Rotten"]).should == [["last_name LIKE ?", "first_name LIKE ?", "user_id = ?", "is_cokehead_bool = ?"],["Rotten", "Johnny", "666", "1"]]
15
+ end
16
+
17
+ it "returns the same query with inverted params if it does not contain more than one kind of input (strings)" do
18
+ Glasses.prioritize_ints_over_strings(["first_name LIKE ?", "last_name LIKE ?"], ["Johnny", "Rotten"]).should == [["last_name LIKE ?", "first_name LIKE ?"], ["Rotten", "Johnny"]]
19
+ end
20
+
21
+ end
22
+
23
+ context "params include strings, ints/bools and ranges" do
24
+
25
+ it "puts integers before strings" do
26
+ Glasses.prioritize_ints_over_strings_and_ranges(["user_id = ?","first_name LIKE ?", "last_name LIKE ?"], ["666", "Johnny", "Rotten"]).should == [["last_name LIKE ?", "first_name LIKE ?", "user_id = ?"],["Rotten", "Johnny", "666"]]
27
+ end
28
+
29
+ it "puts booleans before strings" do
30
+ Glasses.prioritize_ints_over_strings_and_ranges(["is_cokehead_bool = ?", "first_name LIKE ?", "last_name LIKE ?"], ["1", "Johnny", "Rotten"]).should == [["last_name LIKE ?", "first_name LIKE ?", "is_cokehead_bool = ?"],["Rotten", "Johnny", "1"]]
31
+ end
32
+
33
+ it "puts both integers and booleans before strings" do
34
+ Glasses.prioritize_ints_over_strings_and_ranges(["user_id = ?", "is_cokehead_bool = ?", "first_name LIKE ?", "last_name LIKE ?"], ["666", "1", "Johnny", "Rotten"]).should == [["last_name LIKE ?", "first_name LIKE ?", "user_id = ?", "is_cokehead_bool = ?"],["Rotten", "Johnny", "666", "1"]]
35
+ end
36
+
37
+ it "puts integers, booleans and ranges before strings" do
38
+ Glasses.prioritize_ints_over_strings_and_ranges(["user_id = ?", "is_cokehead_bool = ?", "age_min >= ?", "age_max <= ?", "first_name LIKE ?", "last_name LIKE ?"], ["666", "1", "2", "456", "Johnny", "Rotten"]).should == [["last_name LIKE ?", "first_name LIKE ?", "age_max <= ?", "age_min >= ?", "user_id = ?", "is_cokehead_bool = ?"],["Rotten", "Johnny", "456", "2", "666", "1"]]
39
+ end
40
+
41
+ it "puts ints/booleans before ranges" do
42
+ Glasses.prioritize_ints_over_strings_and_ranges(["user_id = ?", "is_cokehead_bool = ?", "age_min >= ?", "age_max <= ?"], ["666", "1", "2", "456"]).should == [["age_max <= ?", "age_min >= ?", "user_id = ?", "is_cokehead_bool = ?"],["456", "2", "666", "1"]]
43
+ end
44
+
45
+ it "returns the same query with inverted params if it does not contain more than one kind of input (strings)" do
46
+ Glasses.prioritize_ints_over_strings_and_ranges(["first_name LIKE ?", "last_name LIKE ?"], ["Johnny", "Rotten"]).should == [["last_name LIKE ?", "first_name LIKE ?"], ["Rotten", "Johnny"]]
47
+ end
48
+
49
+ end
50
+
51
+ end
File without changes
@@ -0,0 +1,43 @@
1
+ describe 'search entries which have a value within a specific range' do
2
+
3
+ context 'search with params sanitized by ActiveRecord' do
4
+
5
+ it 'returns all the results with a field bigger than or equal to some arbitrary value' do
6
+ (Glasses.search_range(Player, {age_min: '110'}).size).should == 3
7
+ end
8
+
9
+ it 'returns all the results with a field lesser than or equal to some arbitrary value' do
10
+ (Glasses.search_range(Player, {age_max: '110'}).size).should == 8
11
+ end
12
+
13
+ it 'returns all the results with a field bigger than or equal to some arbitrary value and with another field lesser than or equal to some other arbitrary value' do
14
+ (Glasses.search_range(Player, {age_min: '20', age_max: '110'}).size).should == 4
15
+ end
16
+
17
+ it 'returns all the results which satisfies both "field in the range" and "field with same prefix" conditions' do
18
+ (Glasses.search_range(Player, {first_name: 'Jane', age_min: '110'}).size).should == 1
19
+ end
20
+
21
+ end
22
+
23
+ context 'search without params sanitized by ActiveRecord' do
24
+
25
+ it 'returns all the results with a field bigger than or equal to some arbitrary value' do
26
+ (Glasses.raw_search_range(Player, {age_min: '110'}).size).should == 3
27
+ end
28
+
29
+ it 'returns all the results with a field lesser than or equal to some arbitrary value' do
30
+ (Glasses.raw_search_range(Player, {age_max: '110'}).size).should == 8
31
+ end
32
+
33
+ it 'returns all the results with a field bigger than or equal to some arbitrary value and with another field lesser than or equal to some other arbitrary value' do
34
+ (Glasses.raw_search_range(Player, {age_min: '20', age_max: '110'}).size).should == 4
35
+ end
36
+
37
+ it 'returns all the results which satisfies both "field in the range" and "field with same prefix" conditions' do
38
+ (Glasses.raw_search_range(Player, {first_name: 'Jane', age_min: '110'}).size).should == 1
39
+ end
40
+
41
+ end
42
+
43
+ end