forest_liana 7.8.0 → 7.8.2

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: 82f94463ae1662d3d4eeac62d1b68b5c3a6895adfce97c87e99eb7312d8b0966
4
- data.tar.gz: fa9f1794cde3218d3c7aa27231549493203a49876957c170fb26ee7c1b4baf73
3
+ metadata.gz: c535f5719b2f62c0ff1e2bde402a0c57b099f4120b5c6b3232d8ea0343c84eaf
4
+ data.tar.gz: b609b22af960f63d0b03e8a99597cf6d202da15414826d6dca1b836b7a672676
5
5
  SHA512:
6
- metadata.gz: 9f30218cb8f5df0e921c754fa1d0b08f79194da46ebe7dac74bffb5343fdf8dd0797ef2542bd41d4bd240aff04821ac0bdd6bdf307375ef3c9a8d978ef07d6f9
7
- data.tar.gz: 7192187737dfb2a67f724bb5c444072f707b3ed02f8c69dc216f4504e2e249ffebe683dff9719f405dca9960f4a44b196e1bb1ccbe021cd62bec4cc36b687621
6
+ metadata.gz: 502270b809bf91474ce0bd977a767ee93325c70cfb7aa2ccc0b807ec54fb70a2c447e58eac44a9beca1b9bde7720e214c855f794834c9ec46eb871c60b259a7a
7
+ data.tar.gz: 581fe22c160e4f10a2ed8a866261b2362a31ffb03b5817433794d19f4c1a3a55878a9350e81b95088aeaf4f2b8d6c58a69ad4c1179b8252f6070afb077d52f85
@@ -6,7 +6,15 @@ module ForestLiana
6
6
  @resource = resource
7
7
  @params = params
8
8
  @user = forest_user
9
- compute_includes()
9
+
10
+ validate_params
11
+ compute_includes
12
+ end
13
+
14
+ def validate_params
15
+ if @params.key?(:aggregate) && !%w[count sum avg max min].include?(@params[:aggregate].downcase)
16
+ raise ForestLiana::Errors::HTTP422Error.new('Invalid aggregate function')
17
+ end
10
18
  end
11
19
 
12
20
  def get_resource
@@ -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[:aggregate].downcase == 'count'
29
+ def aggregate(value)
30
+ aggregator = @params[:aggregate].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[:aggregate].downcase, aggregate_field)
38
+ value.send(aggregator, aggregate_field)
38
39
  else
39
- value.send(@params[:aggregate].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 = "7.8.0"
2
+ VERSION = "7.8.2"
3
3
  end
@@ -10,6 +10,19 @@ module ForestLiana
10
10
  Owner.delete_all
11
11
  end
12
12
 
13
+ describe 'with not allowed aggregator' do
14
+ it 'should raise an error' do
15
+ expect {
16
+ LineStatGetter.new(Owner, {
17
+ timezone: "Europe/Paris",
18
+ aggregate: "eval",
19
+ time_range: "Week",
20
+ group_by_date_field: "`ls`",
21
+ }, user)
22
+ }.to raise_error(ForestLiana::Errors::HTTP422Error, 'Invalid aggregate function')
23
+ end
24
+ end
25
+
13
26
  describe 'Check client_timezone function' do
14
27
  describe 'with a SQLite database' do
15
28
  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
- collection: collection,
32
- timezone: 'Europe/Paris',
33
- aggregate: 'Count',
34
- group_by_field: group_by_field
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
+ collection: collection,
34
+ timezone: 'Europe/Paris',
35
+ aggregate: 'eval',
36
+ group_by_field: '`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
+ collection: collection,
54
+ timezone: 'Europe/Paris',
55
+ aggregate: 'Count',
56
+ group_by_field: group_by_field
57
+ }
58
+ }
42
59
 
43
- describe 'with an aggregate on the name field' do
44
- let(:group_by_field) { '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(:group_by_field) { '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(:group_by_field) { 'age' }
84
+ describe 'with an aggregate on the age field' do
85
+ let(:group_by_field) { '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(:group_by_field) { '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(:group_by_field) { '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(:group_by_field) { 'age' }
126
+ describe 'with an aggregate on the age field' do
127
+ let(:group_by_field) { '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
- collection: collection,
22
- timezone: "Europe/Paris",
23
- aggregate: "Count",
24
- filters: filters
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
+ collection: collection,
26
+ timezone: "Europe/Paris",
27
+ aggregate: "eval",
28
+ aggregate_field: "`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
+ collection: collection,
44
+ timezone: "Europe/Paris",
45
+ aggregate: "Count",
46
+ filters: filters
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(:collection) { 'users' }
36
- let(:filters) { { 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(:collection) { 'users' }
58
+ let(:filters) { { 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(:collection) { 'trees' }
47
- let(:filters) { { 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(:collection) { 'trees' }
69
+ let(:filters) { { 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(:collection) { 'trees' }
58
- let(:filters) { { 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(:collection) { 'trees' }
80
+ let(:filters) { { 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(:collection) { 'users' }
87
- let(:filters) { { 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(:collection) { 'users' }
109
+ let(:filters) { { 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: 7.8.0
4
+ version: 7.8.2
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-01-24 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