forest_liana 7.0.0.beta.4 → 7.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/controllers/forest_liana/actions_controller.rb +2 -2
- data/app/controllers/forest_liana/associations_controller.rb +2 -2
- data/app/controllers/forest_liana/resources_controller.rb +15 -6
- data/app/controllers/forest_liana/scopes_controller.rb +20 -0
- data/app/controllers/forest_liana/smart_actions_controller.rb +39 -3
- data/app/controllers/forest_liana/stats_controller.rb +5 -5
- data/app/services/forest_liana/filters_parser.rb +25 -9
- data/app/services/forest_liana/has_many_dissociator.rb +2 -2
- data/app/services/forest_liana/has_many_getter.rb +2 -2
- data/app/services/forest_liana/leaderboard_stat_getter.rb +20 -14
- data/app/services/forest_liana/line_stat_getter.rb +4 -2
- data/app/services/forest_liana/permissions_checker.rb +3 -4
- data/app/services/forest_liana/permissions_getter.rb +2 -2
- data/app/services/forest_liana/pie_stat_getter.rb +6 -3
- data/app/services/forest_liana/resource_getter.rb +6 -3
- data/app/services/forest_liana/resource_updater.rb +5 -2
- data/app/services/forest_liana/resources_getter.rb +6 -5
- data/app/services/forest_liana/scope_manager.rb +102 -0
- data/app/services/forest_liana/search_query_builder.rb +6 -3
- data/app/services/forest_liana/stat_getter.rb +2 -1
- data/app/services/forest_liana/value_stat_getter.rb +4 -2
- data/config/routes.rb +3 -0
- data/lib/forest_liana/version.rb +1 -1
- data/spec/dummy/app/controllers/forest/islands_controller.rb +5 -0
- data/spec/dummy/config/routes.rb +4 -0
- data/spec/dummy/lib/forest_liana/collections/island.rb +7 -0
- data/spec/requests/actions_controller_spec.rb +100 -12
- data/spec/requests/resources_spec.rb +2 -0
- data/spec/services/forest_liana/filters_parser_spec.rb +27 -1
- data/spec/services/forest_liana/has_many_getter_spec.rb +116 -0
- data/spec/services/forest_liana/line_stat_getter_spec.rb +14 -6
- data/spec/services/forest_liana/permissions_checker_acl_disabled_spec.rb +1 -3
- data/spec/services/forest_liana/pie_stat_getter_spec.rb +114 -0
- data/spec/services/forest_liana/resource_updater_spec.rb +116 -0
- data/spec/services/forest_liana/resources_getter_spec.rb +68 -1
- data/spec/services/forest_liana/scope_manager_spec.rb +232 -0
- data/spec/services/forest_liana/value_stat_getter_spec.rb +96 -0
- metadata +20 -15
- data/app/services/forest_liana/scope_validator.rb +0 -98
- data/test/services/forest_liana/has_many_getter_test.rb +0 -75
- data/test/services/forest_liana/pie_stat_getter_test.rb +0 -29
- data/test/services/forest_liana/resource_updater_test.rb +0 -86
- data/test/services/forest_liana/scope_validator_test.rb +0 -185
- data/test/services/forest_liana/value_stat_getter_test.rb +0 -71
@@ -17,6 +17,8 @@ describe 'Requesting Tree resources', :type => :request do
|
|
17
17
|
allow(ForestLiana::IpWhitelist).to receive(:is_ip_valid) { true }
|
18
18
|
|
19
19
|
allow_any_instance_of(ForestLiana::PermissionsChecker).to receive(:is_authorized?) { true }
|
20
|
+
|
21
|
+
allow(ForestLiana::ScopeManager).to receive(:fetch_scopes).and_return({})
|
20
22
|
end
|
21
23
|
|
22
24
|
token = JWT.encode({
|
@@ -11,6 +11,7 @@ module ForestLiana
|
|
11
11
|
let(:date_condition_1) { { 'field' => 'created_at', 'operator' => 'before', 'value' => 2.hours.ago } }
|
12
12
|
let(:date_condition_2) { { 'field' => 'created_at', 'operator' => 'today' } }
|
13
13
|
let(:date_condition_3) { { 'field' => 'created_at', 'operator' => 'previous_x_days', 'value' => 2 } }
|
14
|
+
let(:presence_condition) { { 'field' => 'name', 'operator' => 'present' } }
|
14
15
|
|
15
16
|
before {
|
16
17
|
island = Island.create!(name: "L'île de la muerta")
|
@@ -274,6 +275,11 @@ module ForestLiana
|
|
274
275
|
let(:filters) { { 'aggregator' => 'or', 'conditions' => [simple_condition_2, simple_condition_3] } }
|
275
276
|
it { expect(resource.where(query).count).to eq 2 }
|
276
277
|
end
|
278
|
+
|
279
|
+
context "'name ends_with \"3\"' 'or' 'name is not null'" do
|
280
|
+
let(:filters) { { 'aggregator' => 'or', 'conditions' => [simple_condition_2, presence_condition] } }
|
281
|
+
it { expect(resource.where(query).count).to eq 3 }
|
282
|
+
end
|
277
283
|
end
|
278
284
|
|
279
285
|
describe 'parse_condition' do
|
@@ -281,7 +287,27 @@ module ForestLiana
|
|
281
287
|
let(:result) { filter_parser.parse_condition(condition) }
|
282
288
|
|
283
289
|
context 'on valid condition' do
|
284
|
-
|
290
|
+
context 'when the condition uses the contains operator' do
|
291
|
+
it { expect(result).to eq "\"trees\".\"name\" LIKE '%3'" }
|
292
|
+
end
|
293
|
+
|
294
|
+
context 'when the condition uses the blank operator' do
|
295
|
+
let(:condition) { { 'field' => 'name', 'operator' => 'blank' } }
|
296
|
+
|
297
|
+
it { expect(result).to eq "\"trees\".\"name\" IS NULL" }
|
298
|
+
end
|
299
|
+
|
300
|
+
context 'when the condition uses the presence operator' do
|
301
|
+
let(:condition) { presence_condition }
|
302
|
+
|
303
|
+
it { expect(result).to eq "\"trees\".\"name\" IS NOT NULL" }
|
304
|
+
end
|
305
|
+
|
306
|
+
context 'when the condition uses the in operator' do
|
307
|
+
let(:condition) { { 'field' => 'name', 'operator' => 'in', 'value' => ['Tree n1', 'Tree n3'] } }
|
308
|
+
|
309
|
+
it { expect(result).to eq "\"trees\".\"name\" IN ('Tree n1','Tree n3')" }
|
310
|
+
end
|
285
311
|
end
|
286
312
|
|
287
313
|
context 'on belongs_to condition' do
|
@@ -0,0 +1,116 @@
|
|
1
|
+
module ForestLiana
|
2
|
+
describe HasManyGetter do
|
3
|
+
describe 'when retrieving has many relationship related records' do
|
4
|
+
let(:rendering_id) { 13 }
|
5
|
+
let(:user) { { 'id' => '1', 'rendering_id' => rendering_id } }
|
6
|
+
let(:scopes) { { } }
|
7
|
+
let(:association) { Island.reflect_on_association(:trees) }
|
8
|
+
let(:params) {
|
9
|
+
{
|
10
|
+
id: Island.first.id,
|
11
|
+
association_name: 'trees',
|
12
|
+
page: { size: 15, number: 1 },
|
13
|
+
timezone: 'America/Nome'
|
14
|
+
}
|
15
|
+
}
|
16
|
+
|
17
|
+
subject {
|
18
|
+
described_class.new(Island, association, params, user)
|
19
|
+
}
|
20
|
+
|
21
|
+
before(:each) do
|
22
|
+
madagascar = Island.create(name: 'madagascar')
|
23
|
+
re = Island.create(name: 'ré')
|
24
|
+
Tree.create(name: 'lemon tree', island: madagascar)
|
25
|
+
Tree.create(name: 'banana tree', island: madagascar)
|
26
|
+
Tree.create(name: 'papaya tree', island: madagascar)
|
27
|
+
Tree.create(name: 'apple tree', island: re)
|
28
|
+
Tree.create(name: 'banana tree', island: re)
|
29
|
+
ForestLiana::ScopeManager.invalidate_scope_cache(rendering_id)
|
30
|
+
allow(ForestLiana::ScopeManager).to receive(:fetch_scopes).and_return(scopes)
|
31
|
+
end
|
32
|
+
|
33
|
+
after(:each) do
|
34
|
+
Island.destroy_all
|
35
|
+
Tree.destroy_all
|
36
|
+
end
|
37
|
+
|
38
|
+
describe 'with empty scopes' do
|
39
|
+
describe 'with page 1 size 15' do
|
40
|
+
it 'should return the 3 trees matching madagascar' do
|
41
|
+
subject.perform
|
42
|
+
|
43
|
+
expect(subject.records.count).to eq 3
|
44
|
+
expect(subject.count).to eq 3
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
describe 'when sorting by decreasing id' do
|
49
|
+
let(:params) {
|
50
|
+
{
|
51
|
+
id: Island.first.id,
|
52
|
+
association_name: 'trees',
|
53
|
+
sort: '-id',
|
54
|
+
page: { size: 15, number: 1 },
|
55
|
+
timezone: 'America/Nome'
|
56
|
+
}
|
57
|
+
}
|
58
|
+
|
59
|
+
it 'should order records properly' do
|
60
|
+
subject.perform
|
61
|
+
|
62
|
+
expect(subject.records.count).to eq 3
|
63
|
+
expect(subject.count).to eq 3
|
64
|
+
expect(subject.records.first.id).to be > subject.records.last.id
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
describe 'when searching for banana tree' do
|
69
|
+
let(:params) {
|
70
|
+
{
|
71
|
+
id: Island.first.id,
|
72
|
+
association_name: 'trees',
|
73
|
+
search: 'banana',
|
74
|
+
page: { size: 15, number: 1 },
|
75
|
+
timezone: 'America/Nome'
|
76
|
+
}
|
77
|
+
}
|
78
|
+
|
79
|
+
it 'should return only the banana tree linked to madagascar' do
|
80
|
+
subject.perform
|
81
|
+
|
82
|
+
expect(subject.records.count).to eq 1
|
83
|
+
expect(subject.count).to eq 1
|
84
|
+
expect(subject.records.first.island.name).to eq 'madagascar'
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
describe 'with scopes' do
|
90
|
+
let(:scopes) { {
|
91
|
+
'Tree' => {
|
92
|
+
'scope'=> {
|
93
|
+
'filter'=> {
|
94
|
+
'aggregator' => 'and',
|
95
|
+
'conditions' => [
|
96
|
+
{ 'field' => 'name', 'operator' => 'contains', 'value' => 'a' }
|
97
|
+
]
|
98
|
+
},
|
99
|
+
'dynamicScopesValues' => { }
|
100
|
+
}
|
101
|
+
}
|
102
|
+
} }
|
103
|
+
|
104
|
+
describe 'when asking for all trees related to madagascar' do
|
105
|
+
it 'should return trees belonging to madagascar and matching the scopes' do
|
106
|
+
subject.perform
|
107
|
+
|
108
|
+
# Only `papaya` and `banana` contain an `a`
|
109
|
+
expect(subject.records.count).to eq 2
|
110
|
+
expect(subject.count).to eq 2
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
@@ -1,12 +1,21 @@
|
|
1
1
|
module ForestLiana
|
2
2
|
describe LineStatGetter do
|
3
|
+
let(:rendering_id) { 13 }
|
4
|
+
let(:user) { { 'id' => '1', 'rendering_id' => rendering_id } }
|
5
|
+
let(:scopes) { { } }
|
6
|
+
|
7
|
+
before(:each) do
|
8
|
+
ForestLiana::ScopeManager.invalidate_scope_cache(rendering_id)
|
9
|
+
allow(ForestLiana::ScopeManager).to receive(:fetch_scopes).and_return(scopes)
|
10
|
+
end
|
11
|
+
|
3
12
|
describe 'Check client_timezone function' do
|
4
13
|
describe 'with a SQLite database' do
|
5
14
|
it 'should return false' do
|
6
15
|
expect(LineStatGetter.new(Owner, {
|
7
16
|
timezone: "Europe/Paris",
|
8
17
|
aggregate: "Count",
|
9
|
-
}).client_timezone).to eq(false)
|
18
|
+
}, user).client_timezone).to eq(false)
|
10
19
|
end
|
11
20
|
end
|
12
21
|
|
@@ -16,7 +25,7 @@ module ForestLiana
|
|
16
25
|
expect(LineStatGetter.new(Owner, {
|
17
26
|
timezone: "Europe/Paris",
|
18
27
|
aggregate: "Count",
|
19
|
-
}).client_timezone).to eq('Europe/Paris')
|
28
|
+
}, user).client_timezone).to eq('Europe/Paris')
|
20
29
|
end
|
21
30
|
end
|
22
31
|
end
|
@@ -25,7 +34,6 @@ module ForestLiana
|
|
25
34
|
describe 'Using a Count aggregation' do
|
26
35
|
describe 'Using a Week time range' do
|
27
36
|
it 'should return consistent data based on monday as week_start ' do
|
28
|
-
|
29
37
|
# Week should start on monday
|
30
38
|
# 08-05-2021 was a Saturday
|
31
39
|
Owner.create(name: 'Michel', hired_at: Date.parse('08-05-2021'));
|
@@ -38,8 +46,8 @@ module ForestLiana
|
|
38
46
|
aggregate: "Count",
|
39
47
|
time_range: "Week",
|
40
48
|
group_by_date_field: "hired_at",
|
41
|
-
}).perform
|
42
|
-
|
49
|
+
}, user).perform
|
50
|
+
|
43
51
|
expect(stat.value.find { |item| item[:label] == "W18-2021" }[:values][:value]).to eq(2)
|
44
52
|
expect(stat.value.find { |item| item[:label] == "W19-2021" }[:values][:value]).to eq(2)
|
45
53
|
end
|
@@ -47,4 +55,4 @@ module ForestLiana
|
|
47
55
|
end
|
48
56
|
end
|
49
57
|
end
|
50
|
-
end
|
58
|
+
end
|
@@ -191,7 +191,6 @@ module ForestLiana
|
|
191
191
|
end
|
192
192
|
end
|
193
193
|
|
194
|
-
|
195
194
|
context 'renderings cache' do
|
196
195
|
let(:fake_ressource) { collection_name }
|
197
196
|
let(:rendering_id) { 1 }
|
@@ -499,7 +498,7 @@ module ForestLiana
|
|
499
498
|
expect(subject.is_authorized?).to be false
|
500
499
|
end
|
501
500
|
end
|
502
|
-
|
501
|
+
|
503
502
|
end
|
504
503
|
|
505
504
|
context 'when user has not the required permission' do
|
@@ -519,7 +518,6 @@ module ForestLiana
|
|
519
518
|
expect(subject.is_authorized?).to be false
|
520
519
|
end
|
521
520
|
end
|
522
|
-
|
523
521
|
end
|
524
522
|
end
|
525
523
|
|
@@ -0,0 +1,114 @@
|
|
1
|
+
module ForestLiana
|
2
|
+
describe PieStatGetter do
|
3
|
+
let(:rendering_id) { 13 }
|
4
|
+
let(:user) { { 'id' => '1', 'rendering_id' => rendering_id } }
|
5
|
+
let(:records) { [
|
6
|
+
{ name: 'Young Tree n1', age: 3 },
|
7
|
+
{ name: 'Young Tree n2', age: 3 },
|
8
|
+
{ name: 'Young Tree n3', age: 3 },
|
9
|
+
{ name: 'Young Tree n4', age: 3 },
|
10
|
+
{ name: 'Young Tree n5', age: 3 },
|
11
|
+
{ name: 'Old Tree n1', age: 15 },
|
12
|
+
{ name: 'Old Tree n2', age: 15 },
|
13
|
+
{ name: 'Old Tree n3', age: 15 },
|
14
|
+
{ name: 'Old Tree n4', age: 15 }
|
15
|
+
] }
|
16
|
+
|
17
|
+
before(:each) do
|
18
|
+
ForestLiana::ScopeManager.invalidate_scope_cache(rendering_id)
|
19
|
+
allow(ForestLiana::ScopeManager).to receive(:fetch_scopes).and_return(scopes)
|
20
|
+
|
21
|
+
records.each { |record|
|
22
|
+
Tree.create!(name: record[:name], age: record[:age])
|
23
|
+
}
|
24
|
+
end
|
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
|
35
|
+
}
|
36
|
+
}
|
37
|
+
|
38
|
+
subject { PieStatGetter.new(model, params, user) }
|
39
|
+
|
40
|
+
describe 'with empty scopes' do
|
41
|
+
let(:scopes) { { } }
|
42
|
+
|
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 eq [
|
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
|
+
]
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
describe 'with an aggregate on the age field' do
|
63
|
+
let(:group_by_field) { 'age' }
|
64
|
+
|
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 }]
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
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' => { }
|
84
|
+
}
|
85
|
+
}
|
86
|
+
}
|
87
|
+
}
|
88
|
+
|
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 eq [
|
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
|
+
]
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
describe 'with an aggregate on the age field' do
|
105
|
+
let(:group_by_field) { 'age' }
|
106
|
+
|
107
|
+
it 'should be only one category' do
|
108
|
+
subject.perform
|
109
|
+
expect(subject.record.value).to eq [{ :key => 3, :value => 5}]
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
@@ -0,0 +1,116 @@
|
|
1
|
+
module ForestLiana
|
2
|
+
describe ResourceUpdater do
|
3
|
+
describe 'when updating a record' do
|
4
|
+
let(:params) {
|
5
|
+
ActionController::Parameters.new(
|
6
|
+
id: 1,
|
7
|
+
data: {
|
8
|
+
id: 1,
|
9
|
+
type: 'User',
|
10
|
+
attributes: attributes
|
11
|
+
}
|
12
|
+
)
|
13
|
+
}
|
14
|
+
let(:rendering_id) { 13 }
|
15
|
+
let(:user) { { 'id' => '1', 'rendering_id' => rendering_id } }
|
16
|
+
let(:scopes) { { } }
|
17
|
+
|
18
|
+
subject {
|
19
|
+
described_class.new(User, params, user)
|
20
|
+
}
|
21
|
+
|
22
|
+
before(:each) do
|
23
|
+
User.create(name: 'Merry')
|
24
|
+
ForestLiana::ScopeManager.invalidate_scope_cache(rendering_id)
|
25
|
+
allow(ForestLiana::ScopeManager).to receive(:fetch_scopes).and_return(scopes)
|
26
|
+
end
|
27
|
+
|
28
|
+
after(:each) do
|
29
|
+
User.destroy_all
|
30
|
+
end
|
31
|
+
|
32
|
+
describe 'with empty scopes' do
|
33
|
+
describe 'with a missing name in attributes' do
|
34
|
+
let(:attributes) { { } }
|
35
|
+
|
36
|
+
it 'should not update the record name' do
|
37
|
+
subject.perform
|
38
|
+
|
39
|
+
expect(subject.record.valid?).to be true
|
40
|
+
expect(subject.record.name).to eq 'Merry'
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe 'with a null name in attributes' do
|
45
|
+
let(:attributes) { { name: nil } }
|
46
|
+
|
47
|
+
it 'should set the record name to null' do
|
48
|
+
subject.perform
|
49
|
+
|
50
|
+
expect(subject.record.valid?).to be true
|
51
|
+
expect(subject.record.name).to eq nil
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe 'with a new value as name in attributes' do
|
56
|
+
let(:attributes) { { name: 'Pippin' } }
|
57
|
+
|
58
|
+
it 'should set the record name to null' do
|
59
|
+
subject.perform
|
60
|
+
|
61
|
+
expect(subject.record.valid?).to be true
|
62
|
+
expect(subject.record.name).to eq 'Pippin'
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
describe 'with scope excluding target record' do
|
68
|
+
let(:attributes) { { name: 'Gandalf' } }
|
69
|
+
let(:scopes) { {
|
70
|
+
'User' => {
|
71
|
+
'scope'=> {
|
72
|
+
'filter'=> {
|
73
|
+
'aggregator' => 'and',
|
74
|
+
'conditions' => [
|
75
|
+
{ 'field' => 'id', 'operator' => 'greater_than', 'value' => 2 }
|
76
|
+
]
|
77
|
+
},
|
78
|
+
'dynamicScopesValues' => { }
|
79
|
+
}
|
80
|
+
}
|
81
|
+
} }
|
82
|
+
|
83
|
+
it 'should not update the record name' do
|
84
|
+
subject.perform
|
85
|
+
|
86
|
+
expect(subject.record).to be nil
|
87
|
+
expect(subject.errors[0][:detail]).to eq 'Couldn\'t find User with \'id\'=1 [WHERE (("users"."id" > 2))]'
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
describe 'with scope including target record' do
|
92
|
+
let(:attributes) { { name: 'Gandalf' } }
|
93
|
+
let(:scopes) { {
|
94
|
+
'User' => {
|
95
|
+
'scope'=> {
|
96
|
+
'filter'=> {
|
97
|
+
'aggregator' => 'and',
|
98
|
+
'conditions' => [
|
99
|
+
{ 'field' => 'id', 'operator' => 'less_than', 'value' => 2 }
|
100
|
+
]
|
101
|
+
},
|
102
|
+
'dynamicScopesValues' => { }
|
103
|
+
}
|
104
|
+
}
|
105
|
+
} }
|
106
|
+
|
107
|
+
it 'should not update the record name' do
|
108
|
+
subject.perform
|
109
|
+
|
110
|
+
expect(subject.record.valid?).to be true
|
111
|
+
expect(subject.record.name).to eq 'Gandalf'
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|