forest_liana 8.0.16 → 8.0.17

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d66f322c9f51d6beebaa2eb338b8f568f7d12bc781d71c4b47a8c2c3e6503c73
4
- data.tar.gz: 37db17c392bac96b35c43595c03ef702e840ae40e420538151d36edc2a347c68
3
+ metadata.gz: ac43c231df7ce45742201f1824fc1733cf94dd2ccfc1f8ffaa214273f6f2f9c3
4
+ data.tar.gz: 5208918a6d4dde8b08e54077060f3a822c7b8126ec15838b7dd47bb0ebcb3464
5
5
  SHA512:
6
- metadata.gz: 9466f6b82dc0ffbfae007bfc0024e5b831172dacdffcf00e51c58a8ca2333dbbefb165227a3d36b704954b1cdb75ecdfb9a5f2605840572220e612226e6cb39d
7
- data.tar.gz: 5c313811aead7c0617d1e5d5d9c424f66e56b0482a46dc8354a1714b59f61490a728cc1cacb9224553110b0577b68712ba62366e8b214d6c7bddb2daffde4c7d
6
+ metadata.gz: 33843161d1f741d9a1786c19d21607f1c2e2bcd6c64994fafefd979c8f4268d1d6ea24261d59b89ed98f3ac14563472991a1a9bb631c612a8a87ab58b744d18a
7
+ data.tar.gz: f50308426ddf53f9e1599c94ed71f1d2458d281b094335e361f6570aad2657406a3c44bbb117084503304b35f8a70f3e197f491b2c4596757c831b0849cf340b
@@ -6,9 +6,17 @@ module ForestLiana
6
6
  @resource = resource
7
7
  @params = params
8
8
  @user = forest_user
9
+
10
+ validate_params
9
11
  compute_includes
10
12
  end
11
13
 
14
+ def validate_params
15
+ if @params.key?(:aggregator) && !%w[count sum avg max min].include?(@params[:aggregator].downcase)
16
+ raise ForestLiana::Errors::HTTP422Error.new('Invalid aggregate function')
17
+ end
18
+ end
19
+
12
20
  def get_resource
13
21
  super
14
22
  @resource.reorder('')
@@ -19,24 +19,25 @@ module ForestLiana
19
19
  end
20
20
 
21
21
  @record = Model::Stat.new(value: {
22
- countCurrent: count(resource),
23
- countPrevious: previous_value ? count(previous_value) : nil
22
+ countCurrent: aggregate(resource),
23
+ countPrevious: previous_value ? aggregate(previous_value) : nil
24
24
  })
25
25
  end
26
26
 
27
27
  private
28
28
 
29
- def count(value)
30
- uniq = @params[:aggregator].downcase == 'count'
29
+ def aggregate(value)
30
+ aggregator = @params[:aggregator].downcase
31
+ uniq = aggregator == 'count'
31
32
 
32
33
  if Rails::VERSION::MAJOR >= 4
33
34
  if uniq
34
35
  # NOTICE: uniq is deprecated since Rails 5.0
35
36
  value = Rails::VERSION::MAJOR >= 5 ? value.distinct : value.uniq
36
37
  end
37
- value.send(@params[:aggregator].downcase, aggregate_field)
38
+ value.send(aggregator, aggregate_field)
38
39
  else
39
- value.send(@params[:aggregator].downcase, aggregate_field, distinct: uniq)
40
+ value.send(aggregator, aggregate_field, distinct: uniq)
40
41
  end
41
42
  end
42
43
 
@@ -1,3 +1,3 @@
1
1
  module ForestLiana
2
- VERSION = "8.0.16"
2
+ VERSION = "8.0.17"
3
3
  end
@@ -9,6 +9,19 @@ module ForestLiana
9
9
  allow(ForestLiana::ScopeManager).to receive(:fetch_scopes).and_return(scopes)
10
10
  end
11
11
 
12
+ describe 'with not allowed aggregator' do
13
+ it 'should raise an error' do
14
+ expect {
15
+ LineStatGetter.new(Owner, {
16
+ timezone: "Europe/Paris",
17
+ aggregator: "eval",
18
+ timeRange: "Week",
19
+ groupByFieldName: "`ls`",
20
+ }, user)
21
+ }.to raise_error(ForestLiana::Errors::HTTP422Error, 'Invalid aggregate function')
22
+ end
23
+ end
24
+
12
25
  describe 'Check client_timezone function' do
13
26
  describe 'with a SQLite database' do
14
27
  it 'should return false' do
