ransack 1.4.1 → 1.5.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.
@@ -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: