bharat_filter_engine 0.1.2 → 0.2.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.
@@ -1,51 +1,51 @@
1
- require "spec_helper"
1
+ # frozen_string_literal: true
2
2
 
3
- RSpec.describe BharatFilterEngine::DynamicFilterValues do
3
+ require 'spec_helper'
4
4
 
5
+ RSpec.describe BharatFilterEngine::DynamicFilterValues do
5
6
  let!(:client_one) do
6
7
  Client.create!(
7
- name: "John"
8
+ name: 'John'
8
9
  )
9
10
  end
10
11
 
11
12
  let!(:client_two) do
12
13
  Client.create!(
13
- name: "Jane"
14
+ name: 'Jane'
14
15
  )
15
16
  end
16
17
 
17
18
  let!(:lead_one) do
18
19
  Lead.create!(
19
- source: "google",
20
+ source: 'google',
20
21
  client: client_one
21
22
  )
22
23
  end
23
24
 
24
25
  let!(:lead_two) do
25
26
  Lead.create!(
26
- source: "referral",
27
+ source: 'referral',
27
28
  client: client_two
28
29
  )
29
30
  end
30
31
 
31
32
  before do
32
33
  Sale.create!(
33
- stage: "qualified",
34
+ stage: 'qualified',
34
35
  lead: lead_one
35
36
  )
36
37
 
37
38
  Sale.create!(
38
- stage: "new",
39
+ stage: 'new',
39
40
  lead: lead_two
40
41
  )
41
42
  end
42
43
 
43
- it "returns direct values" do
44
-
44
+ it 'returns direct values' do
45
45
  result =
46
46
  described_class.new(
47
47
  scope: Sale.all,
48
- field: "stage"
48
+ field: 'stage'
49
49
  ).call
50
50
 
51
51
  expect(result).to eq(
@@ -53,12 +53,11 @@ RSpec.describe BharatFilterEngine::DynamicFilterValues do
53
53
  )
54
54
  end
55
55
 
56
- it "returns nested values" do
57
-
56
+ it 'returns nested values' do
58
57
  result =
59
58
  described_class.new(
60
59
  scope: Sale.all,
61
- field: "lead__source"
60
+ field: 'lead__source'
62
61
  ).call
63
62
 
64
63
  expect(result).to eq(
@@ -66,12 +65,11 @@ RSpec.describe BharatFilterEngine::DynamicFilterValues do
66
65
  )
67
66
  end
68
67
 
69
- it "returns multi-level nested values" do
70
-
68
+ it 'returns multi-level nested values' do
71
69
  result =
72
70
  described_class.new(
73
71
  scope: Sale.all,
74
- field: "lead__client__name"
72
+ field: 'lead__client__name'
75
73
  ).call
76
74
 
77
75
  expect(result).to eq(
@@ -79,47 +77,54 @@ RSpec.describe BharatFilterEngine::DynamicFilterValues do
79
77
  )
80
78
  end
81
79
 
82
- it "returns nil for invalid field" do
83
-
80
+ it 'returns nil for invalid field' do
84
81
  result =
85
82
  described_class.new(
86
83
  scope: Sale.all,
87
- field: "invalid_field"
84
+ field: 'invalid_field'
88
85
  ).call
89
86
 
90
87
  expect(result).to be_nil
91
88
  end
92
89
 
93
- it "returns nil for a valid association with an invalid column" do
94
-
90
+ it 'returns nil for a valid association with an invalid column' do
95
91
  result =
96
92
  described_class.new(
97
93
  scope: Sale.all,
98
- field: "lead__something_wrong"
94
+ field: 'lead__something_wrong'
99
95
  ).call
100
96
 
101
97
  expect(result).to be_nil
102
98
  end
103
99
 
104
- it "returns nil for an invalid association" do
100
+ it 'returns nil for an invalid association' do
101
+ result =
102
+ described_class.new(
103
+ scope: Sale.all,
104
+ field: 'something__name'
105
+ ).call
106
+
107
+ expect(result).to be_nil
108
+ end
105
109
 
110
+ it 'returns nil for an invalid association at a deeper level' do
106
111
  result =
107
112
  described_class.new(
108
113
  scope: Sale.all,
109
- field: "something__name"
114
+ field: 'lead__something__name'
110
115
  ).call
111
116
 
112
117
  expect(result).to be_nil
113
118
  end
114
119
 
115
- it "does not return blank values" do
116
- Sale.create!(stage: "")
120
+ it 'does not return blank values' do
121
+ Sale.create!(stage: '')
117
122
  Sale.create!(stage: nil)
118
123
 