@@ -23,90 +23,113 @@ module ForestLiana
23
23
  }
24
24
  end
25
25
 
26
- let(:model) { Tree }
27
- let(:collection) { 'trees' }
28
- let(:params) {
29
- {
30
- type: 'Pie',
31
- sourceCollectionName: collection,
32
- timezone: 'Europe/Paris',
33
- aggregator: 'Count',
34
- groupByFieldName: groupByFieldName
26
+ describe 'with not allowed aggregator' do
27
+ let(:scopes) { { } }
28
+ let(:model) { Tree }
29
+ let(:collection) { 'trees' }
30
+ let(:params) {
31
+ {
32
+ type: 'Pie',
33
+ sourceCollectionName: collection,
34
+ timezone: 'Europe/Paris',
35
+ aggregator: 'eval',
36
+ groupByFieldName: '`ls`'
37
+ }
35
38
  }
36
- }
37
39
 
38
- subject { PieStatGetter.new(model, params, user) }
40
+ it 'should raise an error' do
41
+ expect {
42
+ PieStatGetter.new(model, params, user)
43
+ }.to raise_error(ForestLiana::Errors::HTTP422Error, 'Invalid aggregate function')
44
+ end
45
+ end
39
46
 
40
- describe 'with empty scopes' do
41
- let(:scopes) { { } }
47
+ describe 'with valid aggregate function' do
48
+ let(:model) { Tree }
49
+ let(:collection) { 'trees' }
50
+ let(:params) {
51
+ {
52
+ type: 'Pie',
53
+ sourceCollectionName: collection,
54
+ timezone: 'Europe/Paris',
55
+ aggregator: 'Count',
56
+ groupByFieldName: groupByFieldName
57
+ }
58
+ }
42
59
 
43
- describe 'with an aggregate on the name field' do
44
- let(:groupByFieldName) { 'name' }
45
-
46
- it 'should be as many categories as records count' do
47
- subject.perform
48
- expect(subject.record.value).to match_array([
49
- {:key => "Old Tree n1", :value => 1},
50
- {:key => "Old Tree n2", :value => 1},
51
- {:key => "Old Tree n3", :value => 1},
52
- {:key => "Old Tree n4", :value => 1},
53
- {:key => "Young Tree n1", :value => 1},
54
- {:key => "Young Tree n2", :value => 1},
55
- {:key => "Young Tree n3", :value => 1},
56
- {:key => "Young Tree n4", :value => 1},
57
- {:key => "Young Tree n5", :value => 1}
58
- ])
60
+ subject { PieStatGetter.new(model, params, user) }
61
+
62
+ describe 'with empty scopes' do
63
+ let(:scopes) { { } }
64
+
65
+ describe 'with an aggregate on the name field' do
66
+ let(:groupByFieldName) { 'name' }
67
+
68
+ it 'should be as many categories as records count' do
69
+ subject.perform
70
+ expect(subject.record.value).to match_array([
71
+ {:key => "Old Tree n1", :value => 1},
72
+ {:key => "Old Tree n2", :value => 1},
73
+ {:key => "Old Tree n3", :value => 1},
74
+ {:key => "Old Tree n4", :value => 1},
75
+ {:key => "Young Tree n1", :value => 1},
76
+ {:key => "Young Tree n2", :value => 1},
77
+ {:key => "Young Tree n3", :value => 1},
78
+ {:key => "Young Tree n4", :value => 1},
79
+ {:key => "Young Tree n5", :value => 1}
80
+ ])
81
+ end
59
82
  end
60
- end
61
83
 
62
- describe 'with an aggregate on the age field' do
63
- let(:groupByFieldName) { 'age' }
84
+ describe 'with an aggregate on the age field' do
85
+ let(:groupByFieldName) { 'age' }
64
86
 
65
- it 'should be as many categories as different ages among records' do
66
- subject.perform
67
- expect(subject.record.value).to eq [{ :key => 3, :value => 5}, { :key => 15, :value => 4 }]
87
+ it 'should be as many categories as different ages among records' do
88
+ subject.perform
89
+ expect(subject.record.value).to eq [{ :key => 3, :value => 5}, { :key => 15, :value => 4 }]
90
+ end
68
91
  end
69
92
  end
70
- end
71
93
 
72
- describe 'with scopes' do
73
- let(:scopes) {
74
- {
75
- 'Tree' => {
76
- 'scope'=> {
77
- 'filter'=> {
78
- 'aggregator' => 'and',
79
- 'conditions' => [
80
- { 'field' => 'age', 'operator' => 'less_than', 'value' => 10 }
81
- ]
82
- },
83
- 'dynamicScopesValues' => { }
94
+ describe 'with scopes' do
95
+ let(:scopes) {
96
+ {
97
+ 'Tree' => {
98
+ 'scope'=> {
99
+ 'filter'=> {
100
+ 'aggregator' => 'and',
101
+ 'conditions' => [
102
+ { 'field' => 'age', 'operator' => 'less_than', 'value' => 10 }
103
+ ]
104
+ },
105
+ 'dynamicScopesValues' => { }
106
+ }
84
107
  }
85
108
  }
86
109
  }
87
- }
88
110
 
89
- describe 'with an aggregate on the name field' do
90
- let(:groupByFieldName) { 'name' }
91
-
92
- it 'should be as many categories as records inside the scope' do
93
- subject.perform
94
- expect(subject.record.value).to match_array([
95
- {:key => "Young Tree n1", :value => 1},
96
- {:key => "Young Tree n2", :value => 1},
97
- {:key => "Young Tree n3", :value => 1},
98
- {:key => "Young Tree n4", :value => 1},
99
- {:key => "Young Tree n5", :value => 1}
100
- ])
111
+ describe 'with an aggregate on the name field' do
112
+ let(:groupByFieldName) { 'name' }
113
+
114
+ it 'should be as many categories as records inside the scope' do
115
+ subject.perform
116
+ expect(subject.record.value).to match_array([
117
+ {:key => "Young Tree n1", :value => 1},
118
+ {:key => "Young Tree n2", :value => 1},
119
+ {:key => "Young Tree n3", :value => 1},
120
+ {:key => "Young Tree n4", :value => 1},
121
+ {:key => "Young Tree n5", :value => 1}
122
+ ])
123
+ end
101
124
  end
102
- end
103
125
 
104
- describe 'with an aggregate on the age field' do
105
- let(:groupByFieldName) { 'age' }
126
+ describe 'with an aggregate on the age field' do
127
+ let(:groupByFieldName) { 'age' }
106
128
 
107
- it 'should be only one category' do
108
- subject.perform
109
- expect(subject.record.value).to eq [{ :key => 3, :value => 5}]
129
+ it 'should be only one category' do
130
+ subject.perform
131
+ expect(subject.record.value).to eq [{ :key => 3, :value => 5}]
132
+ end
110
133
  end
111
134
  end
112
135
  end
@@ -15,80 +15,103 @@ module ForestLiana
15
15
  Tree.create!(name: 'Tree n3', age: 4, island: island, owner: king, cutter: villager)
16
16
  end
17
17
 
18
- let(:params) {
19
- {
20
- type: "Value",
21
- sourceCollectionName: sourceCollectionName,
22
- timezone: "Europe/Paris",
23
- aggregator: "Count",
24
- filter: filter
18
+ describe 'with not allowed aggregator' do
19
+ let(:model) { User }
20
+ let(:collection) { 'users' }
21
+ let(:scopes) { { } }
22
+ let(:params) {
23
+ {
24
+ type: "Value",
25
+ sourceCollectionName: collection,
26
+ timezone: "Europe/Paris",
27
+ aggregator: "eval",
28
+ aggregateFieldName: "`ls`"
29
+ }
25
30
  }
26
- }
27
31
 
28
- subject { ValueStatGetter.new(model, params, user) }
32
+ it 'should raise an error' do
33
+ expect {
34
+ ValueStatGetter.new(model, params, user)
35
+ }.to raise_error(ForestLiana::Errors::HTTP422Error, 'Invalid aggregate function')
36
+ end
37
+ end
29
38
 
30
- describe 'with empty scopes' do
31
- let(:scopes) { { } }
39
+ describe 'with valid aggregate function' do
40
+ let(:params) {
41
+ {
42
+ type: "Value",
43
+ sourceCollectionName: sourceCollectionName,
44
+ timezone: "Europe/Paris",
45
+ aggregator: "Count",
46
+ filter: filter
47
+ }
48
+ }
49
+
50
+ subject { ValueStatGetter.new(model, params, user) }
32
51
 
33
- describe 'with a simple filter matching no entries' do
34
- let(:model) { User }
35
- let(:sourceCollectionName) { 'users' }
36
- let(:filter) { { field: 'name', operator: 'in', value: ['Merry', 'Pippin'] }.to_json }
52
+ describe 'with empty scopes' do
53
+ let(:scopes) { { } }
37
54
 
38
- it 'should have a countCurrent of 0' do
39
- subject.perform
40
- expect(subject.record.value[:countCurrent]).to eq 0
55
+ describe 'with a simple filter matching no entries' do
56
+ let(:model) { User }
57
+ let(:sourceCollectionName) { 'users' }
58
+ let(:filter) { { field: 'name', operator: 'in', value: ['Merry', 'Pippin'] }.to_json }
59
+
60
+ it 'should have a countCurrent of 0' do
61
+ subject.perform
62
+ expect(subject.record.value[:countCurrent]).to eq 0
63
+ end
41
64
  end
42
- end
43
65
 
44
- describe 'with a filter on a belongs_to string field' do
45
- let(:model) { Tree }
46
- let(:sourceCollectionName) { 'trees' }
47
- let(:filter) { { field: 'owner:name', operator: 'equal', value: 'Aragorn' }.to_json }
66
+ describe 'with a filter on a belongs_to string field' do
67
+ let(:model) { Tree }
68
+ let(:sourceCollectionName) { 'trees' }
69
+ let(:filter) { { field: 'owner:name', operator: 'equal', value: 'Aragorn' }.to_json }
48
70
 
49
- it 'should have a countCurrent of 2' do
50
- subject.perform
51
- expect(subject.record.value[:countCurrent]).to eq 2
71
+ it 'should have a countCurrent of 2' do
72
+ subject.perform
73
+ expect(subject.record.value[:countCurrent]).to eq 2
74
+ end
52
75
  end
53
- end
54
76
 
55
- describe 'with a filter on a belongs_to enum field' do
56
- let(:model) { Tree }
57
- let(:sourceCollectionName) { 'trees' }
58
- let(:filter) { { field: 'owner:title', operator: 'equal', value: 'villager' }.to_json }
77
+ describe 'with a filter on a belongs_to enum field' do
78
+ let(:model) { Tree }
79
+ let(:sourceCollectionName) { 'trees' }
80
+ let(:filter) { { field: 'owner:title', operator: 'equal', value: 'villager' }.to_json }
59
81
 
60
- it 'should have a countCurrent of 1' do
61
- subject.perform
62
- expect(subject.record.value[:countCurrent]).to eq 1
82
+ it 'should have a countCurrent of 1' do
83
+ subject.perform
84
+ expect(subject.record.value[:countCurrent]).to eq 1
85
+ end
63
86
  end
64
87
  end
65
- end
66
88
 
67
- describe 'with scopes' do
68
- let(:scopes) {
69
- {
70
- 'User' => {
71
- 'scope'=> {
72
- 'filter'=> {
73
- 'aggregator' => 'and',
74
- 'conditions' => [
75
- { 'field' => 'title', 'operator' => 'not_equal', 'value' => 'villager' }
76
- ]
77
- },
78
- 'dynamicScopesValues' => { }
89
+ describe 'with scopes' do
90
+ let(:scopes) {
91
+ {
92
+ 'User' => {
93
+ 'scope'=> {
94
+ 'filter'=> {
95
+ 'aggregator' => 'and',
96
+ 'conditions' => [
97
+ { 'field' => 'title', 'operator' => 'not_equal', 'value' => 'villager' }
98
+ ]
99
+ },
100
+ 'dynamicScopesValues' => { }
101
+ }
79
102
  }
80
103
  }
81
104
  }
82
- }
83
105
 
84
- describe 'with a filter on a belongs_to enum field' do
85
- let(:model) { User }
86
- let(:sourceCollectionName) { 'users' }
87
- let(:filter) { { field: 'title', operator: 'equal', value: 'villager' }.to_json }
106
+ describe 'with a filter on a belongs_to enum field' do
107
+ let(:model) { User }
108
+ let(:sourceCollectionName) { 'users' }
109
+ let(:filter) { { field: 'title', operator: 'equal', value: 'villager' }.to_json }
88
110
 
89
- it 'should have a countCurrent of 0' do
90
- subject.perform
91
- expect(subject.record.value[:countCurrent]).to eq 0
111
+ it 'should have a countCurrent of 0' do
112
+ subject.perform
113
+ expect(subject.record.value[:countCurrent]).to eq 0
114
+ end
92
115
  end
93
116
  end
94
117
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: forest_liana
3
3
  version: !ruby/object:Gem::Version
4
- version: 8.0.16
4
+ version: 8.0.17
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sandro Munda
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-11-16 00:00:00.000000000 Z
11
+ date: 2023-12-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails