@@ -133,5 +133,187 @@ module ForestLiana
133133 end
134134 end
135135 end
136+
137+ describe 'aggregation methods behavior' do
138+ let ( :scopes ) { { 'scopes' => { } , 'team' => { 'id' => '1' , 'name' => 'Operations' } } }
139+ let ( :model ) { Tree }
140+ let ( :collection ) { 'trees' }
141+ let ( :groupByFieldName ) { 'age' }
142+
143+ describe 'aggregation_sql method' do
144+ subject { PieStatGetter . new ( model , params , user ) }
145+
146+ context 'with COUNT aggregator' do
147+ let ( :params ) {
148+ {
149+ type : 'Pie' ,
150+ sourceCollectionName : collection ,
151+ timezone : 'Europe/Paris' ,
152+ aggregator : 'Count' ,
153+ groupByFieldName : groupByFieldName
154+ }
155+ }
156+
157+ it 'should generate correct COUNT SQL' do
158+ sql = subject . send ( :aggregation_sql , 'count' , nil )
159+ expect ( sql ) . to eq 'COUNT(DISTINCT trees.id)'
160+ end
161+
162+ it 'should generate correct COUNT SQL with specific field' do
163+ sql = subject . send ( :aggregation_sql , 'count' , 'age' )
164+ expect ( sql ) . to eq 'COUNT(DISTINCT trees.age)'
165+ end
166+ end
167+
168+ context 'with SUM aggregator' do
169+ let ( :params ) {
170+ {
171+ type : 'Pie' ,
172+ sourceCollectionName : collection ,
173+ timezone : 'Europe/Paris' ,
174+ aggregator : 'Sum' ,
175+ aggregateFieldName : 'age' ,
176+ groupByFieldName : groupByFieldName
177+ }
178+ }
179+
180+ it 'should generate correct SUM SQL' do
181+ sql = subject . send ( :aggregation_sql , 'sum' , 'age' )
182+ expect ( sql ) . to eq 'SUM(trees.age)'
183+ end
184+ end
185+
186+ context 'with association field' do
187+ let ( :params ) {
188+ {
189+ type : 'Pie' ,
190+ sourceCollectionName : collection ,
191+ timezone : 'Europe/Paris' ,
192+ aggregator : 'Count' ,
193+ groupByFieldName : 'owner:name'
194+ }
195+ }
196+
197+ it 'should handle association fields correctly' do
198+ # Assuming Tree belongs_to :owner
199+ allow ( model ) . to receive ( :reflect_on_association ) . with ( :owner ) . and_return (
200+ double ( table_name : 'owners' )
201+ )
202+
203+ sql = subject . send ( :aggregation_sql , 'count' , 'owner:id' )
204+ expect ( sql ) . to eq 'COUNT(DISTINCT owners.id)'
205+ end
206+ end
207+
208+ context 'with unsupported aggregator' do
209+ let ( :params ) {
210+ {
211+ type : 'Pie' ,
212+ sourceCollectionName : collection ,
213+ timezone : 'Europe/Paris' ,
214+ aggregator : 'Invalid' ,
215+ groupByFieldName : groupByFieldName
216+ }
217+ }
218+
219+ it 'should raise an error for unsupported aggregator' do
220+ expect {
221+ subject . send ( :aggregation_sql , 'invalid' , 'age' )
222+ } . to raise_error ( ForestLiana ::Errors ::HTTP422Error )
223+ end
224+ end
225+ end
226+
227+ describe 'aggregation_alias method' do
228+ subject { PieStatGetter . new ( model , params , user ) }
229+
230+ context 'with COUNT aggregator' do
231+ let ( :params ) {
232+ {
233+ type : 'Pie' ,
234+ sourceCollectionName : collection ,
235+ timezone : 'Europe/Paris' ,
236+ aggregator : 'Count' ,
237+ groupByFieldName : groupByFieldName
238+ }
239+ }
240+
241+ it 'should return correct alias for count' do
242+ alias_name = subject . send ( :aggregation_alias , 'count' , nil )
243+ expect ( alias_name ) . to eq 'count_id'
244+ end
245+ end
246+
247+ context 'with SUM aggregator' do
248+ let ( :params ) {
249+ {
250+ type : 'Pie' ,
251+ sourceCollectionName : collection ,
252+ timezone : 'Europe/Paris' ,
253+ aggregator : 'Sum' ,
254+ aggregateFieldName : 'age' ,
255+ groupByFieldName : groupByFieldName
256+ }
257+ }
258+
259+ it 'should return correct alias for sum' do
260+ alias_name = subject . send ( :aggregation_alias , 'sum' , 'age' )
261+ expect ( alias_name ) . to eq 'sum_age'
262+ end
263+
264+ it 'should handle field names with mixed case' do
265+ alias_name = subject . send ( :aggregation_alias , 'sum' , 'TreeAge' )
266+ expect ( alias_name ) . to eq 'sum_treeage'
267+ end
268+ end
269+ end
270+
271+ describe 'results ordering' do
272+ subject { PieStatGetter . new ( model , params , user ) }
273+
274+ context 'with COUNT aggregator' do
275+ let ( :params ) {
276+ {
277+ type : 'Pie' ,
278+ sourceCollectionName : collection ,
279+ timezone : 'Europe/Paris' ,
280+ aggregator : 'Count' ,
281+ groupByFieldName : groupByFieldName
282+ }
283+ }
284+
285+ it 'should return results ordered by count descending' do
286+ subject . perform
287+
288+ expect ( subject . record . value ) . to eq [
289+ { :key => 3 , :value => 5 } ,
290+ { :key => 15 , :value => 4 }
291+ ]
292+ end
293+ end
294+
295+ context 'with SUM aggregator' do
296+ let ( :params ) {
297+ {
298+ type : 'Pie' ,
299+ sourceCollectionName : collection ,
300+ timezone : 'Europe/Paris' ,
301+ aggregator : 'Sum' ,
302+ aggregateFieldName : 'age' ,
303+ groupByFieldName : groupByFieldName
304+ }
305+ }
306+
307+ it 'should return results ordered by sum descending' do
308+ subject . perform
309+
310+ expect ( subject . record . value ) . to eq [
311+ { :key => 15 , :value => 60 } ,
312+ { :key => 3 , :value => 15 }
313+ ]
314+ end
315+ end
316+ end
317+ end
136318 end
137319end
0 commit comments