119
124
  result =
120
125
  described_class.new(
121
126
  scope: Sale.all,
122
- field: "stage"
127
+ field: 'stage'
123
128
  ).call
124
129
 
125
130
  expect(result).to eq(
@@ -127,4 +132,131 @@ RSpec.describe BharatFilterEngine::DynamicFilterValues do
127
132
  )
128
133
  end
129
134
 
130
- end
135
+ it 'returns distinct values for an integer column' do
136
+ Sale.create!(project_id: 3)
137
+ Sale.create!(project_id: 1)
138
+ Sale.create!(project_id: 3)
139
+ Sale.create!(project_id: nil)
140
+
141
+ result = described_class.new(scope: Sale.all, field: 'project_id').call
142
+ expect(result).to eq([1, 3])
143
+ end
144
+
145
+ it 'keeps a zero value for a numeric column' do
146
+ Sale.create!(amount: 0)
147
+ Sale.create!(amount: 5)
148
+
149
+ result = described_class.new(scope: Sale.all, field: 'amount').call
150
+ expect(result).to eq([0, 5])
151
+ end
152
+
153
+ it 'returns distinct values for a datetime column' do
154
+ Sale.create!(actual_sale_date: Time.utc(2013, 1, 1))
155
+ Sale.create!(actual_sale_date: nil)
156
+
157
+ result = described_class.new(scope: Sale.all, field: 'actual_sale_date').call
158
+ expect(result.size).to eq(1)
159
+ end
160
+
161
+ it 'returns distinct values for a nested integer column' do
162
+ client = Client.create!(name: 'Nested Co')
163
+ lead = Lead.create!(source: 'web', client: client)
164
+ Sale.create!(lead: lead)
165
+ Sale.create!(lead: lead)
166
+ Sale.create!(lead: nil)
167
+
168
+ result = described_class.new(scope: Sale.all, field: 'lead__client_id').call
169
+ expected = Sale.joins(:lead).distinct.pluck('leads.client_id').compact.sort
170
+
171
+ expect(result).to include(client.id)
172
+ expect(result).to eq(expected)
173
+ end
174
+
175
+ it 'filters values by a partial term' do
176
+ Sale.create!(stage: 'closed')
177
+
178
+ result =
179
+ described_class.new(
180
+ scope: Sale.all,
181
+ field: 'stage',
182
+ term: 'qual'
183
+ ).call
184
+
185
+ expect(result).to eq(['qualified'])
186
+ end
187
+
188
+ it 'is case-insensitive when filtering by term' do
189
+ result =
190
+ described_class.new(
191
+ scope: Sale.all,
192
+ field: 'stage',
193
+ term: 'QUAL'
194
+ ).call
195
+
196
+ expect(result).to eq(['qualified'])
197
+ end
198
+
199
+ it 'escapes LIKE wildcards in the term' do
200
+ Sale.create!(stage: 'sale_2026')
201
+ Sale.create!(stage: 'saleX2026')
202
+
203
+ result =
204
+ described_class.new(
205
+ scope: Sale.all,
206
+ field: 'stage',
207
+ term: 'sale_2026'
208
+ ).call
209
+
210
+ expect(result).to eq(['sale_2026'])
211
+ end
212
+
213
+ it 'limits the number of returned values' do
214
+ Sale.create!(stage: 'closed')
215
+
216
+ result =
217
+ described_class.new(
218
+ scope: Sale.all,
219
+ field: 'stage',
220
+ limit: 2
221
+ ).call
222
+
223
+ expect(result).to eq(%w[closed new])
224
+ end
225
+
226
+ it 'ignores a limit of zero' do
227
+ result =
228
+ described_class.new(
229
+ scope: Sale.all,
230
+ field: 'stage',
231
+ limit: 0
232
+ ).call
233
+
234
+ expect(result).to eq(%w[new qualified])
235
+ end
236
+
237
+ it 'combines term and limit together' do
238
+ Sale.create!(stage: 'quarantined')
239
+ Sale.create!(stage: 'qualified_lead')
240
+
241
+ result =
242
+ described_class.new(
243
+ scope: Sale.all,
244
+ field: 'stage',
245
+ term: 'qua',
246
+ limit: 1
247
+ ).call
248
+
249
+ expect(result).to eq(['qualified'])
250
+ end
251
+
252
+ it 'works with a nested field and a term together' do
253
+ result =
254
+ described_class.new(
255
+ scope: Sale.all,
256
+ field: 'lead__client__name',
257
+ term: 'Jo'
258
+ ).call
259
+
260
+ expect(result).to eq(['John'])
261
+ end
262
+ end