forest_liana 9.1.9 → 9.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (26) hide show
  1. checksums.yaml +4 -4
  2. data/app/services/forest_liana/ability/permission/smart_action_checker.rb +1 -1
  3. data/app/services/forest_liana/filters_parser.rb +1 -5
  4. data/app/services/forest_liana/leaderboard_stat_getter.rb +1 -1
  5. data/app/services/forest_liana/line_stat_getter.rb +1 -1
  6. data/app/services/forest_liana/pie_stat_getter.rb +1 -1
  7. data/app/services/forest_liana/scope_manager.rb +34 -58
  8. data/app/services/forest_liana/utils/context_variables.rb +41 -0
  9. data/app/services/forest_liana/utils/context_variables_injector.rb +53 -0
  10. data/app/services/forest_liana/value_stat_getter.rb +1 -1
  11. data/lib/forest_liana/version.rb +1 -1
  12. data/spec/requests/actions_controller_spec.rb +32 -4
  13. data/spec/requests/count_spec.rb +1 -1
  14. data/spec/requests/resources_spec.rb +6 -7
  15. data/spec/requests/stats_spec.rb +29 -28
  16. data/spec/services/forest_liana/filters_parser_spec.rb +35 -35
  17. data/spec/services/forest_liana/has_many_getter_spec.rb +13 -11
  18. data/spec/services/forest_liana/line_stat_getter_spec.rb +1 -1
  19. data/spec/services/forest_liana/pie_stat_getter_spec.rb +11 -11
  20. data/spec/services/forest_liana/resource_updater_spec.rb +25 -21
  21. data/spec/services/forest_liana/resources_getter_spec.rb +10 -10
  22. data/spec/services/forest_liana/scope_manager_spec.rb +243 -152
  23. data/spec/services/forest_liana/utils/context_variables_injector_spec.rb +107 -0
  24. data/spec/services/forest_liana/utils/context_variables_spec.rb +43 -0
  25. data/spec/services/forest_liana/value_stat_getter_spec.rb +11 -11
  26. metadata +8 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f3862ddc61c276a741d24fa5abb2702b44a8fbee31046ad33eca60d9ad43f084
4
- data.tar.gz: 775b29d9b6d45da178dfdcf83dd7c4ae1ae4d05f4485053bfc3864eff7058d6f
3
+ metadata.gz: b721a5f9e7e41711b05b4e34c607d8e23e7030646eb8896629b1170e55466869
4
+ data.tar.gz: 999494458850509c7698b2d00a77f2e8d41d767419b0e5b652ac8114b4fcbb9a
5
5
  SHA512:
6
- metadata.gz: add3d6d36eb1c4fc96b82e8cbfaf9067cdd1c8b0c735c6bf6857c8a1592c810cffd9044a96edddd95ba912cc4512a8e2523915b144e871002ff2420091cf5611
7
- data.tar.gz: c8c328ac81482846d8a9d0144319a9e9e17e64d01fb1ab84e155a68096b95b3174b8fae7cee7513d4c3b532d38085a3caacd4af06f19f52af53d2e6264d668ba
6
+ metadata.gz: 4fdc7007c031c6377f6d1281dad2ca82e1966d4692995ab592d149d6afe5c8b1a78bbc202ff5b558b3ee770f864a4caacb84c67ffc4aa79f1416ccaeb38c214d
7
+ data.tar.gz: e3dd0966176770f7b301a888480b72499025c2e0e1f727677a315f880397fa9903786eb2cb547cbdb6612b545c7a382d17c1ec5eeb95ab5496680bcde0bd8977
@@ -49,7 +49,7 @@ module ForestLiana
49
49
  begin
50
50
  attributes = @parameters[:data][:attributes]
51
51
  records = FiltersParser.new(
52
- @smart_action[condition_name][0]['filter'].to_json,
52
+ @smart_action[condition_name][0]['filter'],
53
53
  @collection,
54
54
  @parameters[:timezone],
55
55
  @parameters
@@ -3,7 +3,7 @@ module ForestLiana
3
3
  AGGREGATOR_OPERATOR = %w(and or)
4
4
 
5
5
  def initialize(filters, resource, timezone, params = nil)
6
- @filters = filters.instance_of?(ActionController::Parameters) ? filters.to_h : JSON.parse(filters)
6
+ @filters = filters
7
7
  @params = params
8
8
  @resource = resource
9
9
  @operator_date_parser = OperatorDateIntervalParser.new(timezone)
@@ -87,10 +87,6 @@ module ForestLiana
87
87
  value = condition['value']
88
88
  field_name = condition['field']
89
89
 
90
- if value.is_a?(String) && value.start_with?('{{')
91
- value = @params[:contextVariables][value.gsub(/[{}]/, '')]
92
- end
93
-
94
90
  if @operator_date_parser.is_date_operator?(operator)
95
91
  condition = @operator_date_parser.get_date_filter(operator, value)
96
92
  return "#{parse_field_name(field_name)} #{condition}"
@@ -27,7 +27,7 @@ module ForestLiana
27
27
  end
28
28
 
29
29
  def get_scoped_model(model, forest_user, timezone)
30
- scope_filters = ForestLiana::ScopeManager.get_scope_for_user(forest_user, model.name, as_string: true)
30
+ scope_filters = ForestLiana::ScopeManager.get_scope(model.name, forest_user)
31
31
 
32
32
  return model.unscoped if scope_filters.blank?
33
33
 
@@ -25,7 +25,7 @@ module ForestLiana
25
25
  def perform
26
26
  value = get_resource()
27
27
 
28
- filters = ForestLiana::ScopeManager.append_scope_for_user(@params[:filter], @user, @resource.name)
28
+ filters = ForestLiana::ScopeManager.append_scope_for_user(@params[:filter], @user, @resource.name, @params['contextVariables'])
29
29
 
30
30
  unless filters.blank?
31
31
  value = FiltersParser.new(filters, @resource, @params[:timezone], @params).apply_filters
@@ -7,7 +7,7 @@ module ForestLiana
7
7
  timezone_offset = @params[:timezone].to_i
8
8
  resource = optimize_record_loading(@resource, get_resource)
9
9
 
10
- filters = ForestLiana::ScopeManager.append_scope_for_user(@params[:filter], @user, @resource.name)
10
+ filters = ForestLiana::ScopeManager.append_scope_for_user(@params[:filter], @user, @resource.name, @params['contextVariables'])
11
11
 
12
12
  unless filters.blank?
13
13
  resource = FiltersParser.new(filters, resource, @params[:timezone], @params).apply_filters
@@ -1,20 +1,19 @@
1
1
  module ForestLiana
2
2
  class ScopeManager
3
- @@scopes_cache = Hash.new
4
- # 5 minutes exipration cache
3
+ # 5 minutes expiration cache
5
4
  @@scope_cache_expiration_delta = 300
6
5
 
7
- def self.apply_scopes_on_records(records, forest_user, collection_name, timezone)
8
- scope_filters = get_scope_for_user(forest_user, collection_name, as_string: true)
6
+ def self.apply_scopes_on_records(records, user, collection_name, timezone)
7
+ scope_filters = get_scope(collection_name, user)
9
8
 
10
9
  return records if scope_filters.blank?
11
10
 
12
11
  FiltersParser.new(scope_filters, records, timezone).apply_filters
13
12
  end
14
13
 
15
- def self.append_scope_for_user(existing_filter, user, collection_name)
16
- existing_filter = existing_filter.to_json if existing_filter.is_a?(ActionController::Parameters)
17
- scope_filter = get_scope_for_user(user, collection_name, as_string: true)
14
+ def self.append_scope_for_user(existing_filter, user, collection_name, request_context_variables = nil)
15
+ existing_filter = inject_context_variables(existing_filter, user, request_context_variables) if existing_filter
16
+ scope_filter = get_scope(collection_name, user, request_context_variables)
18
17
  filters = [existing_filter, scope_filter].compact
19
18
 
20
19
  case filters.length
@@ -23,80 +22,57 @@ module ForestLiana
23
22
  when 1
24
23
  filters[0]
25
24
  else
26
- "{\"aggregator\":\"and\",\"conditions\":[#{existing_filter},#{scope_filter}]}"
25
+ { 'aggregator' => 'and', 'conditions' => [existing_filter, scope_filter] }
27
26
  end
28
27
  end
29
28
 
30
- def self.get_scope_for_user(user, collection_name, as_string: false)
31
- raise 'Missing required rendering_id' unless user['rendering_id']
32
- raise 'Missing required collection_name' unless collection_name
29
+ def self.get_scope(collection_name, user, request_context_variables = nil)
30
+ retrieve = fetch_scopes(user['rendering_id'])
31
+ scope = retrieve['scopes'][collection_name]
33
32
 
34
- collection_scope = get_collection_scope(user['rendering_id'], collection_name)
33
+ return nil if scope.nil?
35
34
 
36
- return nil unless collection_scope
37
-
38
- filters = format_dynamic_values(user['id'], collection_scope)
39
-
40
- as_string && filters ? JSON.generate(filters) : filters
35
+ inject_context_variables(scope, user, request_context_variables)
41
36
  end
42
37
 
43
- def self.get_collection_scope(rendering_id, collection_name)
44
- if !@@scopes_cache[rendering_id]
45
- # when scope cache is unset wait for the refresh
46
- refresh_scopes_cache(rendering_id)
47
- elsif has_cache_expired?(rendering_id)
48
- # when cache expired refresh the scopes without waiting for it
49
- Thread.new { refresh_scopes_cache(rendering_id) }
50
- end
38
+ def self.inject_context_variables(filter, user, request_context_variables = nil)
39
+ filter = JSON.parse(filter) if filter.is_a? String
51
40
 
52
- @@scopes_cache[rendering_id][:scopes][collection_name].deep_dup
53
- end
41
+ retrieve = fetch_scopes(user['rendering_id'])
42
+ context_variables = Utils::ContextVariables.new(retrieve['team'], user, request_context_variables)
54
43
 
55
- def self.has_cache_expired?(rendering_id)
56
- rendering_scopes = @@scopes_cache[rendering_id]
57
- return true unless rendering_scopes
58
-
59
- second_since_last_fetch = Time.now - rendering_scopes[:fetched_at]
60
- second_since_last_fetch >= @@scope_cache_expiration_delta
44
+ Utils::ContextVariablesInjector.inject_context_in_filter(filter, context_variables)
61
45
  end
62
46
 
63
- def self.refresh_scopes_cache(rendering_id)
64
- scopes = fetch_scopes(rendering_id)
65
- @@scopes_cache[rendering_id] = {
66
- :fetched_at => Time.now,
67
- :scopes => scopes
68
- }
47
+ def self.invalidate_scope_cache(rendering_id)
48
+ Rails.cache.delete('forest.scopes.' + rendering_id.to_s)
69
49
  end
70
50
 
71
51
  def self.fetch_scopes(rendering_id)
72
- query_parameters = { 'renderingId' => rendering_id }
73
- response = ForestLiana::ForestApiRequester.get('/liana/scopes', query: query_parameters)
52
+ response = ForestLiana::ForestApiRequester.get("/liana/v4/permissions/renderings/#{rendering_id}")
74
53
 
75
54
  if response.is_a?(Net::HTTPOK)
76
- JSON.parse(response.body)
55
+ Rails.cache.fetch('forest.scopes.' + rendering_id.to_s, expires_in: @@scope_cache_expiration_delta) do
56
+ data = {}
57
+ parse_response = JSON.parse(response.body)
58
+
59
+ data['scopes'] = decode_scope(parse_response['collections'])
60
+ data['team'] = parse_response['team']
61
+
62
+ data
63
+ end
77
64
  else
78
65
  raise 'Unable to fetch scopes'
79
66
  end
80
67
  end
81
68
 
82
- def self.format_dynamic_values(user_id, collection_scope)
83
- filter = collection_scope.dig('scope', 'filter')
84
- return nil unless filter
85
-
86
- dynamic_scopes_values = collection_scope.dig('scope', 'dynamicScopesValues')
87
-
88
- # Only goes one level deep as required for now
89
- filter['conditions'].map do |condition|
90
- value = condition['value']
91
- if value.is_a?(String) && value.start_with?('$currentUser')
92
- condition['value'] = dynamic_scopes_values.dig('users', user_id, value)
93
- end
69
+ def self.decode_scope(raw_scopes)
70
+ scopes = {}
71
+ raw_scopes.each do |collection_name, value|
72
+ scopes[collection_name] = value['scope'] unless value['scope'].nil?
94
73
  end
95
- filter
96
- end
97
74
 
98
- def self.invalidate_scope_cache(rendering_id)
99
- @@scopes_cache.delete(rendering_id)
75
+ scopes
100
76
  end
101
77
  end
102
78
  end
@@ -0,0 +1,41 @@
1
+ module ForestLiana
2
+ module Utils
3
+ class ContextVariables
4
+ attr_reader :team, :user, :request_context_variables
5
+
6
+ USER_VALUE_PREFIX = 'currentUser.'.freeze
7
+
8
+ USER_VALUE_TAG_PREFIX = 'currentUser.tags.'.freeze
9
+
10
+ USER_VALUE_TEAM_PREFIX = 'currentUser.team.'.freeze
11
+
12
+ def initialize(team, user, request_context_variables = nil)
13
+ @team = team
14
+ @user = user
15
+ @request_context_variables = request_context_variables
16
+ end
17
+
18
+ def get_value(context_variable_key)
19
+ return get_current_user_data(context_variable_key) if context_variable_key.start_with?(USER_VALUE_PREFIX)
20
+
21
+ request_context_variables[context_variable_key] if request_context_variables
22
+ end
23
+
24
+ private
25
+
26
+ def get_current_user_data(context_variable_key)
27
+ if context_variable_key.start_with?(USER_VALUE_TEAM_PREFIX)
28
+ return team[context_variable_key[USER_VALUE_TEAM_PREFIX.length..]]
29
+ end
30
+
31
+ if context_variable_key.start_with?(USER_VALUE_TAG_PREFIX)
32
+ user['tags'].each do |tag|
33
+ return tag[context_variable_key[USER_VALUE_TAG_PREFIX.length..]] if tag.key?(context_variable_key[USER_VALUE_TAG_PREFIX.length..])
34
+ end
35
+ end
36
+
37
+ user[context_variable_key[USER_VALUE_PREFIX.length..]]
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,53 @@
1
+ module ForestLiana
2
+ module Utils
3
+ class ContextVariablesInjector
4
+
5
+ def self.inject_context_in_value(value, context_variables)
6
+ inject_context_in_value_custom(value) do |context_variable_key|
7
+ context_variables.get_value(context_variable_key).to_s
8
+ end
9
+ end
10
+
11
+ def self.inject_context_in_value_custom(value)
12
+ return value unless value.is_a?(String)
13
+
14
+ value_with_context_variables_injected = value
15
+ regex = /{{([^}]+)}}/
16
+ encountered_variables = []
17
+
18
+ while (match = regex.match(value_with_context_variables_injected))
19
+ context_variable_key = match[1]
20
+
21
+ unless encountered_variables.include?(context_variable_key)
22
+ value_with_context_variables_injected.gsub!(
23
+ /{{#{context_variable_key}}}/,
24
+ yield(context_variable_key)
25
+ )
26
+ end
27
+
28
+ encountered_variables.push(context_variable_key)
29
+ end
30
+
31
+ value_with_context_variables_injected
32
+ end
33
+
34
+ def self.inject_context_in_filter(filter, context_variables)
35
+ return nil unless filter
36
+
37
+ if filter.key? 'aggregator'
38
+ return {
39
+ 'aggregator' => filter['aggregator'],
40
+ 'conditions' => filter['conditions'].map { |condition| inject_context_in_filter(condition, context_variables) }
41
+ }
42
+ end
43
+
44
+ {
45
+ 'field' => filter['field'],
46
+ 'operator' => filter['operator'],
47
+ 'value' => inject_context_in_value(filter['value'], context_variables)
48
+ }
49
+
50
+ end
51
+ end
52
+ end
53
+ end
@@ -6,7 +6,7 @@ module ForestLiana
6
6
  return if @params[:aggregator].blank?
7
7
  resource = optimize_record_loading(@resource, get_resource)
8
8
 
9
- filters = ForestLiana::ScopeManager.append_scope_for_user(@params[:filter], @user, @resource.name)
9
+ filters = ForestLiana::ScopeManager.append_scope_for_user(@params[:filter], @user, @resource.name, @params['contextVariables'])
10
10
 
11
11
  unless filters.blank?
12
12
  filter_parser = FiltersParser.new(filters, resource, @params[:timezone], @params)
@@ -1,3 +1,3 @@
1
1
  module ForestLiana
2
- VERSION = "9.1.9"
2
+ VERSION = "9.2.0"
3
3
  end
@@ -2,7 +2,7 @@ require 'rails_helper'
2
2
 
3
3
  describe 'Requesting Actions routes', :type => :request do
4
4
  let(:rendering_id) { 13 }
5
- let(:scope_filters) { nil }
5
+ let(:scope_filters) { {'scopes' => {}, 'team' => {'id' => '1', 'name' => 'Operations'}} }
6
6
 
7
7
  before(:each) do
8
8
  allow(ForestLiana::IpWhitelist).to receive(:is_ip_whitelist_retrieved) { true }
@@ -10,7 +10,7 @@ describe 'Requesting Actions routes', :type => :request do
10
10
  Island.create(id: 1, name: 'Corsica')
11
11
 
12
12
  ForestLiana::ScopeManager.invalidate_scope_cache(rendering_id)
13
- allow(ForestLiana::ScopeManager).to receive(:get_scope_for_user).and_return(scope_filters)
13
+ allow(ForestLiana::ScopeManager).to receive(:fetch_scopes).and_return(scope_filters)
14
14
  end
15
15
 
16
16
  after(:each) do
@@ -291,7 +291,21 @@ describe 'Requesting Actions routes', :type => :request do
291
291
 
292
292
  describe 'with scopes' do
293
293
  describe 'when record is in scope' do
294
- let(:scope_filters) { JSON.generate({ field: 'name', operator: 'equal', value: 'Corsica' }) }
294
+ let(:scope_filters) {
295
+ {
296
+ 'scopes' =>
297
+ {
298
+ 'Island' => {
299
+ 'aggregator' => 'and',
300
+ 'conditions' => [{'field' => 'name', 'operator' => 'equal', 'value' => 'Corsica'}]
301
+ }
302
+ },
303
+ 'team' => {
304
+ 'id' => 43,
305
+ 'name' => 'Operations'
306
+ }
307
+ }
308
+ }
295
309
 
296
310
  it 'should respond 200 and perform the action' do
297
311
  post '/forest/actions/test', params: JSON.dump(params), headers: headers
@@ -301,7 +315,21 @@ describe 'Requesting Actions routes', :type => :request do
301
315
  end
302
316
 
303
317
  describe 'when record is out of scope' do
304
- let(:scope_filters) { JSON.generate({ field: 'name', operator: 'equal', value: 'Ré' }) }
318
+ let(:scope_filters) {
319
+ {
320
+ 'scopes' =>
321
+ {
322
+ 'Island' => {
323
+ 'aggregator' => 'and',
324
+ 'conditions' => [{'field' => 'name', 'operator' => 'equal', 'value' => 'Ré'}]
325
+ }
326
+ },
327
+ 'team' => {
328
+ 'id' => 43,
329
+ 'name' => 'Operations'
330
+ }
331
+ }
332
+ }
305
333
 
306
334
  it 'should respond 400 and NOT perform the action' do
307
335
  post '/forest/actions/test', params: JSON.dump(params), headers: headers
@@ -15,7 +15,7 @@ describe 'Requesting Owner', :type => :request do
15
15
 
16
16
  allow_any_instance_of(ForestLiana::Ability).to receive(:forest_authorize!) { true }
17
17
 
18
- allow(ForestLiana::ScopeManager).to receive(:fetch_scopes).and_return({})
18
+ allow(ForestLiana::ScopeManager).to receive(:fetch_scopes).and_return({'scopes' => {}, 'team' => {'id' => '1', 'name' => 'Operations'}})
19
19
  end
20
20
 
21
21
  token = JWT.encode({
@@ -1,10 +1,10 @@
1
1
  require 'rails_helper'
2
2
 
3
3
  describe 'Requesting Tree resources', :type => :request do
4
-
4
+ let(:scope_filters) { {'scopes' => {}, 'team' => {'id' => '1', 'name' => 'Operations'}} }
5
5
  before do
6
6
  user = User.create(name: 'Michel')
7
- tree = Tree.create(name: 'Lemon Tree', owner: user, cutter: user)
7
+ Tree.create(name: 'Lemon Tree', owner: user, cutter: user)
8
8
 
9
9
  Rails.cache.write('forest.users', {'1' => { 'id' => 1, 'roleId' => 1, 'rendering_id' => '1' }})
10
10
  Rails.cache.write('forest.has_permission', true)
@@ -26,8 +26,7 @@ describe 'Requesting Tree resources', :type => :request do
26
26
  allow(ForestLiana::IpWhitelist).to receive(:retrieve) { true }
27
27
  allow(ForestLiana::IpWhitelist).to receive(:is_ip_whitelist_retrieved) { true }
28
28
  allow(ForestLiana::IpWhitelist).to receive(:is_ip_valid) { true }
29
- # allow_any_instance_of(ForestLiana::Ability).to receive(:forest_authorize!) { true }
30
- allow(ForestLiana::ScopeManager).to receive(:fetch_scopes).and_return({})
29
+ allow(ForestLiana::ScopeManager).to receive(:fetch_scopes).and_return(scope_filters)
31
30
  end
32
31
 
33
32
  after do
@@ -156,10 +155,10 @@ describe 'Requesting Tree resources', :type => :request do
156
155
  end
157
156
 
158
157
  describe 'Requesting Address resources', :type => :request do
159
-
158
+ let(:scope_filters) { {'scopes' => {}, 'team' => {'id' => '1', 'name' => 'Operations'}} }
160
159
  before do
161
160
  user = User.create(name: 'Michel')
162
- address = Address.create(line1: '10 Downing Street', city: 'London', zipcode: '2AB', addressable: user)
161
+ Address.create(line1: '10 Downing Street', city: 'London', zipcode: '2AB', addressable: user)
163
162
 
164
163
  Rails.cache.write('forest.users', {'1' => { 'id' => 1, 'roleId' => 1, 'rendering_id' => '1' }})
165
164
  Rails.cache.write('forest.has_permission', true)
@@ -181,7 +180,7 @@ describe 'Requesting Address resources', :type => :request do
181
180
  allow(ForestLiana::IpWhitelist).to receive(:retrieve) { true }
182
181
  allow(ForestLiana::IpWhitelist).to receive(:is_ip_whitelist_retrieved) { true }
183
182
  allow(ForestLiana::IpWhitelist).to receive(:is_ip_valid) { true }
184
- allow(ForestLiana::ScopeManager).to receive(:fetch_scopes).and_return({})
183
+ allow(ForestLiana::ScopeManager).to receive(:fetch_scopes).and_return(scope_filters)
185
184
  end
186
185
 
187
186
  after do
@@ -2,34 +2,39 @@ require 'rails_helper'
2
2
  require 'json'
3
3
 
4
4
  describe "Stats", type: :request do
5
-
6
- token = JWT.encode({
7
- id: 1,
8
- email: 'michael.kelso@that70.show',
9
- first_name: 'Michael',
10
- last_name: 'Kelso',
11
- team: 'Operations',
12
- rendering_id: '1',
13
- exp: Time.now.to_i + 2.weeks.to_i,
14
- permission_level: 'admin'
15
- }, ForestLiana.auth_secret, 'HS256')
16
-
17
- headers = {
18
- 'Accept' => 'application/json',
19
- 'Content-Type' => 'application/json',
20
- 'Authorization' => "Bearer #{token}"
21
- }
22
-
5
+ let(:rendering_id) { 13 }
6
+ let(:scopes) { {'scopes' => {}, 'team' => {'id' => '1', 'name' => 'Operations'}} }
23
7
  let(:schema) {
24
8
  [
25
9
  ForestLiana::Model::Collection.new({
26
- name: 'Product',
27
- fields: [],
28
- actions: []
29
- })
10
+ name: 'Product',
11
+ fields: [],
12
+ actions: []
13
+ })
30
14
  ]
31
15
  }
32
16
 
17
+ let(:token) {
18
+ JWT.encode({
19
+ id: 1,
20
+ email: 'michael.kelso@that70.show',
21
+ first_name: 'Michael',
22
+ last_name: 'Kelso',
23
+ team: 'Operations',
24
+ rendering_id: rendering_id,
25
+ exp: Time.now.to_i + 2.weeks.to_i,
26
+ permission_level: 'admin'
27
+ }, ForestLiana.auth_secret, 'HS256')
28
+ }
29
+
30
+ let(:headers) {
31
+ {
32
+ 'Accept' => 'application/json',
33
+ 'Content-Type' => 'application/json',
34
+ 'Authorization' => "Bearer #{token}"
35
+ }
36
+ }
37
+
33
38
  before do
34
39
  Rails.cache.write('forest.users', {'1' => { 'id' => 1, 'roleId' => 1, 'rendering_id' => '1' }})
35
40
  Rails.cache.write('forest.has_permission', true)
@@ -53,12 +58,8 @@ describe "Stats", type: :request do
53
58
  }
54
59
  )
55
60
 
56
- ForestLiana::ScopeManager.class_variable_set(:@@scopes_cache, {
57
- '1' => {
58
- :fetched_at => Time.now,
59
- :scopes => {}
60
- }
61
- })
61
+ ForestLiana::ScopeManager.invalidate_scope_cache(rendering_id)
62
+ allow(ForestLiana::ScopeManager).to receive(:fetch_scopes).and_return(scopes)
62
63
 
63
64
  allow(ForestLiana).to receive(:apimap).and_return(schema)
64
65
  allow(ForestLiana::IpWhitelist).to receive(:retrieve) { true }