forest_liana 7.8.1 → 7.8.2

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 514943e2282e809284c9553682360f1beb2970978e980bc6b032294b28f3b1d5
4
- data.tar.gz: 249661d5290a7cb89ecbbda63459d5fa4405aa1fd20da0f4bdd42e6efa4bc960
3
+ metadata.gz: c535f5719b2f62c0ff1e2bde402a0c57b099f4120b5c6b3232d8ea0343c84eaf
4
+ data.tar.gz: b609b22af960f63d0b03e8a99597cf6d202da15414826d6dca1b836b7a672676
5
5
  SHA512:
6
- metadata.gz: 3d6799806766f3183f51b97262bb09d4d03c7b2c00094301eb9653eade4ae59efb9b3b4a33fe5ac0b4e3774318c4947d0440e92c9091e1c61612e7951288c841
7
- data.tar.gz: 37099c25f15492669119287dd68e047886d3413a92e26a63cdc7832e539de4cc9b103ed3c502f220cba09c80cb529f5fa7935fc9d9ee4571311f6b0c415e23b1
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.1"
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.1
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-02-28 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