multi-tenant-support 1.1.1 → 1.4.0

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: f6c137c5f91a50070226bf5943aa074b8efb8041493e022b194e950c4a828900
4
- data.tar.gz: 75981d65c8fcaee0be43716a4cd98529425847ff88c7dc428348fd557fb3ab89
3
+ metadata.gz: 2780344bf11a6b5bb065ebed1848d5630ba8b414ab1d5ed9d08a019cf7751265
4
+ data.tar.gz: feb76616d756d524e8c871afdf331d6a754e522c2951e6c3cf15d6cdf2463093
5
5
  SHA512:
6
- metadata.gz: 648bafb81bc655e8b5e5ce5f69cb5396c3d462e6ac67f6d95492a8f23063869c2202457fc76e944d5059bf9cd7fc6d77e898550851e40af5a88c2a912bb4d25c
7
- data.tar.gz: 984a0ab95e23d14bbe45f4814d265c5afb7b90a05147d7a3e31f2d2eec587c2e088a1a57adfea8316bf7137ff7f73d2c0500257cb1eb95fc734b7c94888d7b04
6
+ metadata.gz: 9e70944d15ffe56a7503f3de425b7c99c7a3bd9bbf17d9caa97912b5bddd692636acb4960ab670aba64c8996d6f2a74ced4cda071ee0e07728928a39dc42c953
7
+ data.tar.gz: 3543fc05811590fa14559213a02fd1a71569bc98ba562f93e6530483ba1c09e8a28fcb06f5ce0c80c07eee398ccc2bfa4bcf00b9321ca6a51315247bef7ea09e
data/README.md CHANGED
@@ -237,32 +237,29 @@ MultiTenantSupport.under_tenant amazon do
237
237
  end
238
238
  ```
239
239
 
240
- ### Disallow read across tenant by default
241
-
242
- This gem disallow read across tenant by default. You can check current state through:
240
+ ### Set current tenant global
243
241
 
244
242
  ```ruby
245
- MultiTenantSupport.disallow_read_across_tenant?
243
+ MultiTenantSupport.set_tenant_account(account)
246
244
  ```
247
245
 
248
- ### Allow read across tenant for super admin
249
-
250
- You can turn on the permission to read records across tenant through:
246
+ ### Temp set current tenant to nil
251
247
 
252
248
  ```ruby
253
- MultiTenantSupport.allow_read_across_tenant
254
-
255
- # Or
256
- MultiTenantSupport.allow_read_across_tenant do
249
+ MultiTenantSupport.without_current_tenant do
257
250
  # ...
258
251
  end
259
252
  ```
260
253
 
261
- You can put it in a before action in SuperAdmin's controllers
254
+ ### 3 protection states
262
255
 
263
- ### Disallow modify records tenant
256
+ 1. `MultiTenantSupport.full_protected?`
257
+ 2. `MultiTenantSupport.allow_read_across_tenant?`
258
+ 3. `MultiTenantSupport.unprotected?`
264
259
 
265
- This gem disallow modify record across tenant no matter you are super admin or not.
260
+ #### Full protection(default)
261
+
262
+ The default state is full protection. This gem disallow modify record across tenant by default.
266
263
 
267
264
  If `MultiTenantSupport.current_tenant` exist, you can only modify those records under this tenant, otherwise, you will get some errors like:
268
265
 
@@ -274,6 +271,45 @@ If `MultiTenantSupport.current_tenant` exist, you can only modify those records
274
271
 
275
272
  If `MultiTenantSupport.current_tenant` is missing, you cannot modify or create any tenanted records.
276
273
 
274
+ If you switched to other state, you can switch back through:
275
+
276
+ ```ruby
277
+ MultiTenantSupport.turn_on_full_protection
278
+
279
+ # Or
280
+ MultiTenantSupport.turn_on_full_protection do
281
+ # ...
282
+ end
283
+ ```
284
+
285
+ #### Allow read across tenant for super admin
286
+
287
+ You can turn on the permission to read records across tenant through:
288
+
289
+ ```ruby
290
+ MultiTenantSupport.allow_read_across_tenant
291
+
292
+ # Or
293
+ MultiTenantSupport.allow_read_across_tenant do
294
+ # ...
295
+ end
296
+ ```
297
+
298
+ You can put it in a before action in SuperAdmin's controllers
299
+
300
+ #### Turn off protection
301
+
302
+ Sometimes, as a super admin, we need to execute certain maintenatn operations over all tenant records. You can do this through:
303
+
304
+ ```ruby
305
+ MultiTenantSupport.turn_off_protection
306
+
307
+ # Or
308
+ MultiTenantSupport.turn_off_protection do
309
+ # ...
310
+ end
311
+ ```
312
+
277
313
  ### Set current tenant acccount in controller by default
278
314
 
279
315
  This gem has set a before action `set_current_tenant_account` on ActionController. It search tenant by subdomain or domain. Do remember to `skip_before_action :set_current_tenant_account` in super admin controllers.
@@ -306,6 +342,67 @@ Currently, we don't have a good way to protect this method. So please use `upser
306
342
 
307
343
  This gem has override `unscoped` to prevent the default tenant scope be scoped out. But if you really want to scope out the default tenant scope, you can use `unscope_tenant`.
308
344
 
345
+ ### Console
346
+
347
+ Console does not allow read across tenant by default. But you have several ways to change that:
348
+
349
+ 1. Set `allow_read_across_tenant_by_default` in the initialize file
350
+
351
+ ```ruby
352
+ console do |config|
353
+ config.allow_read_across_tenant_by_default = true
354
+ end
355
+ ```
356
+ 2. Set the environment variable `ALLOW_READ_ACROSS_TENANT` when call consoel command
357
+
358
+ ```bash
359
+ ALLOW_READ_ACROSS_TENANT=1 rails console
360
+ ```
361
+ 3. Manual change it in console
362
+
363
+ ```ruby
364
+ $ rails c
365
+ $ irb(main):001:0> MultiTenantSupport.allow_read_across_tenant
366
+ ```
367
+
368
+ ## Testing
369
+ ### Minitest (Rails default)
370
+
371
+ ```ruby
372
+ # test/test_helper.rb
373
+ require 'multi_tenant_support/minitet'
374
+ ```
375
+ ### RSpec (with Capybara)
376
+
377
+ ```ruby
378
+ # spec/rails_helper.rb or spec/spec_helper.rb
379
+ require 'multi_tenant_support/rspec'
380
+ ```
381
+
382
+ Above code will make sure the `MultiTenantSupport.current_tenant` won't accidentally be reset during integration and system tests. For example:
383
+
384
+ With above testing requre code
385
+
386
+ ```ruby
387
+ # Integration test
388
+ test "a integration test" do
389
+ host! "apple.example.com"
390
+
391
+ assert_no_changes "MultiTenantSupport.current_tenant" do
392
+ get users_path
393
+ end
394
+ end
395
+
396
+ # System test
397
+ test "a system test" do
398
+ Capybara.app_host = "http://apple.example.com"
399
+
400
+ assert_no_changes "MultiTenantSupport.current_tenant" do
401
+ visit users_path
402
+ end
403
+ end
404
+ ```
405
+
309
406
  ## Code Example
310
407
 
311
408
  ### Database Schema
@@ -340,6 +437,10 @@ MultiTenantSupport.configure do
340
437
  config.excluded_subdomains = ['www']
341
438
  config.host = 'example.com'
342
439
  end
440
+
441
+ console do |config|
442
+ config.allow_read_across_tenant_by_default = false
443
+ end
343
444
  end
