apartment 2.0.0 → 2.1.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
  SHA1:
3
- metadata.gz: b431585840ff2cba38b0280bc2a4ee7e6460a089
4
- data.tar.gz: 3f7679220b8adcf6ad0f832c70d5d2ea82ccc3c6
3
+ metadata.gz: 6db463e2bcd7fcb50414759a87c1b77ccb959e04
4
+ data.tar.gz: c614f5ba93fd4e5e779f07a08aaafa4118bd5025
5
5
  SHA512:
6
- metadata.gz: 2f41b445022a6ec41ba6a34f2cbc3d5a086be9495972f8e5af8ab557168a9e649c74d76299a5043739cd2048f2a625701eeb47ea702a70857b6c18bab54a7648
7
- data.tar.gz: cf3fd76a826a36b3a7b0b4a51bf5d68dc34624a830ddc8a2e13d9e7a2f88cd03e5541c0d53863bccffb14f97cd81c5bdd131943cf5b1918495cc86a83a527e44
6
+ metadata.gz: 3bacabc90c5c61c06b266bfa9bfb4d0cf0f3dedfcdba36362894848b065a5bcd6b174badf9d696a97aeadb7589d2063c3e28ef6249ec54bae721fa7914538fbc
7
+ data.tar.gz: b2a1c68f71969fd0e87bc0cfaebdcfd7f99ca54a5e815c2ae6dce17ab165c6352aa64624a29cad9311dd03925795c298828f35179448153d334f8a0c87b50469
@@ -0,0 +1,21 @@
1
+ ## Steps to reproduce
2
+
3
+ ## Expected behavior
4
+
5
+ ## Actual behavior
6
+
7
+ ## System configuration
8
+
9
+ <!-- Please let us know as far as you can. -->
10
+
11
+ * Database: (Tell us what database and its version you use.)
12
+
13
+ * Apartment version:
14
+
15
+ * Apartment config (in `config/initializers/apartment.rb` or so):
16
+
17
+ * `use_schemas`: (`true` or `false`)
18
+
19
+ * Rails (or ActiveRecord) version:
20
+
21
+ * Ruby version:
@@ -1,6 +1,5 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 2.0.0
4
3
  - 2.1.9
5
4
  - 2.2.4
6
5
  - 2.3.1
@@ -26,12 +25,6 @@ matrix:
26
25
  - rvm: ruby-head
27
26
  - gemfile: gemfiles/rails_master.gemfile
28
27
  exclude:
29
- - rvm: 2.0.0
30
- gemfile: gemfiles/rails_5_0.gemfile
31
- - rvm: 2.0.0
32
- gemfile: gemfiles/rails_5_1.gemfile
33
- - rvm: 2.0.0
34
- gemfile: gemfiles/rails_master.gemfile
35
28
  - rvm: 2.1.9
36
29
  gemfile: gemfiles/rails_5_0.gemfile
37
30
  - rvm: 2.1.9
@@ -46,6 +39,8 @@ matrix:
46
39
  gemfile: gemfiles/rails_4_0.gemfile
47
40
  - rvm: ruby-head
48
41
  gemfile: gemfiles/rails_4_1.gemfile
42
+ - rvm: jruby-9.0.5.0
43
+ gemfile: gemfiles/rails_4_0.gemfile
49
44
  - rvm: jruby-9.0.5.0
50
45
  gemfile: gemfiles/rails_4_2.gemfile
51
46
  - rvm: jruby-9.0.5.0
@@ -54,6 +49,8 @@ matrix:
54
49
  gemfile: gemfiles/rails_5_1.gemfile
55
50
  - rvm: jruby-9.0.5.0
56
51
  gemfile: gemfiles/rails_master.gemfile
52
+ - rvm: jruby-9.1.9.0
53
+ gemfile: gemfiles/rails_4_0.gemfile
57
54
  - rvm: jruby-9.1.9.0
58
55
  gemfile: gemfiles/rails_5_0.gemfile
59
56
  - rvm: jruby-9.1.9.0
data/HISTORY.md CHANGED
@@ -1,3 +1,8 @@
1
+ # 2.1.0
2
+ * December 15, 2017
3
+
4
+ - Enhance db:drop task to act on all tenants [kuzukuzu]
5
+
1
6
  # 2.0.0
2
7
  * July 26, 2017
3
8
 
data/README.md CHANGED
@@ -94,12 +94,17 @@ One can optionally use the full database creation instead if they want, though t
94
94
  To switch tenants using Apartment, use the following command:
95
95
 
96
96
  ```ruby
97
- Apartment::Tenant.switch!('tenant_name')
97
+ Apartment::Tenant.switch('tenant_name') do
98
+ # ...
99
+ end
98
100
  ```
99
101
 
100
102
  When switch is called, all requests coming to ActiveRecord will be routed to the tenant
101
- you specify (with the exception of excluded models, see below). To return to the 'root'
102
- tenant, call switch with no arguments.
103
+ you specify (with the exception of excluded models, see below). The tenant is automatically
104
+ switched back at the end of the block to what it was before.
105
+
106
+ There is also `switch!` which doesn't take a block, but it's recommended to use `switch`.
107
+ To return to the default tenant, you can call `switch` with no arguments.
103
108
 
104
109
  ### Switching Tenants per request
105
110
 
@@ -117,7 +122,7 @@ manually in your `application.rb` like so
117
122
 
118
123
  ```ruby
119
124
  # config/application.rb
120
- require 'apartment/elevators/subdomain' # or 'domain' or 'generic'
125
+ require 'apartment/elevators/subdomain' # or 'domain', 'first_subdomain', 'host'
121
126
  ```
122
127
 
123
128
  #### Switch on subdomain
@@ -155,7 +160,7 @@ module MyApplication
155
160
  end
156
161
  ```
157
162
 
158
- If you want to exclude a domain, for example if you don't want your application to treate www like a subdomain, in an initializer in your application, you can set the following:
163
+ If you want to exclude a domain, for example if you don't want your application to treat www like a subdomain, in an initializer in your application, you can set the following:
159
164
 
160
165
  ```ruby
161
166
  # config/initializers/apartment/subdomain_exclusions.rb
@@ -166,7 +171,7 @@ This functions much in the same way as the Subdomain elevator. **NOTE:** in fact
166
171
 
167
172
  #### Switch on domain
168
173
 
169
- To switch based on full domain (excluding subdomains *ie 'www'* and top level domains *ie '.com'* ) use the following:
174
+ To switch based on full domain (excluding the 'www' subdomains and top level domains *ie '.com'* ) use the following:
170
175
 
171
176
  ```ruby
172
177
  # application.rb
@@ -177,6 +182,11 @@ module MyApplication
177
182
  end
178
183
  ```
179
184
 
185
+ Note that if you have several subdomains, then it will match on the first *non-www* subdomain:
186
+ - example.com => example
187
+ - www.example.com => example
188
+ - a.example.com => a
189
+
180
190
  #### Switch on full host using a hash
181
191
 
182
192
  To switch based on full host with a hash to find corresponding tenant name use the following:
@@ -190,6 +200,31 @@ module MyApplication
190
200
  end
191
201
  ```
192
202
 
203
+ #### Switch on full host, ignoring given first subdomains
204
+
205
+ To switch based on full host to find corresponding tenant name use the following:
206
+
207
+ ```ruby
208
+ # application.rb
209
+ module MyApplication
210
+ class Application < Rails::Application
211
+ config.middleware.use Apartment::Elevators::Host
212
+ end
213
+ end
214
+ ```
215
+
216
+ If you want to exclude a first-subdomain, for example if you don't want your application to include www in the matching, in an initializer in your application, you can set the following:
217
+
218
+ ```ruby
219
+ Apartment::Elevators::Host.ignored_first_subdomains = ['www']
220
+ ```
221
+
222
+ With the above set, these would be the results:
223
+ - example.com => example.com
224
+ - www.example.com => example.com
225
+ - a.example.com => a.example.com
226
+ - www.a.example.com => a.example.com
227
+
193
228
  #### Custom Elevator
194
229
 
195
230
  A Generic Elevator exists that allows you to pass a `Proc` (or anything that responds to `call`) to the middleware. This Object will be passed in an `ActionDispatch::Request` object when called for you to do your magic. Apartment will use the return value of this proc to switch to the appropriate tenant. Use like so:
@@ -244,7 +279,7 @@ This works okay for simple applications, but it's important to consider that you
244
279
  To resolve this issue, consider adding the Apartment middleware at a location in the Rack stack that makes sense for your needs, e.g.:
245
280
 
246
281
  ```ruby
247
- Rails.application.config.middleware.insert_before 'Warden::Manager', 'Apartment::Elevators::Subdomain'
282
+ Rails.application.config.middleware.insert_before Warden::Manager, Apartment::Elevators::Subdomain
248
283
  ```
249
284
 
250
285
  Now work done in the Warden middleware is wrapped in the `Apartment::Tenant.switch` context started in the Generic elevator.
@@ -342,6 +377,8 @@ namespace :db do
342
377
  ActiveRecord::Base.connection.execute 'CREATE EXTENSION IF NOT EXISTS HSTORE SCHEMA shared_extensions;'
343
378
  # Enable UUID-OSSP
344
379
  ActiveRecord::Base.connection.execute 'CREATE EXTENSION IF NOT EXISTS "uuid-ossp" SCHEMA shared_extensions;'
380
+ # Grant usage to public
381
+ ActiveRecord::Base.connection.execute 'GRANT usage ON SCHEMA shared_extensions to public;'
345
382
  end
346
383
  end
347
384
 
@@ -443,6 +480,17 @@ Note that you can disable the default migrating of all tenants with `db:migrate`
443
480
  `Apartment.db_migrate_tenants = false` in your `Rakefile`. Note this must be done
444
481
  *before* the rake tasks are loaded. ie. before `YourApp::Application.load_tasks` is called
445
482
 
483
+ #### Parallel Migrations
484
+
485
+ Apartment supports parallelizing migrations into multiple threads when
486
+ you have a large number of tenants. By default, parallel migrations is
487
+ turned off. You can enable this by setting `parallel_migration_threads` to
488
+ the number of threads you want to use in your initializer.
489
+
490
+ Keep in mind that because migrations are going to access the database,
491
+ the number of threads indicated here should be less than the pool size
492
+ that Rails will use to connect to your database.
493
+
446
494
  ### Handling Environments
447
495
 
448
496
  By default, when not using postgresql schemas, Apartment will prepend the environment to the tenant name
@@ -481,9 +529,9 @@ config.tenant_names = lambda do
481
529
  end
482
530
  ```
483
531
 
484
- ## Delayed::Job
532
+ ## Background workers
485
533
 
486
- Has been removed. See [apartment-sidekiq](https://github.com/influitive/apartment-sidekiq) for a better backgrounding experience.
534
+ See [apartment-sidekiq](https://github.com/influitive/apartment-sidekiq) or [apartment-activejob](https://github.com/influitive/apartment-activejob).
487
535
 
488
536
  ## Contributing
489
537
 
@@ -21,7 +21,8 @@ Gem::Specification.new do |s|
21
21
  # must be >= 3.1.2 due to bug in prepared_statements
22
22
  s.add_dependency 'activerecord', '>= 3.1.2', '< 6.0'
23
23
  s.add_dependency 'rack', '>= 1.3.6'
24
- s.add_dependency 'public_suffix', '~> 2.0.5'
24
+ s.add_dependency 'public_suffix', '>= 2'
25
+ s.add_dependency 'parallel', '>= 0.7.1'
25
26
 
26
27
  s.add_development_dependency 'appraisal'
27
28
  s.add_development_dependency 'rake', '~> 0.9'
@@ -41,9 +42,4 @@ Gem::Specification.new do |s|
41
42
  s.add_development_dependency 'pg', '>= 0.11.0'
42
43
  s.add_development_dependency 'sqlite3'
43
44
  end
44
-
45
- if RUBY_VERSION < '2.1.0'
46
- # capybara depends on xpath depends on nokogiri
47
- s.add_development_dependency 'nokogiri', '< 1.7.0'
48
- end
49
45
  end
@@ -11,7 +11,7 @@ module Apartment
11
11
  extend Forwardable
12
12
 
13
13
  ACCESSOR_METHODS = [:use_schemas, :use_sql, :seed_after_create, :prepend_environment, :append_environment, :with_multi_server_setup ]
14
- WRITER_METHODS = [:tenant_names, :database_schema_file, :excluded_models, :default_schema, :persistent_schemas, :connection_class, :tld_length, :db_migrate_tenants, :seed_data_file]
14
+ WRITER_METHODS = [:tenant_names, :database_schema_file, :excluded_models, :default_schema, :persistent_schemas, :connection_class, :tld_length, :db_migrate_tenants, :seed_data_file, :parallel_migration_threads]
15
15
 
16
16
  attr_accessor(*ACCESSOR_METHODS)
17
17
  attr_writer(*WRITER_METHODS)
@@ -51,6 +51,10 @@ module Apartment
51
51
  def default_schema
52
52
  @default_schema || "public" # TODO 'public' is postgres specific
53
53
  end
54
+
55
+ def parallel_migration_threads
56
+ @parallel_migration_threads || 0
57
+ end
54
58
  alias :default_tenant :default_schema
55
59
  alias :default_tenant= :default_schema=
56
60
 
@@ -106,8 +106,9 @@ module Apartment
106
106
  class PostgresqlSchemaFromSqlAdapter < PostgresqlSchemaAdapter
107
107
 
108
108
  PSQL_DUMP_BLACKLISTED_STATEMENTS= [
109
- /SET search_path/i, # overridden later
110
- /SET lock_timeout/i, # new in postgresql 9.3
109
+ /SET search_path/i, # overridden later
110
+ /SET lock_timeout/i, # new in postgresql 9.3
111
+ /SET row_security/i, # new in postgresql 9.5
111
112
  /SET idle_in_transaction_session_timeout/i, # new in postgresql 9.6
112
113
  ]
113
114
 
@@ -4,9 +4,11 @@ module Apartment
4
4
  module Elevators
5
5
  # Provides a rack based tenant switching solution based on domain
6
6
  # Assumes that tenant name should match domain
7
- # Parses request host for second level domain
7
+ # Parses request host for second level domain, ignoring www
8
8
  # eg. example.com => example
9
9
  # www.example.bc.ca => example
10
+ # a.example.bc.ca => a
11
+ #
10
12
  #
11
13
  class Domain < Generic
12
14
 
@@ -0,0 +1,30 @@
1
+ require 'apartment/elevators/generic'
2
+
3
+ module Apartment
4
+ module Elevators
5
+ # Provides a rack based tenant switching solution based on the host
6
+ # Assumes that tenant name should match host
7
+ # Strips/ignores first subdomains in ignored_first_subdomains
8
+ # eg. example.com => example.com
9
+ # www.example.bc.ca => www.example.bc.ca
10
+ # if ignored_first_subdomains = ['www']
11
+ # www.example.bc.ca => example.bc.ca
12
+ # www.a.b.c.d.com => a.b.c.d.com
13
+ #
14
+ class Host < Generic
15
+ def self.ignored_first_subdomains
16
+ @ignored_first_subdomains ||= []
17
+ end
18
+
19
+ def self.ignored_first_subdomains=(arg)
20
+ @ignored_first_subdomains = arg
21
+ end
22
+
23
+ def parse_tenant_name(request)
24
+ return nil if request.host.blank?
25
+ parts = request.host.split('.')
26
+ self.class.ignored_first_subdomains.include?(parts[0]) ? parts.drop(1).join('.') : request.host
27
+ end
28
+ end
29
+ end
30
+ end
@@ -55,7 +55,7 @@ module Apartment
55
55
  end
56
56
 
57
57
  def parse_host(host)
58
- (PublicSuffix.parse(host).trd || '').split('.')
58
+ (PublicSuffix.parse(host, ignore_private: true).trd || '').split('.')
59
59
  end
60
60
  end
61
61
  end
@@ -3,33 +3,54 @@
3
3
 
4
4
  module Apartment
5
5
  class RakeTaskEnhancer
6
-
7
- TASKS = %w(db:migrate db:rollback db:migrate:up db:migrate:down db:migrate:redo db:seed)
8
-
6
+
7
+ module TASKS
8
+ ENHANCE_BEFORE = %w(db:drop)
9
+ ENHANCE_AFTER = %w(db:migrate db:rollback db:migrate:up db:migrate:down db:migrate:redo db:seed)
10
+ freeze
11
+ end
12
+
9
13
  # This is a bit convoluted, but helps solve problems when using Apartment within an engine
10
14
  # See spec/integration/use_within_an_engine.rb
11
-
15
+
12
16
  class << self
13
17
  def enhance!
14
- TASKS.each do |name|
18
+ return unless should_enhance?
19
+
20
+ # insert task before
21
+ TASKS::ENHANCE_BEFORE.each do |name|
15
22
  task = Rake::Task[name]
16
- task.enhance do
17
- if should_enhance?
18
- enhance_task(task)
19
- end
20
- end
23
+ enhance_before_task(task)
21
24
  end
25
+
26
+ # insert task after
27
+ TASKS::ENHANCE_AFTER.each do |name|
28
+ task = Rake::Task[name]
29
+ enhance_after_task(task)
30
+ end
31
+
22
32
  end
23
-
33
+
24
34
  def should_enhance?
25
35
  Apartment.db_migrate_tenants
26
36
  end
27
-
28
- def enhance_task(task)
29
- Rake::Task[task.name.sub(/db:/, 'apartment:')].invoke
37
+
38
+ def enhance_before_task(task)
39
+ task.enhance([inserted_task_name(task)])
40
+ end
41
+
42
+ def enhance_after_task(task)
43
+ task.enhance do
44
+ Rake::Task[inserted_task_name(task)].invoke
45
+ end
30
46
  end
47
+
48
+ def inserted_task_name(task)
49
+ task.name.sub(/db:/, 'apartment:')
50
+ end
51
+
31
52
  end
32
-
53
+
33
54
  end
34
55
  end
35
56
 
@@ -1,3 +1,3 @@
1
1
  module Apartment
2
- VERSION = "2.0.0"
2
+ VERSION = "2.1.0"
3
3
  end
@@ -6,6 +6,7 @@
6
6
  # require 'apartment/elevators/domain'
7
7
  require 'apartment/elevators/subdomain'
8
8
  # require 'apartment/elevators/first_subdomain'
9
+ # require 'apartment/elevators/host'
9
10
 
10
11
  #
11
12
  # Apartment Configuration
@@ -95,3 +96,4 @@ end
95
96
  # Rails.application.config.middleware.use Apartment::Elevators::Domain
96
97
  Rails.application.config.middleware.use Apartment::Elevators::Subdomain
97
98
  # Rails.application.config.middleware.use Apartment::Elevators::FirstSubdomain
99
+ # Rails.application.config.middleware.use Apartment::Elevators::Host
@@ -1,4 +1,5 @@
1
1
  require 'apartment/migrator'
2
+ require 'parallel'
2
3
 
3
4
  apartment_namespace = namespace :apartment do
4
5
 
@@ -14,10 +15,22 @@ apartment_namespace = namespace :apartment do
14
15
  end
15
16
  end
16
17
 
18
+ desc "Drop all tenants"
19
+ task :drop do
20
+ tenants.each do |tenant|
21
+ begin
22
+ puts("Dropping #{tenant} tenant")
23
+ Apartment::Tenant.drop(tenant)
24
+ rescue Apartment::TenantNotFound => e
25
+ puts e.message
26
+ end
27
+ end
28
+ end
29
+
17
30
  desc "Migrate all tenants"
18
31
  task :migrate do
19
32
  warn_if_tenants_empty
20
- tenants.each do |tenant|
33
+ each_tenant do |tenant|
21
34
  begin
22
35
  puts("Migrating #{tenant} tenant")
23
36
  Apartment::Migrator.migrate tenant
@@ -31,7 +44,7 @@ apartment_namespace = namespace :apartment do
31
44
  task :seed do
32
45
  warn_if_tenants_empty
33
46
 
34
- tenants.each do |tenant|
47
+ each_tenant do |tenant|
35
48
  begin
36
49
  puts("Seeding #{tenant} tenant")
37
50
  Apartment::Tenant.switch(tenant) do
@@ -49,7 +62,7 @@ apartment_namespace = namespace :apartment do
49
62
 
50
63
  step = ENV['STEP'] ? ENV['STEP'].to_i : 1
51
64
 
52
- tenants.each do |tenant|
65
+ each_tenant do |tenant|
53
66
  begin
54
67
  puts("Rolling back #{tenant} tenant")
55
68
  Apartment::Migrator.rollback tenant, step
@@ -67,7 +80,7 @@ apartment_namespace = namespace :apartment do
67
80
  version = ENV['VERSION'] ? ENV['VERSION'].to_i : nil
68
81
  raise 'VERSION is required' unless version
69
82
 
70
- tenants.each do |tenant|
83
+ each_tenant do |tenant|
71
84
  begin
72
85
  puts("Migrating #{tenant} tenant up")
73
86
  Apartment::Migrator.run :up, tenant, version
@@ -84,7 +97,7 @@ apartment_namespace = namespace :apartment do
84
97
  version = ENV['VERSION'] ? ENV['VERSION'].to_i : nil
85
98
  raise 'VERSION is required' unless version
86
99
 
87
- tenants.each do |tenant|
100
+ each_tenant do |tenant|
88
101
  begin
89
102
  puts("Migrating #{tenant} tenant down")
90
103
  Apartment::Migrator.run :down, tenant, version
@@ -106,6 +119,12 @@ apartment_namespace = namespace :apartment do
106
119
  end
107
120
  end
108
121
 
122
+ def each_tenant(&block)
123
+ Parallel.each(tenants, in_threads: Apartment.parallel_migration_threads) do |tenant|
124
+ block.call(tenant)
125
+ end
126
+ end
127
+
109
128
  def tenants
110
129
  ENV['DB'] ? ENV['DB'].split(',').map { |s| s.strip } : Apartment.tenant_names || []
111
130
  end
@@ -1,6 +1,7 @@
1
1
  require 'spec_helper'
2
2
  require 'rake'
3
3
  require 'apartment/migrator'
4
+ require 'apartment/tenant'
4
5
 
5
6
  describe "apartment rake tasks" do
6
7
 
@@ -116,5 +117,13 @@ describe "apartment rake tasks" do
116
117
  @rake['apartment:rollback'].invoke
117
118
  end
118
119
  end
120
+
121
+ describe "apartment:drop" do
122
+ it "should migrate public and all multi-tenant dbs" do
123
+ expect(Apartment::Tenant).to receive(:drop).exactly(tenant_count).times
124
+ @rake['apartment:drop'].invoke
125
+ end
126
+ end
127
+
119
128
  end
120
129
  end
@@ -0,0 +1,89 @@
1
+ require 'spec_helper'
2
+ require 'apartment/elevators/host'
3
+
4
+ describe Apartment::Elevators::Host do
5
+
6
+ subject(:elevator){ described_class.new(Proc.new{}) }
7
+
8
+ describe "#parse_tenant_name" do
9
+
10
+ it "should return nil when no host" do
11
+ request = ActionDispatch::Request.new('HTTP_HOST' => '')
12
+ expect(elevator.parse_tenant_name(request)).to be_nil
13
+ end
14
+
15
+ context "assuming no ignored_first_subdomains" do
16
+ before { allow(described_class).to receive(:ignored_first_subdomains).and_return([]) }
17
+
18
+ context "with 3 parts" do
19
+ it "should return the whole host" do
20
+ request = ActionDispatch::Request.new('HTTP_HOST' => 'foo.bar.com')
21
+ expect(elevator.parse_tenant_name(request)).to eq('foo.bar.com')
22
+ end
23
+ end
24
+
25
+ context "with 6 parts" do
26
+ it "should return the whole host" do
27
+ request = ActionDispatch::Request.new('HTTP_HOST' => 'one.two.three.foo.bar.com')
28
+ expect(elevator.parse_tenant_name(request)).to eq('one.two.three.foo.bar.com')
29
+ end
30
+ end
31
+ end
32
+
33
+ context "assuming ignored_first_subdomains is set" do
34
+ before { allow(described_class).to receive(:ignored_first_subdomains).and_return(%w{www foo}) }
35
+
36
+ context "with 3 parts" do
37
+ it "should return host without www" do
38
+ request = ActionDispatch::Request.new('HTTP_HOST' => 'www.bar.com')
39
+ expect(elevator.parse_tenant_name(request)).to eq('bar.com')
40
+ end
41
+
42
+ it "should return host without foo" do
43
+ request = ActionDispatch::Request.new('HTTP_HOST' => 'foo.bar.com')
44
+ expect(elevator.parse_tenant_name(request)).to eq('bar.com')
45
+ end
46
+ end
47
+
48
+ context "with 6 parts" do
49
+ it "should return host without www" do
50
+ request = ActionDispatch::Request.new('HTTP_HOST' => 'www.one.two.three.foo.bar.com')
51
+ expect(elevator.parse_tenant_name(request)).to eq('one.two.three.foo.bar.com')
52
+ end
53
+
54
+ it "should return host without www" do
55
+ request = ActionDispatch::Request.new('HTTP_HOST' => 'foo.one.two.three.bar.com')
56
+ expect(elevator.parse_tenant_name(request)).to eq('one.two.three.bar.com')
57
+ end
58
+ end
59
+ end
60
+
61
+ context "assuming localhost" do
62
+ it "should return localhost" do
63
+ request = ActionDispatch::Request.new('HTTP_HOST' => 'localhost')
64
+ expect(elevator.parse_tenant_name(request)).to eq('localhost')
65
+ end
66
+ end
67
+
68
+ context "assuming ip address" do
69
+ it "should return the ip address" do
70
+ request = ActionDispatch::Request.new('HTTP_HOST' => '127.0.0.1')
71
+ expect(elevator.parse_tenant_name(request)).to eq('127.0.0.1')
72
+ end
73
+ end
74
+ end
75
+
76
+ describe "#call" do
77
+ it "switches to the proper tenant" do
78
+ allow(described_class).to receive(:ignored_first_subdomains).and_return([])
79
+ expect(Apartment::Tenant).to receive(:switch).with('foo.bar.com')
80
+ elevator.call('HTTP_HOST' => 'foo.bar.com')
81
+ end
82
+
83
+ it "ignores ignored_first_subdomains" do
84
+ allow(described_class).to receive(:ignored_first_subdomains).and_return(%w{foo})
85
+ expect(Apartment::Tenant).to receive(:switch).with('bar.com')
86
+ elevator.call('HTTP_HOST' => 'foo.bar.com')
87
+ end
88
+ end
89
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: apartment
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryan Brunner
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2017-08-22 00:00:00.000000000 Z
12
+ date: 2017-12-15 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activerecord
@@ -49,16 +49,30 @@ dependencies:
49
49
  name: public_suffix
50
50
  requirement: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - "~>"
52
+ - - ">="
53
53
  - !ruby/object:Gem::Version
54
- version: 2.0.5
54
+ version: '2'
55
55
  type: :runtime
56
56
  prerelease: false
57
57
  version_requirements: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - "~>"
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '2'
62
+ - !ruby/object:Gem::Dependency
63
+ name: parallel
64
+ requirement: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: 0.7.1
69
+ type: :runtime
70
+ prerelease: false
71
+ version_requirements: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
60
74
  - !ruby/object:Gem::Version
61
- version: 2.0.5
75
+ version: 0.7.1
62
76
  - !ruby/object:Gem::Dependency
63
77
  name: appraisal
64
78
  requirement: !ruby/object:Gem::Requirement
@@ -180,11 +194,10 @@ executables: []
180
194
  extensions: []
181
195
  extra_rdoc_files: []
182
196
  files:
197
+ - ".github/ISSUE_TEMPLATE.md"
183
198
  - ".gitignore"
184
199
  - ".pryrc"
185
200
  - ".rspec"
186
- - ".ruby-gemset"
187
- - ".ruby-version"
188
201
  - ".travis.yml"
189
202
  - Appraisals
190
203
  - Gemfile
@@ -215,6 +228,7 @@ files:
215
228
  - lib/apartment/elevators/domain.rb
216
229
  - lib/apartment/elevators/first_subdomain.rb
217
230
  - lib/apartment/elevators/generic.rb
231
+ - lib/apartment/elevators/host.rb
218
232
  - lib/apartment/elevators/host_hash.rb
219
233
  - lib/apartment/elevators/subdomain.rb
220
234
  - lib/apartment/migrator.rb
@@ -322,6 +336,7 @@ files:
322
336
  - spec/unit/elevators/first_subdomain_spec.rb
323
337
  - spec/unit/elevators/generic_spec.rb
324
338
  - spec/unit/elevators/host_hash_spec.rb
339
+ - spec/unit/elevators/host_spec.rb
325
340
  - spec/unit/elevators/subdomain_spec.rb
326
341
  - spec/unit/migrator_spec.rb
327
342
  - spec/unit/reloader_spec.rb
@@ -445,6 +460,7 @@ test_files:
445
460
  - spec/unit/elevators/first_subdomain_spec.rb
446
461
  - spec/unit/elevators/generic_spec.rb
447
462
  - spec/unit/elevators/host_hash_spec.rb
463
+ - spec/unit/elevators/host_spec.rb
448
464
  - spec/unit/elevators/subdomain_spec.rb
449
465
  - spec/unit/migrator_spec.rb
450
466
  - spec/unit/reloader_spec.rb
@@ -1 +0,0 @@
1
- apartment
@@ -1 +0,0 @@
1
- ruby-2.3