Skip to content

Commit d48932d

Browse files
committed
Merge pull request #50 from potatosalad/filter-feature
Added filter support and tests for string, date_range, numeric, select, and check_boxes filters.
2 parents c77619c + e31b605 commit d48932d

File tree

10 files changed

+264
-52
lines changed

10 files changed

+264
-52
lines changed

Gemfile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,12 @@ group :assets do
2222
end
2323

2424
gem 'jquery-rails'
25+
gem 'jquery-ui-rails'
2526
gem 'jslint'
2627

2728
group :test do
2829
gem 'capybara'
30+
gem 'poltergeist'
2931
gem 'launchy'
32+
gem 'simplecov', require: false
3033
end

lib/meta_search/searches/mongoid.rb

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,48 @@ def initialize relation, params, options
1515

1616
def build
1717
params.each_pair do |field_query, value|
18-
field, query = field_query.scan(metasearch_regexp).first
18+
field, query = field_query.to_s.scan(metasearch_regexp).first
1919
case query.to_sym
20-
when :contains
20+
when :equals, :eq
21+
@relation = relation.where(field => value)
22+
when :does_not_equal, :ne, :not_eq
23+
@relation = relation.where(field.to_sym.ne => value)
24+
when :contains, :like, :matches
2125
@relation = relation.where(field => /#{value}/)
26+
when :does_not_contain, :nlike, :not_matches
27+
@relation = relation.where(field.to_sym.not => /#{value}/)
28+
when :starts_with, :sw
29+
@relation = relation.where(field.to_sym => /\A#{Regexp.quote(value)}/)
30+
when :does_not_start_with, :dnsw
31+
@relation = relation.where(field.to_sym.not => /\A#{Regexp.quote(value)}/)
32+
when :ends_with, :ew
33+
@relation = relation.where(field.to_sym => /#{Regexp.quote(value)}\z/)
34+
when :does_not_end_with, :dnew
35+
@relation = relation.where(field.to_sym.not => /#{Regexp.quote(value)}\z/)
36+
when :greater_than, :gt
37+
@relation = relation.where(field.to_sym.gt => value)
38+
when :less_than, :lt
39+
@relation = relation.where(field.to_sym.lt => value)
40+
when :greater_than_or_equal_to, :gte, :gteq
41+
@relation = relation.where(field.to_sym.gte => value)
42+
when :less_than_or_equal_to, :lte, :lteq
43+
@relation = relation.where(field.to_sym.lte => value)
44+
when :in
45+
@relation = relation.where(field.to_sym.in => Array.wrap(value))
46+
when :not_in, :ni
47+
@relation = relation.where(field.to_sym.nin => Array.wrap(value))
48+
when :is_true
49+
@relation = relation.where(field => true)
50+
when :is_false
51+
@relation = relation.where(field => false)
52+
when :is_present
53+
@relation = relation.where(field.to_sym.exists => true)
54+
when :is_blank
55+
@relation = relation.where(field.to_sym.exists => false)
56+
when :is_null
57+
@relation = relation.where(field => nil)
58+
when :is_not_null
59+
@relation = relation.where(field.to_sym.ne => nil)
2260
else
2361
raise [field_query, value].inspect
2462
end
@@ -54,11 +92,12 @@ def method_missing name, *args, &block
5492
end
5593

5694
def metasearch_regexp
57-
field_names = klass.content_columns.map(&:name)
95+
# field_names = klass.content_columns.map(&:name)
96+
field_names = klass.fields.map(&:second).map(&:name)
5897

5998
conditions = MetaSearch::DEFAULT_WHERES.map {|condition| condition[0...-1]} # pop tail options
6099

61-
/\A(#{field_names.join('|')})_(#{conditions.join('|')})/
100+
/\A(#{field_names.join('|')})_(#{conditions.join('|')})\z/
62101
end
63102

64103
end

spec/features/smoke_spec.rb

Lines changed: 183 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -5,69 +5,206 @@
55
describe 'browse the test app' do
66
let(:password) { 'foobar•secret' }
77
let(:email) { '[email protected]' }
8+
let(:admin_user) do
9+
AdminUser.where(email: email).first || AdminUser.create!(email: email, password: password)
10+
end
11+
let(:other_email) { '[email protected]' }
12+
let(:other_user) do
13+
AdminUser.where(email: other_email).first || AdminUser.create!(email: other_email, password: password)
14+
end
815

916
before do
1017
Mongoid.purge!
11-
AdminUser.create! email: email, password: password
18+
expect(admin_user).to be_persisted
19+
expect(other_user).to be_persisted
1220
end
13-
before { visit '/admin' }
14-
15-
it 'does something' do
16-
I18n.t('active_admin.devise.login.submit').should eq('Login')
1721

18-
# Auth
19-
fill_in 'Email', with: email
20-
fill_in 'Password', with: password
21-
click_on 'Login'
22+
context 'when authorized' do
23+
before do
24+
visit '/admin'
2225

23-
# New
24-
click_on 'Posts'
25-
click_on 'New Post'
26-
fill_in 'Title', with: 'dhh screencast'
27-
fill_in 'Body', with: 'is still the best intro to rails'
26+
I18n.t('active_admin.devise.login.submit').should eq('Login')
2827

29-
# Create
30-
click_on 'Create Post'
28+
# Auth
29+
fill_in 'Email', with: email
30+
fill_in 'Password', with: password
31+
click_on 'Login'
32+
end
3133

32-
within '.attributes_table.post' do
33-
page.should have_content('dhh screencast')
34-
page.should have_content('is still the best intro to rails')
34+
it 'creates and edits a new post' do
35+
# New
36+
click_on 'Posts'
37+
click_on 'New Post'
38+
fill_in 'Title', with: 'dhh screencast'
39+
fill_in 'Body', with: 'is still the best intro to rails'
40+
41+
# Create
42+
click_on 'Create Post'
43+
44+
within '.attributes_table.post' do
45+
page.should have_content('dhh screencast')
46+
page.should have_content('is still the best intro to rails')
47+
end
48+
49+
# Edit
50+
click_on 'Edit Post'
51+
fill_in 'Title', with: 'DHH original screencast'
52+
53+
# Update
54+
click_on 'Update Post'
55+
56+
within '.attributes_table.post' do
57+
page.should have_content('DHH original screencast')
58+
page.should have_content('is still the best intro to rails')
59+
end
60+
61+
# List
62+
within('.breadcrumb') { click_on 'Posts' }
63+
within '#index_table_posts' do
64+
page.should have_content('DHH original screencast')
65+
page.should have_content('is still the best intro to rails')
66+
end
3567
end
3668

37-
# Edit
38-
click_on 'Edit Post'
39-
fill_in 'Title', with: 'DHH original screencast'
69+
context 'with 1 post' do
4070

41-
# Update
42-
click_on 'Update Post'
71+
before do
72+
Post.create!(title: 'Quick Brown Fox', body: 'The quick brown fox jumps over the lazy dog.', view_count: 5, admin_user: admin_user, other_user: other_user)
73+
74+
click_on 'Posts'
75+
end
76+
77+
describe 'filters' do
78+
describe 'string' do
79+
it 'searches by title' do
80+
fill_in 'Search Title', with: 'Brown'
81+
click_on 'Filter'
4382

44-
within '.attributes_table.post' do
45-
page.should have_content('DHH original screencast')
46-
page.should have_content('is still the best intro to rails')
47-
end
83+
within '#index_table_posts' do
84+
page.should have_content('Quick Brown Fox')
85+
end
4886

49-
# List
50-
within('.breadcrumb') { click_on 'Posts' }
51-
within '#index_table_posts' do
52-
page.should have_content('DHH original screencast')
53-
page.should have_content('is still the best intro to rails')
54-
end
87+
fill_in 'Search Title', with: 'dog'
88+
click_on 'Filter'
89+
page.should_not have_content('Quick Brown Fox')
90+
91+
fill_in 'Search Title', with: ''
92+
click_on 'Filter'
93+
94+
page.should have_content('Displaying 1 Post')
95+
end
96+
end
97+
98+
describe 'date_range' do
99+
it 'searches by created_at range' do
100+
fill_in 'q[created_at_gte]', with: 1.day.ago.to_datetime.strftime("%Y-%m-%d")
101+
fill_in 'q[created_at_lte]', with: 2.days.from_now.to_datetime.strftime("%Y-%m-%d")
102+
click_on 'Filter'
103+
104+
within '#index_table_posts' do
105+
page.should have_content('Quick Brown Fox')
106+
end
55107

56-
# Filter
57-
fill_in 'Search Title', with: 'original'
58-
click_on 'Filter'
108+
fill_in 'q[created_at_gte]', with: 1.day.from_now.to_datetime.strftime("%Y-%m-%d")
109+
click_on 'Filter'
110+
page.should_not have_content('Quick Brown Fox')
59111

60-
within '#index_table_posts' do
61-
page.should have_content('DHH original screencast')
62-
end
112+
fill_in 'q[created_at_gte]', with: ''
113+
fill_in 'q[created_at_lte]', with: ''
114+
click_on 'Filter'
115+
116+
page.should have_content('Displaying 1 Post')
117+
end
118+
end
119+
120+
describe 'numeric' do
121+
it 'searches by created_at range', js: true do
122+
within '.filter_numeric' do
123+
find(:select).find('option[value=view_count_eq]').select_option
124+
end
125+
fill_in 'View count', with: '5'
126+
click_on 'Filter'
127+
128+
within '#index_table_posts' do
129+
page.should have_content('Quick Brown Fox')
130+
end
63131

64-
fill_in 'Search Title', with: 'orizinal'
65-
click_on 'Filter'
66-
page.should_not have_content('DHH original screencast')
132+
fill_in 'View count', with: '6'
133+
click_on 'Filter'
134+
page.should_not have_content('Quick Brown Fox')
67135

68-
fill_in 'Search Title', with: ''
69-
click_on 'Filter'
136+
within '.filter_numeric' do
137+
find(:select).find('option[value=view_count_lt]').select_option
138+
end
139+
click_on 'Filter'
70140

71-
page.should have_content('Displaying 1 Post')
141+
within '#index_table_posts' do
142+
page.should have_content('Quick Brown Fox')
143+
end
144+
145+
within '.filter_numeric' do
146+
find(:select).find('option[value=view_count_gt]').select_option
147+
end
148+
click_on 'Filter'
149+
page.should_not have_content('Quick Brown Fox')
150+
151+
fill_in 'View count', with: '4'
152+
click_on 'Filter'
153+
154+
within '#index_table_posts' do
155+
page.should have_content('Quick Brown Fox')
156+
end
157+
158+
fill_in 'View count', with: ''
159+
click_on 'Filter'
160+
161+
page.should have_content('Displaying 1 Post')
162+
end
163+
end
164+
end
165+
166+
describe 'select' do
167+
it 'selects by admin_user' do
168+
select email, from: 'Admin user'
169+
click_on 'Filter'
170+
171+
within '#index_table_posts' do
172+
page.should have_content('Quick Brown Fox')
173+
end
174+
175+
select other_email, from: 'Admin user'
176+
click_on 'Filter'
177+
page.should_not have_content('Quick Brown Fox')
178+
179+
select 'Any', from: 'Admin user'
180+
click_on 'Filter'
181+
182+
page.should have_content('Displaying 1 Post')
183+
end
184+
end
185+
186+
describe 'check_boxes' do
187+
it 'checks by other_user' do
188+
check email
189+
click_on 'Filter'
190+
page.should_not have_content('Quick Brown Fox')
191+
192+
check other_email
193+
click_on 'Filter'
194+
195+
within '#index_table_posts' do
196+
page.should have_content('Quick Brown Fox')
197+
end
198+
199+
uncheck email
200+
uncheck other_email
201+
click_on 'Filter'
202+
203+
page.should have_content('Displaying 1 Post')
204+
end
205+
end
206+
207+
end
72208
end
209+
73210
end

spec/spec_helper.rb

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,14 @@
22
ENV['RAILS_ENV'] ||= 'test'
33
require 'rubygems'
44
require 'bundler'
5+
6+
if %w(true 1).include?(ENV['COVERAGE'])
7+
require 'simplecov'
8+
SimpleCov.start do
9+
add_filter '/test_app/'
10+
end
11+
end
12+
513
Bundler.require
614

715
require File.expand_path("../../test_app/config/environment", __FILE__)
@@ -10,6 +18,7 @@
1018

1119
# Requires supporting ruby files with custom matchers and macros, etc,
1220
# in spec/support/ and its subdirectories.
21+
Dir[File.join(File.expand_path("../../", __FILE__), "spec/support/**/*.rb")].each {|f| require f}
1322
Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
1423

1524
RSpec.configure do |config|

spec/support/capybara.rb

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
1-
require 'capibara/rails'
1+
require 'capybara/rails'
2+
require 'capybara/poltergeist'
3+
Capybara.javascript_driver = :poltergeist

test_app/app/admin/posts.rb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
11
ActiveAdmin.register Post do
22

3+
filter :title
4+
filter :body
5+
filter :created_at, as: :date_range
6+
filter :view_count, as: :numeric
7+
filter :admin_user, as: :select
8+
filter :other_user, as: :check_boxes
9+
310
end
Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,7 @@
1-
//= require active_admin/base
1+
//= require jquery
2+
//= require jquery_ujs
3+
//= require jquery.ui.core
4+
//= require jquery.ui.widget
5+
//= require jquery.ui.datepicker
6+
7+
//= require active_admin/application

test_app/app/models/admin_user.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,4 +37,8 @@ class AdminUser
3737

3838
## Token authenticatable
3939
# field :authentication_token, :type => String
40+
41+
def name
42+
email
43+
end
4044
end

0 commit comments

Comments
 (0)