motel-activerecord 1.0.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 +7 -0
- data/README.md +225 -0
- data/VERSION +1 -0
- data/lib/motel-activerecord.rb +10 -0
- data/lib/motel/connection_adapters.rb +3 -0
- data/lib/motel/connection_adapters/connection_handler.rb +96 -0
- data/lib/motel/connection_adapters/connection_specification.rb +2 -0
- data/lib/motel/connection_adapters/connection_specification/resolver.rb +92 -0
- data/lib/motel/errors.rb +28 -0
- data/lib/motel/lobby.rb +47 -0
- data/lib/motel/manager.rb +69 -0
- data/lib/motel/multi_tenant.rb +53 -0
- data/lib/motel/railtie.rb +63 -0
- data/lib/motel/sources.rb +3 -0
- data/lib/motel/sources/database.rb +120 -0
- data/lib/motel/sources/default.rb +54 -0
- data/lib/motel/sources/redis.rb +80 -0
- data/lib/motel/version.rb +6 -0
- data/spec/lib/motel/connection_adapters/connection_handler_spec.rb +184 -0
- data/spec/lib/motel/connection_adapters/connection_specification/resolver_spec.rb +120 -0
- data/spec/lib/motel/lobby_spec.rb +155 -0
- data/spec/lib/motel/manager_spec.rb +238 -0
- data/spec/lib/motel/multi_tenant_spec.rb +169 -0
- data/spec/lib/motel/sources/database_spec.rb +246 -0
- data/spec/lib/motel/sources/default_spec.rb +167 -0
- data/spec/lib/motel/sources/redis_spec.rb +188 -0
- data/spec/spec_helper.rb +14 -0
- data/spec/tmp/foo.sqlite3 +0 -0
- data/spec/tmp/tenants.sqlite3 +0 -0
- metadata +144 -0
@@ -0,0 +1,238 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Motel::Manager do
|
4
|
+
|
5
|
+
before(:all) do
|
6
|
+
ActiveRecord::Base.connection_handler = begin
|
7
|
+
Motel::ConnectionAdapters::ConnectionHandler.new
|
8
|
+
end
|
9
|
+
@manager = Motel::Manager
|
10
|
+
end
|
11
|
+
|
12
|
+
before(:each) do
|
13
|
+
ActiveRecord::Base.connection_handler.tenants_source = begin
|
14
|
+
Motel::Sources::Default.new
|
15
|
+
end
|
16
|
+
@tenants_source = ActiveRecord::Base.connection_handler.tenants_source
|
17
|
+
@tenants_source.add_tenant('foo', FOO_SPEC)
|
18
|
+
@tenants_source.add_tenant('bar', BAR_SPEC)
|
19
|
+
end
|
20
|
+
|
21
|
+
after(:each) do
|
22
|
+
ENV['TENANT'] = nil
|
23
|
+
@manager.current_tenant = nil
|
24
|
+
@manager.default_tenant = nil
|
25
|
+
|
26
|
+
# Remove all connections tenant
|
27
|
+
ActiveRecord::Base.connection_handler.active_tenants do |tenant|
|
28
|
+
ActiveRecord::Base.connection_handler.remove_connection(tenant)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe '#tenants_source_configurations' do
|
33
|
+
|
34
|
+
context 'redis source' do
|
35
|
+
|
36
|
+
before(:each) do
|
37
|
+
@manager.tenants_source_configurations({
|
38
|
+
source: :redis,
|
39
|
+
host: 'localhost',
|
40
|
+
port: 6380,
|
41
|
+
password: 'none',
|
42
|
+
path: '/tmp/redis.sock',
|
43
|
+
prefix_tenant_alias: 'test-tenant'
|
44
|
+
})
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'places a redis instance on the source' do
|
48
|
+
expect(@manager.tenants_source).to be_an_instance_of Motel::Sources::Redis
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'source attributes has a correct values' do
|
52
|
+
expect(@manager.tenants_source.host).to eq 'localhost'
|
53
|
+
expect(@manager.tenants_source.port).to eq 6380
|
54
|
+
expect(@manager.tenants_source.password).to eq 'none'
|
55
|
+
expect(@manager.tenants_source.path).to eq '/tmp/redis.sock'
|
56
|
+
expect(@manager.tenants_source.prefix_tenant_alias).to eq 'test-tenant'
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
|
61
|
+
context 'database source' do
|
62
|
+
|
63
|
+
before(:each) do
|
64
|
+
@manager.tenants_source_configurations({
|
65
|
+
source: :database,
|
66
|
+
source_spec: TENANTS_SPEC,
|
67
|
+
table_name: 'tenant'
|
68
|
+
})
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'places a database instance on the source' do
|
72
|
+
expect(@manager.tenants_source).to be_an_instance_of Motel::Sources::Database
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'source attributes has a correct values' do
|
76
|
+
expect(@manager.tenants_source.source_spec).to eq TENANTS_SPEC
|
77
|
+
expect(@manager.tenants_source.table_name).to eq 'tenant'
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
|
82
|
+
context 'default source' do
|
83
|
+
|
84
|
+
before(:each) do
|
85
|
+
@manager.tenants_source_configurations({source: :default})
|
86
|
+
end
|
87
|
+
|
88
|
+
it 'places a default instance on the source' do
|
89
|
+
expect(@manager.tenants_source).to be_an_instance_of Motel::Sources::Default
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
95
|
+
|
96
|
+
describe '#tenants' do
|
97
|
+
|
98
|
+
it 'returns tenant foo' do
|
99
|
+
expect(@manager.tenants.key?('foo')).to be_true
|
100
|
+
end
|
101
|
+
|
102
|
+
it 'returns tenant bar' do
|
103
|
+
expect(@manager.tenants.key?('bar')).to be_true
|
104
|
+
end
|
105
|
+
|
106
|
+
end
|
107
|
+
|
108
|
+
describe '#tenant' do
|
109
|
+
|
110
|
+
it 'returns tenant foo spec' do
|
111
|
+
expect(@manager.tenant('foo')['adapter']).to eq FOO_SPEC['adapter']
|
112
|
+
expect(@manager.tenant('foo')['database']).to eq FOO_SPEC['database']
|
113
|
+
end
|
114
|
+
|
115
|
+
end
|
116
|
+
|
117
|
+
describe '#tenant?' do
|
118
|
+
|
119
|
+
it 'returns true if tenant foo does exist' do
|
120
|
+
expect(@manager.tenant?('foo')).to be_true
|
121
|
+
end
|
122
|
+
|
123
|
+
it 'returns true if tenant baz does exist' do
|
124
|
+
resolver = ActiveRecord::ConnectionAdapters::ConnectionSpecification::Resolver.new(
|
125
|
+
BAZ_SPEC, nil
|
126
|
+
)
|
127
|
+
handler = ActiveRecord::Base.connection_handler
|
128
|
+
handler.establish_connection('baz', resolver.spec)
|
129
|
+
expect(@manager.tenant?('baz')).to be_true
|
130
|
+
end
|
131
|
+
|
132
|
+
it 'returns false if tenant does not exist' do
|
133
|
+
expect(@manager.tenant?('foobar')).to be_false
|
134
|
+
end
|
135
|
+
|
136
|
+
end
|
137
|
+
|
138
|
+
describe '#add_tenant' do
|
139
|
+
|
140
|
+
it 'adds new tenant' do
|
141
|
+
@manager.add_tenant('baz', BAZ_SPEC)
|
142
|
+
|
143
|
+
expect(@tenants_source.tenant?('baz')).to be_true
|
144
|
+
end
|
145
|
+
|
146
|
+
end
|
147
|
+
|
148
|
+
describe '#update_tenant' do
|
149
|
+
|
150
|
+
it 'updates tenant' do
|
151
|
+
@manager.update_tenant('foo', {adapter: 'mysql2', database: 'foo'})
|
152
|
+
|
153
|
+
expect(@tenants_source.tenant('foo')['adapter']).to eq 'mysql2'
|
154
|
+
expect(@tenants_source.tenant('foo')['database']).to eq 'foo'
|
155
|
+
end
|
156
|
+
|
157
|
+
it 'returns the spec unpdated' do
|
158
|
+
spec_updated = @manager.update_tenant('foo', {adapter: 'mysql2', database: 'foo'})
|
159
|
+
|
160
|
+
|
161
|
+
expect(spec_updated['adapter']).to eq 'mysql2'
|
162
|
+
expect(spec_updated['database']).to eq 'foo'
|
163
|
+
end
|
164
|
+
|
165
|
+
end
|
166
|
+
|
167
|
+
describe '#delete_tenant' do
|
168
|
+
|
169
|
+
it 'returns true' do
|
170
|
+
expect(@manager.delete_tenant('foo')).to be_true
|
171
|
+
end
|
172
|
+
|
173
|
+
it 'deletes tenant' do
|
174
|
+
@manager.delete_tenant('foo')
|
175
|
+
expect(@tenants_source.tenant?('foo')).to be_false
|
176
|
+
end
|
177
|
+
|
178
|
+
it 'removes connection of tenant' do
|
179
|
+
|
180
|
+
ActiveRecord::Base.connection_handler.establish_connection('foo')
|
181
|
+
@manager.delete_tenant('foo')
|
182
|
+
|
183
|
+
expect(ActiveRecord::Base.connection_handler.active_tenants).not_to include('foo')
|
184
|
+
end
|
185
|
+
|
186
|
+
end
|
187
|
+
|
188
|
+
describe '#active_tenants' do
|
189
|
+
|
190
|
+
it 'returns active tenans' do
|
191
|
+
ActiveRecord::Base.connection_handler.establish_connection('foo')
|
192
|
+
expect(@manager.active_tenants).to include('foo')
|
193
|
+
end
|
194
|
+
|
195
|
+
end
|
196
|
+
|
197
|
+
describe '#determines_tenant' do
|
198
|
+
|
199
|
+
context 'tenant environment variable, current tenant and default tenant are set' do
|
200
|
+
|
201
|
+
it 'returns tenant enviroment variable' do
|
202
|
+
ENV['TENANT'] = 'foo'
|
203
|
+
@manager.current_tenant = 'bar'
|
204
|
+
@manager.default_tenant = 'baz'
|
205
|
+
|
206
|
+
expect(@manager.determines_tenant).to eq ENV['TENANT']
|
207
|
+
end
|
208
|
+
|
209
|
+
end
|
210
|
+
|
211
|
+
context 'only current tenant and default tenant are set' do
|
212
|
+
|
213
|
+
it 'returns tenant enviroment variable' do
|
214
|
+
ENV['TENANT'] = nil
|
215
|
+
@manager.current_tenant = 'bar'
|
216
|
+
@manager.default_tenant = 'baz'
|
217
|
+
|
218
|
+
expect(@manager.determines_tenant).to eq @manager.current_tenant
|
219
|
+
end
|
220
|
+
|
221
|
+
end
|
222
|
+
|
223
|
+
context 'only default tenant is set' do
|
224
|
+
|
225
|
+
it 'returns tenant enviroment variable' do
|
226
|
+
ENV['TENANT'] = nil
|
227
|
+
@manager.current_tenant = nil
|
228
|
+
@manager.default_tenant = 'baz'
|
229
|
+
|
230
|
+
expect(@manager.determines_tenant).to eq @manager.default_tenant
|
231
|
+
end
|
232
|
+
|
233
|
+
end
|
234
|
+
|
235
|
+
end
|
236
|
+
|
237
|
+
end
|
238
|
+
|
@@ -0,0 +1,169 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ActiveRecord::Base do
|
4
|
+
|
5
|
+
before(:all) do
|
6
|
+
ActiveRecord::Base.motel.tenants_source_configurations({source: :default})
|
7
|
+
ActiveRecord::Base.motel.add_tenant('foo', FOO_SPEC)
|
8
|
+
ActiveRecord::Base.motel.add_tenant('bar', BAR_SPEC)
|
9
|
+
end
|
10
|
+
|
11
|
+
after(:all) do
|
12
|
+
ActiveRecord::Base.motel.delete_tenant('foo')
|
13
|
+
ActiveRecord::Base.motel.delete_tenant('bar')
|
14
|
+
end
|
15
|
+
|
16
|
+
after(:each) do
|
17
|
+
ActiveRecord::Base.connection_handler.active_tenants do |tenant|
|
18
|
+
ActiveRecord::Base.connection_handler.remove_connection(tenant)
|
19
|
+
end
|
20
|
+
ActiveRecord::Base.motel.current_tenant = nil
|
21
|
+
end
|
22
|
+
|
23
|
+
describe '.establish_connection' do
|
24
|
+
|
25
|
+
it 'establishes a connection keyed by the class name' do
|
26
|
+
ActiveRecord::Base.establish_connection(BAZ_SPEC)
|
27
|
+
|
28
|
+
expect(ActiveRecord::Base.connection_handler.active_tenants).to include('ActiveRecord::Base')
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
describe '.connection_pool' do
|
34
|
+
|
35
|
+
context 'current tenant established' do
|
36
|
+
|
37
|
+
it 'returns a connection pool of current tenant' do
|
38
|
+
ActiveRecord::Base.motel.current_tenant = 'foo'
|
39
|
+
pool = ActiveRecord::Base.connection_handler.establish_connection('foo')
|
40
|
+
|
41
|
+
expect(ActiveRecord::Base.connection_pool).to eq pool
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
context 'current tenant not established' do
|
47
|
+
|
48
|
+
it 'rises an error' do
|
49
|
+
ActiveRecord::Base.motel.current_tenant = nil
|
50
|
+
expect{ActiveRecord::Base.connection_pool}.to raise_error Motel::NoCurrentTenantError
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
|
57
|
+
describe '.retrieve_connection' do
|
58
|
+
|
59
|
+
context 'current tenant established' do
|
60
|
+
|
61
|
+
it 'returns a connection of current tenant' do
|
62
|
+
ActiveRecord::Base.motel.current_tenant = 'foo'
|
63
|
+
pool = ActiveRecord::Base.connection_handler.establish_connection('foo')
|
64
|
+
|
65
|
+
expect(ActiveRecord::Base.retrieve_connection).to eq pool.connection
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
|
70
|
+
context 'current tenant not established' do
|
71
|
+
|
72
|
+
it 'rises an error' do
|
73
|
+
ActiveRecord::Base.motel.current_tenant = nil
|
74
|
+
expect{ActiveRecord::Base.retrieve_connection}.to raise_error Motel::NoCurrentTenantError
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
|
81
|
+
describe '.connected?' do
|
82
|
+
|
83
|
+
before(:each) do
|
84
|
+
ActiveRecord::Base.connection_handler.retrieve_connection('foo')
|
85
|
+
end
|
86
|
+
|
87
|
+
context 'current tenant established' do
|
88
|
+
|
89
|
+
it 'returns true' do
|
90
|
+
ActiveRecord::Base.motel.current_tenant = 'foo'
|
91
|
+
expect(ActiveRecord::Base.connected?).to be_true
|
92
|
+
end
|
93
|
+
|
94
|
+
it 'returns false' do
|
95
|
+
ActiveRecord::Base.motel.current_tenant = 'bar'
|
96
|
+
expect(ActiveRecord::Base.connected?).to be_false
|
97
|
+
end
|
98
|
+
|
99
|
+
end
|
100
|
+
|
101
|
+
context 'current tenant not established' do
|
102
|
+
|
103
|
+
it 'rises an error' do
|
104
|
+
ActiveRecord::Base.motel.current_tenant = nil
|
105
|
+
expect{ActiveRecord::Base.connected?}.to raise_error Motel::NoCurrentTenantError
|
106
|
+
end
|
107
|
+
|
108
|
+
end
|
109
|
+
|
110
|
+
end
|
111
|
+
|
112
|
+
describe '.remove_connection' do
|
113
|
+
|
114
|
+
context 'current tenant established' do
|
115
|
+
|
116
|
+
it 'removes connection' do
|
117
|
+
ActiveRecord::Base.connection_handler.establish_connection('foo')
|
118
|
+
ActiveRecord::Base.motel.current_tenant = 'foo'
|
119
|
+
ActiveRecord::Base.remove_connection
|
120
|
+
expect(ActiveRecord::Base.connection_handler.active_tenants).not_to include('foo')
|
121
|
+
end
|
122
|
+
|
123
|
+
end
|
124
|
+
|
125
|
+
context 'current tenant not established' do
|
126
|
+
|
127
|
+
it 'rises an error' do
|
128
|
+
ActiveRecord::Base.motel.current_tenant = nil
|
129
|
+
expect{ActiveRecord::Base.remove_connection}.to raise_error Motel::NoCurrentTenantError
|
130
|
+
end
|
131
|
+
|
132
|
+
end
|
133
|
+
|
134
|
+
end
|
135
|
+
|
136
|
+
describe '.arel_engine' do
|
137
|
+
|
138
|
+
it 'returns a ActiveRecord::Base class' do
|
139
|
+
expect(ActiveRecord::Base.arel_engine).to eq ActiveRecord::Base
|
140
|
+
end
|
141
|
+
|
142
|
+
end
|
143
|
+
|
144
|
+
describe '.current_tenant' do
|
145
|
+
|
146
|
+
context 'tenant enviroment variable or current tenant or default tenant are set' do
|
147
|
+
|
148
|
+
it 'returns the current tenant' do
|
149
|
+
ActiveRecord::Base.motel.current_tenant = 'foo'
|
150
|
+
|
151
|
+
expect(ActiveRecord::Base.current_tenant).to eq 'foo'
|
152
|
+
end
|
153
|
+
|
154
|
+
end
|
155
|
+
|
156
|
+
context 'no tenant has been established' do
|
157
|
+
|
158
|
+
it 'rises an error' do
|
159
|
+
ActiveRecord::Base.motel.current_tenant = nil
|
160
|
+
|
161
|
+
expect{ActiveRecord::Base.current_tenant}.to raise_error Motel::NoCurrentTenantError
|
162
|
+
end
|
163
|
+
|
164
|
+
end
|
165
|
+
|
166
|
+
end
|
167
|
+
|
168
|
+
end
|
169
|
+
|
@@ -0,0 +1,246 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Motel::Sources::Database do
|
4
|
+
|
5
|
+
before(:all) do
|
6
|
+
@klass = Class.new(ActiveRecord::Base) { def self.name; 'klass'; end }
|
7
|
+
|
8
|
+
resolver = ActiveRecord::ConnectionAdapters::ConnectionSpecification::Resolver.new(TENANTS_SPEC, nil)
|
9
|
+
@handler = ActiveRecord::ConnectionAdapters::ConnectionHandler.new
|
10
|
+
@handler.establish_connection(@klass, resolver.spec)
|
11
|
+
|
12
|
+
@table_name = 'tenant'
|
13
|
+
@tenants_source = Motel::Sources::Database.new(
|
14
|
+
source_spec: TENANTS_SPEC, table_name: @table_name
|
15
|
+
)
|
16
|
+
|
17
|
+
@tenant_table_sql = <<-SQL
|
18
|
+
CREATE TABLE #{@table_name}(
|
19
|
+
`name` VARCHAR PRIMARY KEY,
|
20
|
+
`adapter` VARCHAR,
|
21
|
+
`socket` VARCHAR,
|
22
|
+
`port` INTEGER,
|
23
|
+
`pool` INTEGER,
|
24
|
+
`host` VARCHAR,
|
25
|
+
`username` VARCHAR,
|
26
|
+
`password` VARCHAR,
|
27
|
+
`database` VARCHAR,
|
28
|
+
`url` VARCHAR
|
29
|
+
)
|
30
|
+
SQL
|
31
|
+
end
|
32
|
+
|
33
|
+
before(:all) do
|
34
|
+
@handler.retrieve_connection_pool(@klass).with_connection do |conn|
|
35
|
+
conn.execute(@tenant_table_sql)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
before (:each) do
|
40
|
+
@foo_tenant_sql = <<-SQL
|
41
|
+
INSERT INTO #{@table_name}(`name`, `adapter`, `database`)
|
42
|
+
VALUES ("foo", "#{FOO_SPEC['adapter']}", "#{FOO_SPEC['database']}")
|
43
|
+
SQL
|
44
|
+
|
45
|
+
@bar_tenant_sql = <<-SQL
|
46
|
+
INSERT INTO #{@table_name}(`name`, `adapter`, `database`)
|
47
|
+
VALUES ("bar", "#{BAR_SPEC['adapter']}", "#{BAR_SPEC['database']}")
|
48
|
+
SQL
|
49
|
+
|
50
|
+
@handler.retrieve_connection_pool(@klass).with_connection do |conn|
|
51
|
+
conn.execute(@foo_tenant_sql)
|
52
|
+
conn.execute(@bar_tenant_sql)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
after(:each) do
|
57
|
+
@handler.retrieve_connection_pool(@klass).with_connection do |conn|
|
58
|
+
conn.execute("DELETE FROM #{@table_name}")
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
after(:all) do
|
63
|
+
@handler.retrieve_connection_pool(@klass).with_connection do |conn|
|
64
|
+
conn.execute("DROP TABLE #{@table_name}")
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
describe '#tenants' do
|
69
|
+
|
70
|
+
it 'there are only two tenants' do
|
71
|
+
expect(@tenants_source.tenants.count).to eq 2
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'exist foo key' do
|
75
|
+
expect(@tenants_source.tenants.key?('foo')).to be_true
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'tenant foo has a correct spec' do
|
79
|
+
expect(@tenants_source.tenants['foo']['adapter']).to eq FOO_SPEC['adapter']
|
80
|
+
expect(@tenants_source.tenants['foo']['database']).to eq FOO_SPEC['database']
|
81
|
+
end
|
82
|
+
|
83
|
+
it 'exist bar key' do
|
84
|
+
expect(@tenants_source.tenants.key?('bar')).to be_true
|
85
|
+
end
|
86
|
+
|
87
|
+
it 'tenant bar has a correct spec' do
|
88
|
+
expect(@tenants_source.tenants['bar']['adapter']).to eq BAR_SPEC['adapter']
|
89
|
+
expect(@tenants_source.tenants['bar']['database']).to eq BAR_SPEC['database']
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
93
|
+
|
94
|
+
describe '#tenant' do
|
95
|
+
|
96
|
+
context 'existing tenant' do
|
97
|
+
|
98
|
+
it 'tenant foo has a correct spec' do
|
99
|
+
expect(@tenants_source.tenant('foo')['adapter']).to eq FOO_SPEC['adapter']
|
100
|
+
expect(@tenants_source.tenant('foo')['database']).to eq FOO_SPEC['database']
|
101
|
+
end
|
102
|
+
|
103
|
+
end
|
104
|
+
|
105
|
+
context 'nonexistent tenant' do
|
106
|
+
|
107
|
+
it 'returns null' do
|
108
|
+
expect(@tenants_source.tenant('baz')).to be_nil
|
109
|
+
end
|
110
|
+
|
111
|
+
end
|
112
|
+
|
113
|
+
end
|
114
|
+
|
115
|
+
describe '#tenant?' do
|
116
|
+
|
117
|
+
it 'returns true if tenant does exist' do
|
118
|
+
expect(@tenants_source.tenant?('foo')).to be_true
|
119
|
+
end
|
120
|
+
|
121
|
+
it 'returns false if tenant does not exist' do
|
122
|
+
expect(@tenants_source.tenant?('baz')).to be_false
|
123
|
+
end
|
124
|
+
|
125
|
+
end
|
126
|
+
|
127
|
+
describe '#add_tenant' do
|
128
|
+
|
129
|
+
context 'existing tenant' do
|
130
|
+
|
131
|
+
it 'raise an error' do
|
132
|
+
expect{
|
133
|
+
@tenants_source.add_tenant('foo', FOO_SPEC)
|
134
|
+
}.to raise_error Motel::ExistingTenantError
|
135
|
+
end
|
136
|
+
|
137
|
+
end
|
138
|
+
|
139
|
+
context 'nonexistent tenant' do
|
140
|
+
|
141
|
+
context 'spec has keys as strings' do
|
142
|
+
|
143
|
+
it 'add new tenant to database' do
|
144
|
+
@tenants_source.add_tenant(
|
145
|
+
'baz', {'adapter' => BAZ_SPEC['adapter'], 'database' => BAZ_SPEC['database']}
|
146
|
+
)
|
147
|
+
|
148
|
+
result = @handler.retrieve_connection_pool(@klass).with_connection do |conn|
|
149
|
+
conn.select_all("SELECT * FROM #{@table_name} WHERE `name` = 'baz'")
|
150
|
+
end
|
151
|
+
|
152
|
+
expect(result.first['adapter']).to eq BAZ_SPEC['adapter']
|
153
|
+
expect(result.first['database']).to eq BAZ_SPEC['database']
|
154
|
+
end
|
155
|
+
|
156
|
+
end
|
157
|
+
|
158
|
+
context 'spec has keys as symbols' do
|
159
|
+
|
160
|
+
it 'add new tenant to database' do
|
161
|
+
@tenants_source.add_tenant(
|
162
|
+
'baz', {adapter: BAZ_SPEC['adapter'] , database: BAZ_SPEC['database']}
|
163
|
+
)
|
164
|
+
|
165
|
+
result = @handler.retrieve_connection_pool(@klass).with_connection do |conn|
|
166
|
+
conn.select_all("SELECT * FROM #{@table_name} WHERE `name` = 'baz'")
|
167
|
+
end
|
168
|
+
|
169
|
+
expect(result.first['adapter']).to eq BAZ_SPEC['adapter']
|
170
|
+
expect(result.first['database']).to eq BAZ_SPEC['database']
|
171
|
+
end
|
172
|
+
|
173
|
+
end
|
174
|
+
|
175
|
+
end
|
176
|
+
|
177
|
+
end
|
178
|
+
|
179
|
+
describe '#update_tenant' do
|
180
|
+
|
181
|
+
context 'existing tenant' do
|
182
|
+
|
183
|
+
context 'full update' do
|
184
|
+
|
185
|
+
it 'update tenant in the database' do
|
186
|
+
@tenants_source.update_tenant(
|
187
|
+
'foo', {adapter: 'mysql2', database: 'foo'}
|
188
|
+
)
|
189
|
+
|
190
|
+
result = @handler.retrieve_connection_pool(@klass).with_connection do |conn|
|
191
|
+
conn.select_all("SELECT * FROM #{@table_name} WHERE `name` = 'foo'")
|
192
|
+
end
|
193
|
+
|
194
|
+
expect(result.first['adapter']).to eq 'mysql2'
|
195
|
+
expect(result.first['database']).to eq 'foo'
|
196
|
+
end
|
197
|
+
|
198
|
+
end
|
199
|
+
|
200
|
+
context 'partial update' do
|
201
|
+
|
202
|
+
it 'update tenant in the database' do
|
203
|
+
@tenants_source.update_tenant(
|
204
|
+
'foo', {adapter: 'mysql2'}
|
205
|
+
)
|
206
|
+
|
207
|
+
result = @handler.retrieve_connection_pool(@klass).with_connection do |conn|
|
208
|
+
conn.select_all("SELECT * FROM #{@table_name} WHERE `name` = 'foo'")
|
209
|
+
end
|
210
|
+
|
211
|
+
expect(result.first['adapter']).to eq 'mysql2'
|
212
|
+
expect(result.first['database']).to eq FOO_SPEC['database']
|
213
|
+
end
|
214
|
+
|
215
|
+
end
|
216
|
+
|
217
|
+
end
|
218
|
+
|
219
|
+
context 'nonexistent tenant' do
|
220
|
+
|
221
|
+
it 'raise an error' do
|
222
|
+
expect{
|
223
|
+
@tenants_source.update_tenant('baz', {})
|
224
|
+
}.to raise_error Motel::NonexistentTenantError
|
225
|
+
end
|
226
|
+
|
227
|
+
end
|
228
|
+
|
229
|
+
end
|
230
|
+
|
231
|
+
describe '#delete_tenant' do
|
232
|
+
|
233
|
+
it 'remove tenant from redis server' do
|
234
|
+
@tenants_source.delete_tenant('foo')
|
235
|
+
|
236
|
+
result = @handler.retrieve_connection_pool(@klass).with_connection do |conn|
|
237
|
+
conn.select_all("SELECT * FROM #{@table_name} WHERE `name` = 'foo'")
|
238
|
+
end
|
239
|
+
|
240
|
+
expect(result.count).to eq 0
|
241
|
+
end
|
242
|
+
|
243
|
+
end
|
244
|
+
|
245
|
+
end
|
246
|
+
|