344
445
  ```
345
446
 
@@ -12,6 +12,10 @@ MultiTenantSupport.configure do
12
12
  config.excluded_subdomains = ['www']
13
13
  config.host = 'REPLACE.ME'
14
14
  end
15
+
16
+ console do |config|
17
+ config.allow_read_across_tenant_by_default = false
18
+ end
15
19
  end
16
20
 
17
21
  # Uncomment if you are using sidekiq without ActiveJob
@@ -4,6 +4,7 @@ require "multi_tenant_support/errors"
4
4
  require "multi_tenant_support/config/app"
5
5
  require "multi_tenant_support/config/controller"
6
6
  require "multi_tenant_support/config/model"
7
+ require "multi_tenant_support/config/console"
7
8
  require "multi_tenant_support/current"
8
9
  require "multi_tenant_support/find_tenant_account"
9
10
  require "multi_tenant_support/concern/controller_concern"
@@ -25,35 +26,70 @@ module MultiTenantSupport
25
26
  Current.tenant_account&.send(model.tenant_account_primary_key)
26
27
  end
27
28
 
29
+ def set_current_tenant(tenant)
30
+ Current.tenant_account = tenant
31
+ Current.protection_state = PROTECTED
32
+ end
33
+
28
34
  def under_tenant(tenant_account, &block)
29
35
  raise ArgumentError, "block is missing" if block.nil?
30
36
 
31
- Current.set(tenant_account: tenant_account) do
37
+ Current.set(tenant_account: tenant_account, protection_state: PROTECTED) do
32
38
  yield
33
39
  end
34
40
  end
35
41
 
36
- def disallow_read_across_tenant?
37
- !Current.allow_read_across_tenant
42
+ def without_current_tenant(&block)
43
+ raise ArgumentError, "block is missing" if block.nil?
44
+
45
+ Current.set(tenant_account: nil) do
46
+ yield
47
+ end
38
48
  end
39
49
 
40
- def disallow_read_across_tenant
50
+ def full_protected?
51
+ current_tenant || Current.protection_state == PROTECTED
52
+ end
53
+
54
+ def allow_read_across_tenant?
55
+ current_tenant.nil? && [PROTECTED_EXCEPT_READ, UNPROTECTED].include?(Current.protection_state)
56
+ end
57
+
58
+ def unprotected?
59
+ current_tenant.nil? && Current.protection_state == UNPROTECTED
60
+ end
61
+
62
+ def turn_off_protection
63
+ raise 'Cannot turn off protection, try wrap in without_current_tenant' if current_tenant
64
+
41
65
  if block_given?
42
- Current.set(allow_read_across_tenant: false) do
66
+ Current.set(protection_state: UNPROTECTED) do
43
67
  yield
44
68
  end
45
69
  else
46
- Current.allow_read_across_tenant = false
70
+ Current.protection_state = UNPROTECTED
47
71
  end
48
72
  end
49
73
 
50
74
  def allow_read_across_tenant
75
+ raise 'Cannot read across tenant, try wrap in without_current_tenant' if current_tenant
76
+
77
+ if block_given?
78
+ Current.set(protection_state: PROTECTED_EXCEPT_READ) do
79
+ yield
80
+ end
81
+ else
82
+ Current.protection_state = PROTECTED_EXCEPT_READ
83
+ end
84
+ end
85
+
86
+ def turn_on_full_protection
51
87
  if block_given?
52
- Current.set(allow_read_across_tenant: true) do
88
+ Current.set(protection_state: PROTECTED) do
53
89
  yield
54
90
  end
55
91
  else
56
- Current.allow_read_across_tenant = true
92
+ Current.protection_state = PROTECTED
57
93
  end
58
94
  end
59
95
 
@@ -8,6 +8,7 @@ module MultiTenantSupport
8
8
  end
9
9
 
10
10
  class_methods do
11
+
11
12
  if Gem::Version.new(Rails.version) < Gem::Version.new("7.0.0.alpha1")
12
13
  def perform_now(*args)
13
14
  job = job_or_instantiate(*args)
@@ -23,6 +24,21 @@ module MultiTenantSupport
23
24
  end
24
25
  ")
25
26
  end
27
+
28
+ def execute(job_data)
29
+ keep_current_tenant_unchange do
30
+ super(job_data)
31
+ end
32
+ end
33
+
34
+ private
35
+
36
+ def keep_current_tenant_unchange
37
+ _current_tenant = MultiTenantSupport::Current.tenant_account
38
+ yield
39
+ ensure
40
+ MultiTenantSupport::Current.tenant_account = _current_tenant
41
+ end
26
42
  end
27
43
 
28
44
  def perform_now
@@ -10,13 +10,9 @@ module MultiTenantSupport
10
10
 
11
11
  private
12
12
 
13
- define_method(MultiTenantSupport.current_tenant_account_method) do
14
- instance_variable_get("@#{MultiTenantSupport.current_tenant_account_method}")
15
- end
16
-
17
13
  def set_current_tenant_account
18
14
  tenant_account = find_current_tenant_account
19
- MultiTenantSupport::Current.tenant_account = tenant_account
15
+ MultiTenantSupport.set_current_tenant(tenant_account)
20
16
  instance_variable_set("@#{MultiTenantSupport.current_tenant_account_method}", tenant_account)
21
17
  end
22
18
 
@@ -31,8 +27,12 @@ module MultiTenantSupport
31
27
  end
32
28
 
33
29
  module ViewHelper
34
- define_method(MultiTenantSupport.current_tenant_account_method) do
35
- instance_variable_get("@#{MultiTenantSupport.current_tenant_account_method}")
30
+ extend ActiveSupport::Concern
31
+
32
+ included do
33
+ define_method(MultiTenantSupport.current_tenant_account_method) do
34
+ instance_variable_get("@#{MultiTenantSupport.current_tenant_account_method}")
35
+ end
36
36
  end
37
37
  end
38
38
  end
@@ -18,7 +18,7 @@ module MultiTenantSupport
18
18
 
19
19
  def set_default_scope_under_current_tenant(foreign_key)
20
20
  default_scope lambda {
21
- if MultiTenantSupport.disallow_read_across_tenant? || MultiTenantSupport.current_tenant
21
+ if MultiTenantSupport.full_protected?
22
22
  scope_under_current_tenant
23
23
  else
24
24
  where(nil)
@@ -37,7 +37,7 @@ module MultiTenantSupport
37
37
 
38
38
  override_unscoped = Module.new {
39
39
  define_method :unscoped do |&block|
40
- if MultiTenantSupport.disallow_read_across_tenant? || MultiTenantSupport.current_tenant
40
+ if MultiTenantSupport.full_protected?
41
41
  block ? relation.scope_under_current_tenant.scoping { block.call } : relation.scope_under_current_tenant
42
42
  else
43
43
  super(&block)
@@ -48,13 +48,13 @@ module MultiTenantSupport
48
48
 
49
49
  override_insert_all = Module.new {
50
50
  define_method :insert_all do |attributes, **arguments|
51
- raise MissingTenantError unless MultiTenantSupport.current_tenant
51
+ raise MissingTenantError unless MultiTenantSupport.unprotected? || MultiTenantSupport.current_tenant
52
52
 
53
53
  super(attributes, **arguments)
54
54
  end
55
55
 
56
56
  define_method :insert_all! do |attributes, **arguments|
57
- raise MissingTenantError unless MultiTenantSupport.current_tenant
57
+ raise MissingTenantError unless MultiTenantSupport.unprotected? || MultiTenantSupport.current_tenant
58
58
 
59
59
  super(attributes, **arguments)
60
60
  end
@@ -63,7 +63,7 @@ module MultiTenantSupport
63
63
 
64
64
  override_upsert_all = Module.new {
65
65
  define_method :upsert_all do |attributes, **arguments|
66
- warn "[WARNING] You are using upsert_all(or upsert) which may update records across tenants"
66
+ warn "[WARNING] You are using upsert_all(or upsert) which may update records across tenants" unless MultiTenantSupport.unprotected?
67
67
 
68
68
  super(attributes, **arguments)
69
69
  end
@@ -71,13 +71,16 @@ module MultiTenantSupport
71
71
  extend override_upsert_all
72
72
 
73
73
  after_initialize do |object|
74
- if MultiTenantSupport.disallow_read_across_tenant? || object.new_record?
75
- raise MissingTenantError unless MultiTenantSupport.current_tenant
76
- raise InvalidTenantAccess if object.send(foreign_key) != MultiTenantSupport.current_tenant_id
77
- end
74
+ next if object.new_record? && MultiTenantSupport.unprotected?
75
+ next if object.persisted? && MultiTenantSupport.allow_read_across_tenant?
76
+
77
+ raise MissingTenantError unless MultiTenantSupport.current_tenant
78
+ raise InvalidTenantAccess if object.send(foreign_key) != MultiTenantSupport.current_tenant_id
78
79
  end
79
80
 
80
81
  before_save do |object|
82
+ next if MultiTenantSupport.unprotected?
83
+
81
84
  raise MissingTenantError unless MultiTenantSupport.current_tenant
82
85
  raise NilTenantError if object.send(foreign_key).nil?
83
86
  raise InvalidTenantAccess if object.send(foreign_key) != MultiTenantSupport.current_tenant_id
@@ -85,28 +88,24 @@ module MultiTenantSupport
85
88
 
86
89
  override_update_columns_module = Module.new {
87
90
  define_method :update_columns do |attributes|
88
- raise MissingTenantError unless MultiTenantSupport.current_tenant
89
- raise NilTenantError if send(foreign_key).nil?
90
- raise InvalidTenantAccess if send(foreign_key) != MultiTenantSupport.current_tenant_id
91
+ unless MultiTenantSupport.unprotected?
92
+ raise MissingTenantError unless MultiTenantSupport.current_tenant
93
+ raise NilTenantError if send(foreign_key).nil?
94
+ raise InvalidTenantAccess if send(foreign_key) != MultiTenantSupport.current_tenant_id
95
+ end
91
96
 
92
97
  super(attributes)
93
98
  end
94
-
95
- define_method :update_column do |name, value|
96
- raise MissingTenantError unless MultiTenantSupport.current_tenant
97
- raise NilTenantError if send(foreign_key).nil?
98
- raise InvalidTenantAccess if send(foreign_key) != MultiTenantSupport.current_tenant_id
99
-
100
- super(name, value)
101
- end
102
99
  }
103
100
 
104
101
  include override_update_columns_module
105
102
 
106
103
  override_delete = Module.new {
107
104
  define_method :delete do
108
- raise MissingTenantError unless MultiTenantSupport.current_tenant
109
- raise InvalidTenantAccess if send(foreign_key) != MultiTenantSupport.current_tenant_id
105
+ unless MultiTenantSupport.unprotected?
106
+ raise MissingTenantError unless MultiTenantSupport.current_tenant
107
+ raise InvalidTenantAccess if send(foreign_key) != MultiTenantSupport.current_tenant_id
108
+ end
110
109
 
111
110
  super()
112
111
  end
@@ -115,7 +114,9 @@ module MultiTenantSupport
115
114
 
116
115
  override_delete_by = Module.new {
117
116
  define_method :delete_by do |*args|
118
- raise MissingTenantError unless MultiTenantSupport.current_tenant
117
+ unless MultiTenantSupport.unprotected?
118
+ raise MissingTenantError unless MultiTenantSupport.current_tenant
119
+ end
119
120
 
120
121
  super(*args)
121
122
  end
@@ -123,8 +124,10 @@ module MultiTenantSupport
123
124
  extend override_delete_by
124
125
 
125
126
  before_destroy do |object|
126
- raise MissingTenantError unless MultiTenantSupport.current_tenant
127
- raise InvalidTenantAccess if object.send(foreign_key) != MultiTenantSupport.current_tenant_id
127
+ unless MultiTenantSupport.unprotected?
128
+ raise MissingTenantError unless MultiTenantSupport.current_tenant
129
+ raise InvalidTenantAccess if object.send(foreign_key) != MultiTenantSupport.current_tenant_id
130
+ end
128
131
  end
129
132
  end
130
133
 
@@ -132,9 +135,12 @@ module MultiTenantSupport
132
135
  readonly_tenant_module = Module.new {
133
136
 
134
137
  define_method "#{tenant_name}=" do |tenant|
138
+ return super(tenant_account) if MultiTenantSupport.unprotected?
139
+
135
140
  raise NilTenantError if tenant.nil?
136
141
  raise MissingTenantError unless MultiTenantSupport.current_tenant
137
142
 
143
+
138
144
  if new_record? && tenant == MultiTenantSupport.current_tenant
139
145
  super tenant
140
146
  else
@@ -143,6 +149,8 @@ module MultiTenantSupport
143
149
  end
144
150
 
145
151
  define_method "#{foreign_key}=" do |key|
152
+ return super(tenant_account) if MultiTenantSupport.unprotected?
153
+
146
154
  raise NilTenantError if key.nil?
147
155
  raise MissingTenantError unless MultiTenantSupport.current_tenant
148
156
 
@@ -170,9 +178,11 @@ ActiveSupport.on_load(:active_record) do |base|
170
178
 
171
179
  override_delete_all = Module.new {
172
180
  define_method :delete_all do
173
- current_tenant_exist = MultiTenantSupport.current_tenant
174
- is_global_model = !MultiTenantSupport.model.tenanted_models.include?(klass.name)
175
- raise MultiTenantSupport::MissingTenantError unless current_tenant_exist || is_global_model
181
+ unless MultiTenantSupport.unprotected?
182
+ current_tenant_exist = MultiTenantSupport.current_tenant
183
+ is_global_model = !MultiTenantSupport.model.tenanted_models.include?(klass.name)
184
+ raise MultiTenantSupport::MissingTenantError unless current_tenant_exist || is_global_model
185
+ end
176
186
 
177
187
  super()
178
188
  end
@@ -181,9 +191,11 @@ ActiveSupport.on_load(:active_record) do |base|
181
191
 
182
192
  override_update_all = Module.new {
183
193
  define_method :update_all do |updates|
184
- current_tenant_exist = MultiTenantSupport.current_tenant
185
- is_global_model = !MultiTenantSupport.model.tenanted_models.include?(klass.name)
186
- raise MultiTenantSupport::MissingTenantError unless current_tenant_exist || is_global_model
194
+ unless MultiTenantSupport.unprotected?
195
+ current_tenant_exist = MultiTenantSupport.current_tenant
196
+ is_global_model = !MultiTenantSupport.model.tenanted_models.include?(klass.name)
197
+ raise MultiTenantSupport::MissingTenantError unless current_tenant_exist || is_global_model
198
+ end
187
199
 
188
200
  super(updates)
189
201
  end
@@ -0,0 +1,21 @@
1
+ module MultiTenantSupport
2
+
3
+ module Config
4
+ class Console
5
+ attr_writer :allow_read_across_tenant_by_default
6
+
7
+ def allow_read_across_tenant_by_default
8
+ @allow_read_across_tenant_by_default ||= false
9
+ end
10
+ end
11
+ end
12
+
13
+ module_function
14
+ def console
15
+ @console ||= Config::Console.new
16
+ return @console unless block_given?
17
+
18
+ yield @console
19
+ end
20
+
21
+ end
@@ -1,8 +1,23 @@
1
1
  require 'active_support'
2
2
 
3
3
  module MultiTenantSupport
4
+
5
+ # Scoped and proteced
6
+ PROTECTED = 1
7
+
8
+ # Scoped and protected except read across tenant
9
+ PROTECTED_EXCEPT_READ = 2
10
+
11
+ # Scoped but unprotected
12
+ UNPROTECTED = 3
13
+
14
+ # This class is for internal usage only
4
15
  class Current < ActiveSupport::CurrentAttributes
5
16
  attribute :tenant_account,
6
- :allow_read_across_tenant
17
+ :protection_state
18
+
19
+ def protection_state
20
+ attributes[:protection_state] ||= PROTECTED
21
+ end
7
22
  end
8
23
  end
@@ -0,0 +1,7 @@
1
+ require_relative "./test/integration"
2
+ require_relative "./test/system"
3
+ require_relative "./test/capybara"
4
+
5
+ ActionDispatch::IntegrationTest.prepend(MultiTenantSupport::Test::Integration)
6
+ ActionDispatch::SystemTestCase.prepend(MultiTenantSupport::Test::System)
7
+ Capybara::Node::Element.prepend(MultiTenantSupport::Test::Capybara)
@@ -9,5 +9,13 @@ module MultiTenantSupport
9
9
  config.app_generators.templates.unshift(active_record_templates)
10
10
  end
11
11
 
12
+ console do
13
+ if ENV["ALLOW_READ_ACROSS_TENANT"] || MultiTenantSupport.console.allow_read_across_tenant_by_default
14
+ MultiTenantSupport.allow_read_across_tenant
15
+ else
16
+ MultiTenantSupport.turn_on_full_protection
17
+ end
18
+ end
19
+
12
20
  end
13
21
  end
@@ -0,0 +1,13 @@
1
+ require_relative "./test/integration"
2
+ require_relative "./test/system"
3
+ require_relative "./test/capybara"
4
+
5
+ RSpec.configure do |config|
6
+ config.include MultiTenantSupport::Test::Integration, type: :request
7
+ config.include MultiTenantSupport::Test::Integration, type: :controller
8
+
9
+ config.include MultiTenantSupport::Test::System, type: :system
10
+ config.include MultiTenantSupport::Test::System, type: :feature
11
+ end
12
+
13
+ Capybara::Node::Element.prepend(MultiTenantSupport::Test::Capybara)
@@ -0,0 +1,57 @@
1
+ module MultiTenantSupport
2
+ module Test
3
+ module Capybara
4
+
5
+ def set(value, **options)
6
+ keep_context_tenant_unchange do
7
+ super(value, **options)
8
+ end
9
+ end
10
+
11
+ def select_option(wait: nil)
12
+ keep_context_tenant_unchange do
13
+ super(wait: wait)
14
+ end
15
+ end
16
+
17
+ def unselect_option(wait: nil)
18
+ keep_context_tenant_unchange do
19
+ super(wait: wait)
20
+ end
21
+ end
22
+
23
+ def perform_click_action(keys, wait: nil, **options)
24
+ keep_context_tenant_unchange do
25
+ super
26
+ end
27
+ end
28
+
29
+ def trigger(event)
30
+ keep_context_tenant_unchange do
31
+ super
32
+ end
33
+ end
34
+
35
+ def evaluate_script(script, *args)
36
+ keep_context_tenant_unchange do
37
+ super
38
+ end
39
+ end
40
+
41
+ def evaluate_async_script(script, *args)
42
+ keep_context_tenant_unchange do
43
+ super
44
+ end
45
+ end
46
+
47
+ def keep_context_tenant_unchange
48
+ _current_tenant = MultiTenantSupport::Current.tenant_account
49
+ MultiTenantSupport::Current.tenant_account = nil # Simulate real circumstance
50
+ yield
51
+ ensure
52
+ MultiTenantSupport::Current.tenant_account = _current_tenant
53
+ end
54
+
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,29 @@
1
+ module MultiTenantSupport
2
+ module Test
3
+ module Integration
4
+
5
+ %i[get post patch put delete head options].each do |method|
6
+ define_method method do |path, **args|
7
+ keep_context_tenant_unchange do
8
+ super(path, **args)
9
+ end
10
+ end
11
+ end
12
+
13
+ def follow_redirect(**args)
14
+ keep_context_tenant_unchange do
15
+ super(**args)
16
+ end
17
+ end
18
+
19
+ def keep_context_tenant_unchange
20
+ _current_tenant = MultiTenantSupport::Current.tenant_account
21
+ MultiTenantSupport::Current.tenant_account = nil # Simulate real circumstance
22
+ yield
23
+ ensure
24
+ MultiTenantSupport::Current.tenant_account = _current_tenant
25
+ end
26
+
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,38 @@
1
+ module MultiTenantSupport
2
+ module Test
3
+ module System
4
+
5
+ %i[
6
+ visit refresh click_on go_back go_forward
7
+ check choose click_button click_link
8
+ fill_in uncheck check unselect select
9
+ execute_script evaluate_script
10
+ ].each do |method|
11
+ if RUBY_VERSION >= '2.7'
12
+ class_eval <<~METHOD, __FILE__, __LINE__ + 1
13
+ def #{method}(...)
14
+ keep_context_tenant_unchange do
15
+ super(...)
16
+ end
17
+ end
18
+ METHOD
19
+ else
20
+ define_method method do |*args, &block|
21
+ keep_context_tenant_unchange do
22
+ super(*args, &block)
23
+ end
24
+ end
25
+ end
26
+ end
27
+
28
+ def keep_context_tenant_unchange
29
+ _current_tenant = MultiTenantSupport::Current.tenant_account
30
+ MultiTenantSupport::Current.tenant_account = nil # Simulate real circumstance
31
+ yield
32
+ ensure
33
+ MultiTenantSupport::Current.tenant_account = _current_tenant
34
+ end
35
+
36
+ end
37
+ end
38
+ end
@@ -1,3 +1,3 @@
1
1
  module MultiTenantSupport
2
- VERSION = '1.1.1'
2
+ VERSION = '1.4.0'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: multi-tenant-support
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.1
4
+ version: 1.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Hopper Gee
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-10-07 00:00:00.000000000 Z
11
+ date: 2021-10-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -45,13 +45,19 @@ files:
45
45
  - lib/multi_tenant_support/concern/controller_concern.rb
46
46
  - lib/multi_tenant_support/concern/model_concern.rb
47
47
  - lib/multi_tenant_support/config/app.rb
48
+ - lib/multi_tenant_support/config/console.rb
48
49
  - lib/multi_tenant_support/config/controller.rb
49
50
  - lib/multi_tenant_support/config/model.rb
50
51
  - lib/multi_tenant_support/current.rb
51
52
  - lib/multi_tenant_support/errors.rb
52
53
  - lib/multi_tenant_support/find_tenant_account.rb
54
+ - lib/multi_tenant_support/minitest.rb
53
55
  - lib/multi_tenant_support/railtie.rb
56
+ - lib/multi_tenant_support/rspec.rb
54
57
  - lib/multi_tenant_support/sidekiq.rb
58
+ - lib/multi_tenant_support/test/capybara.rb
59
+ - lib/multi_tenant_support/test/integration.rb
60
+ - lib/multi_tenant_support/test/system.rb
55
61
  - lib/multi_tenant_support/version.rb
56
62
  - lib/tasks/multi_tenant_support_tasks.rake
57
63
  homepage: https://github.com/hoppergee/multi-tenant-support