ransack 1.4.1 → 1.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -51,8 +51,8 @@ module Ransack
51
51
  end
52
52
 
53
53
  describe '#sort_link with default search_key defined as symbol' do
54
- subject { @controller.
55
- view_context.sort_link(
54
+ subject { @controller.view_context
55
+ .sort_link(
56
56
  Person.search(
57
57
  { :sorts => ['name desc'] }, :search_key => :people_search
58
58
  ),
@@ -71,6 +71,46 @@ module Ransack
71
71
  }
72
72
  end
73
73
 
74
+ describe '#sort_link desc through association table defined as a symbol' do
75
+ subject { @controller.view_context
76
+ .sort_link(
77
+ Person.search({ :sorts => 'comments_body asc' }),
78
+ :comments_body, :controller => 'people'
79
+ )
80
+ }
81
+ it {
82
+ should match(
83
+ if ActiveRecord::VERSION::STRING =~ /^3\.[1-2]\./
84
+ /people\?q%5Bs%5D=comments.body\+desc/
85
+ else
86
+ /people\?q(%5B|\[)s(%5D|\])=comments.body\+desc/
87
+ end
88
+ )
89
+ }
90
+ it { should match /sort_link asc/ }
91
+ it { should match /Body ▲/ }
92
+ end
93
+
94
+ describe '#sort_link through association table defined as a string' do
95
+ subject { @controller.view_context
96
+ .sort_link(
97
+ Person.search({ :sorts => 'comments.body desc' }),
98
+ 'comments.body', :controller => 'people'
99
+ )
100
+ }
101
+ it {
102
+ should match(
103
+ if ActiveRecord::VERSION::STRING =~ /^3\.[1-2]\./
104
+ /people\?q%5Bs%5D=comments.body\+asc/
105
+ else
106
+ /people\?q(%5B|\[)s(%5D|\])=comments.body\+asc/
107
+ end
108
+ )
109
+ }
110
+ it { should match /sort_link desc/ }
111
+ it { should match /Comments.body ▼/ }
112
+ end
113
+
74
114
  describe '#sort_link works even if search params are a blank string' do
75
115
  before { @controller.view_context.params[:q] = '' }
76
116
  specify {
@@ -105,6 +145,127 @@ module Ransack
105
145
  }
106
146
  end
107
147
 
148
+ describe '#sort_link with multiple search_keys defined as an array' do
149
+ subject { @controller.view_context
150
+ .sort_link(
151
+ [:main_app, Person.search(:sorts => ['name desc', 'email asc'])],
152
+ :name, [:name, 'email DESC'],
153
+ :controller => 'people'
154
+ )
155
+ }
156
+ it {
157
+ should match(
158
+ /people\?q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=name\+asc&q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=email\+desc/
159
+ )
160
+ }
161
+ it {
162
+ should match /sort_link desc/
163
+ }
164
+ it {
165
+ should match /Full Name ▼/
166
+ }
167
+ end
168
+
169
+ describe '#sort_link with multiple search_keys should allow a label to be specified' do
170
+ subject { @controller.view_context
171
+ .sort_link(
172
+ [:main_app, Person.search(:sorts => ['name desc', 'email asc'])],
173
+ :name, [:name, 'email DESC'],
174
+ 'Property Name',
175
+ :controller => 'people'
176
+ )
177
+ }
178
+ it {
179
+ should match /Property Name ▼/
180
+ }
181
+ end
182
+
183
+ describe '#sort_link with multiple search_keys should flip multiple fields specified without a direction' do
184
+ subject { @controller.view_context
185
+ .sort_link(
186
+ [:main_app, Person.search(:sorts => ['name desc', 'email asc'])],
187
+ :name, [:name, :email],
188
+ :controller => 'people'
189
+ )
190
+ }
191
+ it {
192
+ should match(
193
+ /people\?q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=name\+asc&q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=email\+desc/
194
+ )
195
+ }
196
+ it {
197
+ should match /sort_link desc/
198
+ }
199
+ it {
200
+ should match /Full Name ▼/
201
+ }
202
+ end
203
+
204
+ describe '#sort_link with multiple search_keys should allow a default_order to be specified' do
205
+ subject { @controller.view_context
206
+ .sort_link(
207
+ [:main_app, Person.search()],
208
+ :name, [:name, :email],
209
+ :controller => 'people',
210
+ :default_order => 'desc'
211
+ )
212
+ }
213
+ it {
214
+ should match(
215
+ /people\?q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=name\+desc&q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=email\+desc/
216
+ )
217
+ }
218
+ it {
219
+ should match /sort_link/
220
+ }
221
+ it {
222
+ should match /Full Name/
223
+ }
224
+ end
225
+
226
+ describe '#sort_link with multiple search_keys should allow multiple default_orders to be specified' do
227
+ subject { @controller.view_context
228
+ .sort_link(
229
+ [:main_app, Person.search()],
230
+ :name, [:name, :email],
231
+ :controller => 'people',
232
+ :default_order => { 'name' => 'desc', :email => 'asc' }
233
+ )
234
+ }
235
+ it {
236
+ should match(
237
+ /people\?q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=name\+desc&q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=email\+asc/
238
+ )
239
+ }
240
+ it {
241
+ should match /sort_link/
242
+ }
243
+ it {
244
+ should match /Full Name/
245
+ }
246
+ end
247
+
248
+ describe '#sort_link with multiple search_keys with multiple default_orders should not override a specified order' do
249
+ subject { @controller.view_context
250
+ .sort_link(
251
+ [:main_app, Person.search()],
252
+ :name, [:name, 'email desc'],
253
+ :controller => 'people',
254
+ :default_order => { 'name' => 'desc', :email => 'asc' }
255
+ )
256
+ }
257
+ it {
258
+ should match(
259
+ /people\?q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=name\+desc&q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=email\+desc/
260
+ )
261
+ }
262
+ it {
263
+ should match /sort_link/
264
+ }
265
+ it {
266
+ should match /Full Name/
267
+ }
268
+ end
108
269
  context 'view has existing parameters' do
109
270
  before do
110
271
  @controller.view_context.params.merge!({ :exist => 'existing' })
@@ -2,12 +2,55 @@ require 'spec_helper'
2
2
 
3
3
  module Ransack
4
4
  module Nodes
5
+
5
6
  describe Grouping do
7
+
6
8
  before do
7
9
  @g = 1
8
10
  end
9
11
 
12
+ let(:context) { Context.for(Person) }
13
+
14
+ subject { described_class.new(context) }
15
+
16
+ describe '#attribute_method?' do
17
+ context 'for attributes of the context' do
18
+ it 'is true' do
19
+ expect(subject.attribute_method?('name')).to be_true
20
+ end
21
+
22
+ context "when the attribute contains '_and_'" do
23
+ it 'is true' do
24
+ expect(subject.attribute_method?('terms_and_conditions')).to be_true
25
+ end
26
+ end
27
+
28
+ context "when the attribute contains '_or_'" do
29
+ it 'is true' do
30
+ expect(subject.attribute_method?('true_or_false')).to be_true
31
+ end
32
+ end
33
+
34
+ context "when the attribute ends with '_start'" do
35
+ it 'is true' do
36
+ expect(subject.attribute_method?('life_start')).to be_true
37
+ end
38
+ end
39
+
40
+ context "when the attribute ends with '_end'" do
41
+ it 'is true' do
42
+ expect(subject.attribute_method?('stop_end')).to be_true
43
+ end
44
+ end
45
+ end
46
+
47
+ context 'for unknown attributes' do
48
+ it 'is false' do
49
+ expect(subject.attribute_method?('not_an_attribute')).to be_false
50
+ end
51
+ end
52
+ end
10
53
 
11
54
  end
12
55
  end
13
- end
56
+ end
@@ -22,8 +22,7 @@ module Ransack
22
22
  describe 'eq' do
23
23
  it 'generates an equality condition for boolean true' do
24
24
  @s.awesome_eq = true
25
- field = "#{quote_table_name("people")}.#{
26
- quote_column_name("awesome")}"
25
+ field = "#{quote_table_name("people")}.#{quote_column_name("awesome")}"
27
26
  expect(@s.result.to_sql).to match /#{field} = #{
28
27
  ActiveRecord::Base.connection.quoted_true}/
29
28
  end
@@ -41,8 +40,91 @@ module Ransack
41
40
  end
42
41
  end
43
42
 
44
- describe 'cont' do
43
+ describe 'lteq' do
44
+ it 'generates a <= condition with an integer column' do
45
+ val = 1000
46
+ @s.salary_lteq = val
47
+ field = "#{quote_table_name("people")}.#{quote_column_name("salary")}"
48
+ expect(@s.result.to_sql).to match /#{field} <= #{val}/
49
+ end
50
+
51
+ it 'generates a <= condition with a string column' do
52
+ val = 'jane@doe.com'
53
+ @s.email_lteq = val
54
+ field = "#{quote_table_name("people")}.#{quote_column_name("email")}"
55
+ expect(@s.result.to_sql).to match /#{field} <= '#{val}'/
56
+ end
57
+
58
+ it 'does not generate a condition for nil' do
59
+ @s.salary_lteq = nil
60
+ expect(@s.result.to_sql).not_to match /WHERE/
61
+ end
62
+ end
63
+
64
+ describe 'lt' do
65
+ it 'generates a < condition with an integer column' do
66
+ val = 2000
67
+ @s.salary_lt = val
68
+ field = "#{quote_table_name("people")}.#{quote_column_name("salary")}"
69
+ expect(@s.result.to_sql).to match /#{field} < #{val}/
70
+ end
71
+
72
+ it 'generates a < condition with a string column' do
73
+ val = 'jane@doe.com'
74
+ @s.email_lt = val
75
+ field = "#{quote_table_name("people")}.#{quote_column_name("email")}"
76
+ expect(@s.result.to_sql).to match /#{field} < '#{val}'/
77
+ end
78
+
79
+ it 'does not generate a condition for nil' do
80
+ @s.salary_lt = nil
81
+ expect(@s.result.to_sql).not_to match /WHERE/
82
+ end
83
+ end
84
+
85
+ describe 'gteq' do
86
+ it 'generates a >= condition with an integer column' do
87
+ val = 300
88
+ @s.salary_gteq = val
89
+ field = "#{quote_table_name("people")}.#{quote_column_name("salary")}"
90
+ expect(@s.result.to_sql).to match /#{field} >= #{val}/
91
+ end
92
+
93
+ it 'generates a >= condition with a string column' do
94
+ val = 'jane@doe.com'
95
+ @s.email_gteq = val
96
+ field = "#{quote_table_name("people")}.#{quote_column_name("email")}"
97
+ expect(@s.result.to_sql).to match /#{field} >= '#{val}'/
98
+ end
99
+
100
+ it 'does not generate a condition for nil' do
101
+ @s.salary_gteq = nil
102
+ expect(@s.result.to_sql).not_to match /WHERE/
103
+ end
104
+ end
105
+
106
+ describe 'gt' do
107
+ it 'generates a > condition with an integer column' do
108
+ val = 400
109
+ @s.salary_gt = val
110
+ field = "#{quote_table_name("people")}.#{quote_column_name("salary")}"
111
+ expect(@s.result.to_sql).to match /#{field} > #{val}/
112
+ end
113
+
114
+ it 'generates a > condition with a string column' do
115
+ val = 'jane@doe.com'
116
+ @s.email_gt = val
117
+ field = "#{quote_table_name("people")}.#{quote_column_name("email")}"
118
+ expect(@s.result.to_sql).to match /#{field} > '#{val}'/
119
+ end
120
+
121
+ it 'does not generate a condition for nil' do
122
+ @s.salary_gt = nil
123
+ expect(@s.result.to_sql).not_to match /WHERE/
124
+ end
125
+ end
45
126
 
127
+ describe 'cont' do
46
128
  it_has_behavior 'wildcard escaping', :name_cont,
47
129
  (if ActiveRecord::Base.connection.adapter_name == "PostgreSQL"
48
130
  /"people"."name" ILIKE '%\\%\\._\\\\%'/
@@ -80,6 +162,86 @@ module Ransack
80
162
  end
81
163
  end
82
164
 
165
+ describe 'start' do
166
+ it 'generates a LIKE query with value followed by %' do
167
+ @s.name_start = 'Er'
168
+ field = "#{quote_table_name("people")}.#{quote_column_name("name")}"
169
+ expect(@s.result.to_sql).to match /#{field} I?LIKE 'Er%'/
170
+ end
171
+
172
+ it "works with attribute names ending with '_start'" do
173
+ @s.new_start_start = 'hEy'
174
+ field = "#{quote_table_name("people")}.#{quote_column_name("new_start")}"
175
+ expect(@s.result.to_sql).to match /#{field} I?LIKE 'hEy%'/
176
+ end
177
+
178
+ it "works with attribute names ending with '_end'" do
179
+ @s.stop_end_start = 'begin'
180
+ field = "#{quote_table_name("people")}.#{quote_column_name("stop_end")}"
181
+ expect(@s.result.to_sql).to match /#{field} I?LIKE 'begin%'/
182
+ end
183
+ end
184
+
185
+ describe 'not_start' do
186
+ it 'generates a NOT LIKE query with value followed by %' do
187
+ @s.name_not_start = 'Eri'
188
+ field = "#{quote_table_name("people")}.#{quote_column_name("name")}"
189
+ expect(@s.result.to_sql).to match /#{field} NOT I?LIKE 'Eri%'/
190
+ end
191
+
192
+ it "works with attribute names ending with '_start'" do
193
+ @s.new_start_not_start = 'hEy'
194
+ field = "#{quote_table_name("people")}.#{quote_column_name("new_start")}"
195
+ expect(@s.result.to_sql).to match /#{field} NOT I?LIKE 'hEy%'/
196
+ end
197
+
198
+ it "works with attribute names ending with '_end'" do
199
+ @s.stop_end_not_start = 'begin'
200
+ field = "#{quote_table_name("people")}.#{quote_column_name("stop_end")}"
201
+ expect(@s.result.to_sql).to match /#{field} NOT I?LIKE 'begin%'/
202
+ end
203
+ end
204
+
205
+ describe 'end' do
206
+ it 'generates a LIKE query with value preceded by %' do
207
+ @s.name_end = 'Miller'
208
+ field = "#{quote_table_name("people")}.#{quote_column_name("name")}"
209
+ expect(@s.result.to_sql).to match /#{field} I?LIKE '%Miller'/
210
+ end
211
+
212
+ it "works with attribute names ending with '_start'" do
213
+ @s.new_start_end = 'finish'
214
+ field = "#{quote_table_name("people")}.#{quote_column_name("new_start")}"
215
+ expect(@s.result.to_sql).to match /#{field} I?LIKE '%finish'/
216
+ end
217
+
218
+ it "works with attribute names ending with '_end'" do
219
+ @s.stop_end_end = 'Ending'
220
+ field = "#{quote_table_name("people")}.#{quote_column_name("stop_end")}"
221
+ expect(@s.result.to_sql).to match /#{field} I?LIKE '%Ending'/
222
+ end
223
+ end
224
+
225
+ describe 'not_end' do
226
+ it 'generates a NOT LIKE query with value preceded by %' do
227
+ @s.name_not_end = 'Miller'
228
+ field = "#{quote_table_name("people")}.#{quote_column_name("name")}"
229
+ expect(@s.result.to_sql).to match /#{field} NOT I?LIKE '%Miller'/
230
+ end
231
+
232
+ it "works with attribute names ending with '_start'" do
233
+ @s.new_start_not_end = 'finish'
234
+ field = "#{quote_table_name("people")}.#{quote_column_name("new_start")}"
235
+ expect(@s.result.to_sql).to match /#{field} NOT I?LIKE '%finish'/
236
+ end
237
+
238
+ it "works with attribute names ending with '_end'" do
239
+ @s.stop_end_not_end = 'Ending'
240
+ field = "#{quote_table_name("people")}.#{quote_column_name("stop_end")}"
241
+ expect(@s.result.to_sql).to match /#{field} NOT I?LIKE '%Ending'/
242
+ end
243
+ end
244
+
83
245
  describe 'true' do
84
246
  it 'generates an equality condition for boolean true' do
85
247
  @s.awesome_true = true
@@ -6,7 +6,10 @@ module Ransack
6
6
  describe '.attribute' do
7
7
  it 'translate namespaced attribute like AR does' do
8
8
  ar_translation = ::Namespace::Article.human_attribute_name(:title)
9
- ransack_translation = Ransack::Translate.attribute(:title, :context => ::Namespace::Article.search.context)
9
+ ransack_translation = Ransack::Translate.attribute(
10
+ :title,
11
+ :context => ::Namespace::Article.search.context
12
+ )
10
13
  expect(ransack_translation).to eq ar_translation
11
14
  end
12
15
  end
@@ -5,6 +5,11 @@ en:
5
5
  attributes:
6
6
  person:
7
7
  name: Full Name
8
+ only_admin: admin uSer Only
9
+ salary: wages
10
+ awesome: ransack is really awesome
11
+ article:
12
+ body: maiN BoDy
8
13
  activerecord:
9
14
  attributes:
10
15
  namespace/article: