subdomain_router 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ lib/**/*.rb
2
+ bin/*
3
+ -
4
+ features/**/*.feature
5
+ LICENSE.txt
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm 1.9.3@subdomain_router --create
data/Gemfile ADDED
@@ -0,0 +1,16 @@
1
+ source 'http://rubygems.org'
2
+
3
+ gem 'rails'
4
+
5
+ group :development do
6
+ # SPECS
7
+ gem 'rspec'
8
+
9
+ # DOCS
10
+ gem 'yard'
11
+ gem 'redcarpet'
12
+
13
+ # DEVELOPMENT
14
+ gem 'bundler'
15
+ gem 'jeweler'
16
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,107 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ actionmailer (3.2.3)
5
+ actionpack (= 3.2.3)
6
+ mail (~> 2.4.4)
7
+ actionpack (3.2.3)
8
+ activemodel (= 3.2.3)
9
+ activesupport (= 3.2.3)
10
+ builder (~> 3.0.0)
11
+ erubis (~> 2.7.0)
12
+ journey (~> 1.0.1)
13
+ rack (~> 1.4.0)
14
+ rack-cache (~> 1.2)
15
+ rack-test (~> 0.6.1)
16
+ sprockets (~> 2.1.2)
17
+ activemodel (3.2.3)
18
+ activesupport (= 3.2.3)
19
+ builder (~> 3.0.0)
20
+ activerecord (3.2.3)
21
+ activemodel (= 3.2.3)
22
+ activesupport (= 3.2.3)
23
+ arel (~> 3.0.2)
24
+ tzinfo (~> 0.3.29)
25
+ activeresource (3.2.3)
26
+ activemodel (= 3.2.3)
27
+ activesupport (= 3.2.3)
28
+ activesupport (3.2.3)
29
+ i18n (~> 0.6)
30
+ multi_json (~> 1.0)
31
+ arel (3.0.2)
32
+ builder (3.0.0)
33
+ diff-lcs (1.1.3)
34
+ erubis (2.7.0)
35
+ git (1.2.5)
36
+ hike (1.2.1)
37
+ i18n (0.6.0)
38
+ jeweler (1.8.3)
39
+ bundler (~> 1.0)
40
+ git (>= 1.2.5)
41
+ rake
42
+ rdoc
43
+ journey (1.0.3)
44
+ json (1.6.6)
45
+ mail (2.4.4)
46
+ i18n (>= 0.4.0)
47
+ mime-types (~> 1.16)
48
+ treetop (~> 1.4.8)
49
+ mime-types (1.18)
50
+ multi_json (1.3.2)
51
+ polyglot (0.3.3)
52
+ rack (1.4.1)
53
+ rack-cache (1.2)
54
+ rack (>= 0.4)
55
+ rack-ssl (1.3.2)
56
+ rack
57
+ rack-test (0.6.1)
58
+ rack (>= 1.0)
59
+ rails (3.2.3)
60
+ actionmailer (= 3.2.3)
61
+ actionpack (= 3.2.3)
62
+ activerecord (= 3.2.3)
63
+ activeresource (= 3.2.3)
64
+ activesupport (= 3.2.3)
65
+ bundler (~> 1.0)
66
+ railties (= 3.2.3)
67
+ railties (3.2.3)
68
+ actionpack (= 3.2.3)
69
+ activesupport (= 3.2.3)
70
+ rack-ssl (~> 1.3.2)
71
+ rake (>= 0.8.7)
72
+ rdoc (~> 3.4)
73
+ thor (~> 0.14.6)
74
+ rake (0.9.2.2)
75
+ rdoc (3.12)
76
+ json (~> 1.4)
77
+ redcarpet (2.1.1)
78
+ rspec (2.9.0)
79
+ rspec-core (~> 2.9.0)
80
+ rspec-expectations (~> 2.9.0)
81
+ rspec-mocks (~> 2.9.0)
82
+ rspec-core (2.9.0)
83
+ rspec-expectations (2.9.1)
84
+ diff-lcs (~> 1.1.3)
85
+ rspec-mocks (2.9.0)
86
+ sprockets (2.1.2)
87
+ hike (~> 1.2)
88
+ rack (~> 1.0)
89
+ tilt (~> 1.1, != 1.3.0)
90
+ thor (0.14.6)
91
+ tilt (1.3.3)
92
+ treetop (1.4.10)
93
+ polyglot
94
+ polyglot (>= 0.3.1)
95
+ tzinfo (0.3.33)
96
+ yard (0.7.5)
97
+
98
+ PLATFORMS
99
+ ruby
100
+
101
+ DEPENDENCIES
102
+ bundler
103
+ jeweler
104
+ rails
105
+ redcarpet
106
+ rspec
107
+ yard
data/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2012 Tim Morgan
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,160 @@
1
+ Subdomain Router
2
+ ================
3
+
4
+ A Ruby on Rails addition that adds dynamic subdomain routing to your web app.
5
+
6
+ | | |
7
+ |:------------|:--------------------------------|
8
+ | **Author** | Tim Morgan |
9
+ | **Version** | 1.0 (Apr 20, 2012) |
10
+ | **License** | Released under the MIT license. |
11
+
12
+ About
13
+ -----
14
+
15
+ This gem consists of two components: A routing constraint that can be used in
16
+ your `routes.rb` file to limit certain endpoints to dynamic subdomains (or vice
17
+ versa), and a monkey-patch to the `url_for` method that allows it to
18
+ intelligently generate URLs with subdomains.
19
+
20
+ The most common use case for this is if you have each of your users choose a
21
+ subdomain when they sign up, and then you route to different user accounts based
22
+ on their subdomain. (Think Heroku for example.)
23
+
24
+ Sorry about the monkey-patching by the way. :( You should probably inspect the
25
+ patch closely if you are using any other `url_for` hooks.
26
+
27
+ ### Testing multiple subdomains in development
28
+
29
+ Typically in development you access your website by going to
30
+ "http://localhost:3000" (or perhaps "http://0.0.0.0:3000"). Neither of these
31
+ URLs is compatible with subdomains, however.
32
+
33
+ Fortunately there exists an easy solution that requires no changes to your
34
+ `/etc/hosts` file. The domain "lvh.me" points to 127.0.0.1, so by going to
35
+ "http://lvh.me:3000", you can access your local Rails instance. And it works
36
+ with subdomains: "http://custom.lvh.me:3000" will work just as well.
37
+
38
+ Installation
39
+ ------------
40
+
41
+ ### Gem installation
42
+
43
+ To use this gem, add to your Gemfile:
44
+
45
+ ```` ruby
46
+ gem 'subdomain_router'
47
+ ````
48
+
49
+ ### Configuration
50
+
51
+ You will need to configure SubdomainRouter before you can use it. The
52
+ configuration code can be placed anywhere you feel is appropriate
53
+ (`config/application.rb`, a file in `config/initializers`, etc.) as long as it
54
+ runs when your web app starts up.
55
+
56
+ ```` ruby
57
+ SubdomainRouter::Config.default_subdomain = 'www'
58
+ SubdomainRouter::Config.domain = 'mywebsite.com'
59
+ SubdomainRouter::Config.tld_components = 1
60
+ SubdomainRouter::Config.subdomain_matcher = ->(subdomain, request) { ... }
61
+ ````
62
+
63
+ The configuration options are described below.
64
+
65
+ | Option | Description |
66
+ |:--------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
67
+ | `default_subdomain` | The subdomain to use when no dynamic subdomain is specified. This is the subdomain people would use when visiting your site for the first time (default "www" and "" for test.) |
68
+ | `domain` | The domain name. In development, it is by default `lvh.me` (see the _About_ section). In test, it is by default `test.host`. In production, it should be the domain name of your site. |
69
+ | `tld_components` | The number of components in the TLD. If you have a `.com` website, this is 1. If you have a `.co.uk` website, it would be 2. In development and test, it should be 1 (default 1). |
70
+ | `subdomain_matcher` | A `Proc` that takes a subdomain (as a `String`) and an `ActionDispatch::Request` object, and returns `true` if it is a valid dynamic subdomain, or `false` otherwise. A response of `false` would result in a 404. |
71
+
72
+ So as you can see, sensible defaults are provided for most options. At a
73
+ minimum, you need to set `subdomain_matcher` in all environments and `domain` in
74
+ production.
75
+
76
+ These configuration variables are shared by some others in Rails. For DRY
77
+ purposes, you can reuse the configuration values:
78
+
79
+ ```` ruby
80
+ Rails.application.config.action_dispatch.tld_length = SubdomainRouter::Config.tld_components
81
+
82
+ # if you use cookies
83
+ Rails.application.config.session_store :cookie_store, domain: ".#{SubdomainRouter::Config.domain}", expire_after: 2.weeks, key: '_mysite_session'
84
+ ````
85
+
86
+ ### Code additions
87
+
88
+ In your `ApplicationController`, add the following:
89
+
90
+ ```` ruby
91
+ include SubdomainRouter::Controller
92
+ ````
93
+
94
+ In your routes file, group all of the routes you _do_ want to be accessible from
95
+ dynamic subdomains into a block like so:
96
+
97
+ ```` ruby
98
+ constraints SubdomainRouter::Constraint do
99
+ # [...]
100
+ end
101
+ ````
102
+
103
+ Then group all of the routes you want accessible from the default subdomain into
104
+ a similar block:
105
+
106
+ ```` ruby
107
+ constraints(subdomain: SubdomainRouter::Config.default_subdomain) do
108
+ # [...]
109
+ end
110
+ ````
111
+
112
+ This should be all you need. See the next section to learn how to use the
113
+ monkey-patched `url_for`.
114
+
115
+ Usage
116
+ -----
117
+
118
+ Aside from implementing the `subdomain_matcher` proc above, the only other thing
119
+ you will need to is provide subdomain information to all of your links. Since
120
+ `url_for` powers the URL methods (e.g., `posts_url`), the following information
121
+ applies to them equally.
122
+
123
+ For every call to `link_to` or `url_for` in your views, you will need to think
124
+ about how the link will work with subdomains. There are three possibilities:
125
+
126
+ * **Leave the subdomain untouched.** A link to `/bar` at `www.foo.com` will go
127
+ to `www.foo.com/bar`. A link to `/bar` at `custom.foo.com` will go to
128
+ `custom.foo.com/bar`.
129
+ * **Go to the default subdomain.** A link to `/bar` at `www.foo.com` will go to
130
+ `www.foo.com/bar`. A link to `/bar` at `custom.foo.com` will go to
131
+ `www.foo.com/bar`.
132
+ * **Go to a specific subdomain.** A link to `/bar` at `www.foo.com` will go to
133
+ `custom.foo.com/bar`. A link to `/bar` at `another.foo.com` will go to
134
+ `custom.foo.com/bar`.
135
+
136
+ So, if you want to **leave the subdomain untouched**, either omit the
137
+ `:subdomain` option from your call to `url_for`, or set it to `nil`:
138
+
139
+ ```` ruby
140
+ url_for(controller: 'posts', action: 'index') # implied subdomain: nil
141
+ posts_url(subdomain: nil) # explicitly specifying
142
+ ````
143
+
144
+ If you want to **go to the default subdomain**, set the `:subdomain` option to
145
+ `false`:
146
+
147
+ ```` ruby
148
+ url_for(controller: 'testimonials', action: 'index', subdomain: false)
149
+ testimonials_url(subdomain: false)
150
+ ````
151
+
152
+ If you want to **go to a specific subdomain**, specify it using the `:subdomain`
153
+ option:
154
+
155
+ ```` ruby
156
+ url_for(controller: 'profile', action: 'show', subdomain: user.subdomain)
157
+ profile_url(subdomain: user.subdomain)
158
+ ````
159
+
160
+ See {SubdomainRouter::Controller#url_for} for more.
data/Rakefile ADDED
@@ -0,0 +1,45 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+ require 'bundler'
5
+ begin
6
+ Bundler.setup(:default, :development)
7
+ rescue Bundler::BundlerError => e
8
+ $stderr.puts e.message
9
+ $stderr.puts "Run `bundle install` to install missing gems"
10
+ exit e.status_code
11
+ end
12
+ require 'rake'
13
+
14
+ require 'jeweler'
15
+ Jeweler::Tasks.new do |gem|
16
+ # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
17
+ gem.name = "subdomain_router"
18
+ gem.homepage = "http://github.com/RISCfuture/subdomain_router"
19
+ gem.license = "MIT"
20
+ gem.summary = %Q{Use dynamic subdomains in your Rails website}
21
+ gem.description = %Q{This adds a routing constraint and controller methods to allow dynamic subdomain-based routing.}
22
+ gem.email = "gemcutter@timothymorgan.info"
23
+ gem.authors = ["Tim Morgan"]
24
+ # dependencies defined in Gemfile
25
+ end
26
+ Jeweler::RubygemsDotOrgTasks.new
27
+
28
+ require 'rspec/core'
29
+ require 'rspec/core/rake_task'
30
+ RSpec::Core::RakeTask.new(:spec) do |spec|
31
+ spec.pattern = FileList['spec/**/*_spec.rb']
32
+ end
33
+
34
+ task default: :spec
35
+
36
+ require 'yard'
37
+ YARD::Rake::YardocTask.new('doc') do |doc|
38
+ doc.options << '-m' << 'markdown' << '-M' << 'redcarpet'
39
+ doc.options << '--protected' << '--no-private'
40
+ doc.options << '-r' << 'README.md'
41
+ doc.options << '-o' << 'doc'
42
+ doc.options << '--title' << 'Subdomain Router Documentation'
43
+
44
+ doc.files = %w( lib/**/* README.md )
45
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 1.0.0
@@ -0,0 +1,84 @@
1
+ # Module for working with dynamic subdomain routing.
2
+
3
+ module SubdomainRouter
4
+
5
+ # Controller mixin that adds subdomain management features.
6
+
7
+ module Controller
8
+ extend ActiveSupport::Concern
9
+
10
+ included do
11
+ helper_method(:url_for) if respond_to?(:helper_method)
12
+ end
13
+
14
+ # Adds to the `url_for` method the ability to route to different subdomains.
15
+ # Thus, all URL generation (including smart route methods) gains the
16
+ # `:subdomain` options.
17
+ #
18
+ # For more information, see the Rails documentation.
19
+ #
20
+ # @param [Hash] options Options for the URL.
21
+ # @option options [String, nil, false] :subdomain The subdomain to route to.
22
+ # If `false`, uses the default subdomain (e.g., "www"). If `nil`, uses the
23
+ # current subdomain.
24
+ # @return [String] The generated URL.
25
+ # @raise [ArgumentError] If the `:subdomain` option is invalid.
26
+
27
+ def url_for(options={})
28
+ return super unless options.is_a?(Hash)
29
+
30
+ case options[:subdomain]
31
+ when nil
32
+ options.delete :subdomain
33
+ super options
34
+ when false, String
35
+ subdomain = options.delete(:subdomain) || Config.default_subdomain
36
+ host = options[:host] || (respond_to?(:request) && request.host) || Config.domain
37
+ host_parts = host.split('.').last(Config.tld_components + 1)
38
+ host_parts.unshift subdomain
39
+ host_parts.delete_if &:blank?
40
+ super options.merge(host: host_parts.join('.'))
41
+ else
42
+ raise ArgumentError, ":subdomain must be nil, false, or a string"
43
+ end
44
+ end
45
+ end
46
+
47
+ # A routing constraint that restricts routes to only valid dynamic subdomains.
48
+ #
49
+ # @example
50
+ # get 'home' => 'accounts#show', constraint: SubdomainRouter::Constraint
51
+
52
+ module Constraint
53
+
54
+ # Determines if a given request has a custom user subdomain.
55
+ #
56
+ # @param [ActionDispatch::Request] request An HTTP request.
57
+ # @return [true, false] Whether the request subdomain matches a known user
58
+ # subdomain.
59
+
60
+ def matches?(request)
61
+ return false unless request.subdomains.size == 1
62
+ return false if request.subdomains.first == Config.default_subdomain
63
+ return subdomain?(request)
64
+ end
65
+ module_function :matches?
66
+
67
+ private
68
+
69
+ def subdomain?(request)
70
+ subdomain = request.subdomains.first.downcase
71
+ Config.subdomain_matcher.(subdomain, request)
72
+ end
73
+ module_function :subdomain?
74
+ end
75
+
76
+ # Subdomain routing configuration object.
77
+
78
+ Config = Struct.new(:default_subdomain, :domain, :tld_components, :subdomain_matcher).new
79
+ Config.default_subdomain = Rails.env.test? ? '' : 'www'
80
+ Config.domain = 'lvh.me' if Rails.env.development?
81
+ Config.domain = 'test.host' if Rails.env.test?
82
+ Config.tld_components = 1
83
+ Config.subdomain_matcher = ->(subdomain, request) { false }
84
+ end
@@ -0,0 +1,20 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
3
+
4
+ require 'bundler'
5
+ Bundler.require :development
6
+ Bundler.require
7
+ require 'action_controller'
8
+ require 'subdomain_router'
9
+
10
+ # Requires supporting files with custom matchers and macros, etc,
11
+ # in ./support/ and its subdirectories.
12
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
13
+
14
+ SubdomainRouter::Config.default_subdomain = ''
15
+ SubdomainRouter::Config.tld_components = 1
16
+ SubdomainRouter::Config.domain = 'test.host'
17
+
18
+ RSpec.configure do |config|
19
+
20
+ end
@@ -0,0 +1,145 @@
1
+ require 'spec_helper'
2
+
3
+ class UrlForController < ActionController::Metal
4
+ include SubdomainRouter::Controller
5
+ end
6
+
7
+ class UrlForMailer
8
+ include SubdomainRouter::Controller
9
+ end
10
+
11
+ describe SubdomainRouter::Controller do
12
+ before :all do
13
+ @controller = UrlForController.new
14
+ end
15
+
16
+ describe "#url_for" do
17
+ it "should call the superclass unless a hash is given" do
18
+ @controller.url_for('foo').should eql('foo')
19
+ end
20
+
21
+ context "[given host]" do
22
+ before :each do
23
+ @controller.stub!(:request).and_return(mock('ActionDispatch::Request', host: 'test.host'))
24
+ end
25
+
26
+ it "should leave the domain untouched if :subdomain => nil" do
27
+ @controller.url_for(host: 'foo.bar').should eql(host: 'foo.bar')
28
+ @controller.url_for(host: 'sd.foo.bar').should eql(host: 'sd.foo.bar')
29
+ @controller.url_for(host: 'baz.bat.foo.bar').should eql(host: 'baz.bat.foo.bar')
30
+ end
31
+
32
+ it "should replace the subdomain if :subdomain is given" do
33
+ @controller.url_for(host: 'foo.bar', subdomain: 'sd').should eql(host: 'sd.foo.bar')
34
+ @controller.url_for(host: 'baz.foo.bar', subdomain: 'sd').should eql(host: 'sd.foo.bar')
35
+ @controller.url_for(host: 'baz.bat.foo.bar', subdomain: 'sd').should eql(host: 'sd.foo.bar')
36
+ end
37
+
38
+ it "should use the default subdomain if :subdomain is false" do
39
+ @controller.url_for(host: 'foo.bar', subdomain: false).should eql(host: 'foo.bar')
40
+ @controller.url_for(host: 'baz.foo.bar', subdomain: false).should eql(host: 'foo.bar')
41
+ @controller.url_for(host: 'baz.bat.foo.bar', subdomain: false).should eql(host: 'foo.bar')
42
+ end
43
+ end
44
+
45
+ context "[request host]" do
46
+ it "should leave the domain untouched if :subdomain => nil" do
47
+ @controller.stub!(:request).and_return(mock('ActionDispatch::Request', host: 'foo.bar'))
48
+ @controller.url_for(subdomain: nil).should eql({})
49
+
50
+ @controller.stub!(:request).and_return(mock('ActionDispatch::Request', host: 'sd.foo.bar'))
51
+ @controller.url_for(subdomain: nil).should eql({})
52
+
53
+ @controller.stub!(:request).and_return(mock('ActionDispatch::Request', host: 'baz.bat.foo.bar'))
54
+ @controller.url_for(subdomain: nil).should eql({})
55
+ end
56
+
57
+ it "should replace the subdomain if :subdomain is given" do
58
+ @controller.stub!(:request).and_return(mock('ActionDispatch::Request', host: 'foo.bar'))
59
+ @controller.url_for(subdomain: 'sd').should eql(host: 'sd.foo.bar')
60
+
61
+ @controller.stub!(:request).and_return(mock('ActionDispatch::Request', host: 'baz.foo.bar'))
62
+ @controller.url_for(subdomain: 'sd').should eql(host: 'sd.foo.bar')
63
+
64
+ @controller.stub!(:request).and_return(mock('ActionDispatch::Request', host: 'baz.bat.foo.bar'))
65
+ @controller.url_for(subdomain: 'sd').should eql(host: 'sd.foo.bar')
66
+ end
67
+
68
+ it "should use the default subdomain if :subdomain is false" do
69
+ @controller.stub!(:request).and_return(mock('ActionDispatch::Request', host: 'foo.bar'))
70
+ @controller.url_for(subdomain: false).should eql(host: 'foo.bar')
71
+
72
+ @controller.stub!(:request).and_return(mock('ActionDispatch::Request', host: 'baz.foo.bar'))
73
+ @controller.url_for(subdomain: false).should eql(host: 'foo.bar')
74
+
75
+ @controller.stub!(:request).and_return(mock('ActionDispatch::Request', host: 'baz.bat.foo.bar'))
76
+ @controller.url_for(subdomain: false).should eql(host: 'foo.bar')
77
+ end
78
+ end
79
+
80
+ context "[no host]" do
81
+ before :all do
82
+ @mailer = UrlForMailer.new
83
+ end
84
+
85
+ before :each do
86
+ pending "Need to find a way to test this without building up a whole Rails app"
87
+ end
88
+
89
+ it "should leave the domain untouched if :subdomain => nil" do
90
+ # no host provided = exception
91
+ -> { @mailer.url_for(controller: 'users', action: 'new', subdomain: nil) }.should raise_error(ArgumentError)
92
+ end
93
+
94
+ it "should replace the subdomain if :subdomain is given" do
95
+ @mailer.url_for(controller: 'users', action: 'new', subdomain: 'sd').should eql('http://sd.test.host/users/new')
96
+ end
97
+
98
+ it "should use the default subdomain if :subdomain is false" do
99
+ @mailer.url_for(controller: 'users', action: 'new', subdomain: false).should eql('http://test.host/users/new')
100
+ end
101
+ end
102
+ end
103
+ end
104
+
105
+ describe SubdomainRouter::Constraint do
106
+ describe ".matches?" do
107
+ before :each do
108
+ @env = {}
109
+ @request = mock('ActionDispatch::Request', env: @env)
110
+ end
111
+
112
+ it "should return false if there is more than one subdomain" do
113
+ @request.stub!(:subdomains).and_return(%w( foo bar ))
114
+ SubdomainRouter::Constraint.matches?(@request).should be_false
115
+ end
116
+
117
+ it "should return false if there is no subdomain" do
118
+ @request.stub!(:subdomains).and_return([])
119
+ SubdomainRouter::Constraint.matches?(@request).should be_false
120
+ end
121
+
122
+ it "should return false if the subdomain is equal to the default subdomain" do
123
+ SubdomainRouter::Config.default_subdomain = 'www'
124
+ @request.stub!(:subdomains).and_return(%w( www ))
125
+ SubdomainRouter::Constraint.matches?(@request).should be_false
126
+ end
127
+
128
+ it "should return false if the subdomain does not belong to any user" do
129
+ @request.stub!(:subdomains).and_return(%w( not-found ))
130
+ SubdomainRouter::Constraint.matches?(@request).should be_false
131
+ end
132
+
133
+ it "should return true if the subdomain belongs to a user and save the user to the env" do
134
+ SubdomainRouter::Config.subdomain_matcher = ->(subdomain, request) { subdomain == 'valid' }
135
+ @request.stub!(:subdomains).and_return([ 'valid' ])
136
+ SubdomainRouter::Constraint.matches?(@request).should be_true
137
+ end
138
+
139
+ it "should downcase the subdomain" do
140
+ SubdomainRouter::Config.subdomain_matcher = ->(subdomain, request) { subdomain == 'valid' }
141
+ @request.stub!(:subdomains).and_return([ 'VALID' ])
142
+ SubdomainRouter::Constraint.matches?(@request).should be_true
143
+ end
144
+ end
145
+ end
@@ -0,0 +1,66 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = "subdomain_router"
8
+ s.version = "1.0.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Tim Morgan"]
12
+ s.date = "2012-04-23"
13
+ s.description = "This adds a routing constraint and controller methods to allow dynamic subdomain-based routing."
14
+ s.email = "gemcutter@timothymorgan.info"
15
+ s.extra_rdoc_files = [
16
+ "LICENSE.txt",
17
+ "README.md"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ ".rspec",
22
+ ".rvmrc",
23
+ "Gemfile",
24
+ "Gemfile.lock",
25
+ "LICENSE.txt",
26
+ "README.md",
27
+ "Rakefile",
28
+ "VERSION",
29
+ "lib/subdomain_router.rb",
30
+ "spec/spec_helper.rb",
31
+ "spec/subdomain_router_spec.rb"
32
+ ]
33
+ s.homepage = "http://github.com/RISCfuture/subdomain_router"
34
+ s.licenses = ["MIT"]
35
+ s.require_paths = ["lib"]
36
+ s.rubygems_version = "1.8.23"
37
+ s.summary = "Use dynamic subdomains in your Rails website"
38
+
39
+ if s.respond_to? :specification_version then
40
+ s.specification_version = 3
41
+
42
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
43
+ s.add_runtime_dependency(%q<rails>, [">= 0"])
44
+ s.add_development_dependency(%q<rspec>, [">= 0"])
45
+ s.add_development_dependency(%q<yard>, [">= 0"])
46
+ s.add_development_dependency(%q<redcarpet>, [">= 0"])
47
+ s.add_development_dependency(%q<bundler>, [">= 0"])
48
+ s.add_development_dependency(%q<jeweler>, [">= 0"])
49
+ else
50
+ s.add_dependency(%q<rails>, [">= 0"])
51
+ s.add_dependency(%q<rspec>, [">= 0"])
52
+ s.add_dependency(%q<yard>, [">= 0"])
53
+ s.add_dependency(%q<redcarpet>, [">= 0"])
54
+ s.add_dependency(%q<bundler>, [">= 0"])
55
+ s.add_dependency(%q<jeweler>, [">= 0"])
56
+ end
57
+ else
58
+ s.add_dependency(%q<rails>, [">= 0"])
59
+ s.add_dependency(%q<rspec>, [">= 0"])
60
+ s.add_dependency(%q<yard>, [">= 0"])
61
+ s.add_dependency(%q<redcarpet>, [">= 0"])
62
+ s.add_dependency(%q<bundler>, [">= 0"])
63
+ s.add_dependency(%q<jeweler>, [">= 0"])
64
+ end
65
+ end
66
+
metadata ADDED
@@ -0,0 +1,160 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: subdomain_router
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Tim Morgan
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-04-23 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rails
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: rspec
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: yard
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: redcarpet
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ - !ruby/object:Gem::Dependency
79
+ name: bundler
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ - !ruby/object:Gem::Dependency
95
+ name: jeweler
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ description: This adds a routing constraint and controller methods to allow dynamic
111
+ subdomain-based routing.
112
+ email: gemcutter@timothymorgan.info
113
+ executables: []
114
+ extensions: []
115
+ extra_rdoc_files:
116
+ - LICENSE.txt
117
+ - README.md
118
+ files:
119
+ - .document
120
+ - .rspec
121
+ - .rvmrc
122
+ - Gemfile
123
+ - Gemfile.lock
124
+ - LICENSE.txt
125
+ - README.md
126
+ - Rakefile
127
+ - VERSION
128
+ - lib/subdomain_router.rb
129
+ - spec/spec_helper.rb
130
+ - spec/subdomain_router_spec.rb
131
+ - subdomain_router.gemspec
132
+ homepage: http://github.com/RISCfuture/subdomain_router
133
+ licenses:
134
+ - MIT
135
+ post_install_message:
136
+ rdoc_options: []
137
+ require_paths:
138
+ - lib
139
+ required_ruby_version: !ruby/object:Gem::Requirement
140
+ none: false
141
+ requirements:
142
+ - - ! '>='
143
+ - !ruby/object:Gem::Version
144
+ version: '0'
145
+ segments:
146
+ - 0
147
+ hash: -4479704525159209868
148
+ required_rubygems_version: !ruby/object:Gem::Requirement
149
+ none: false
150
+ requirements:
151
+ - - ! '>='
152
+ - !ruby/object:Gem::Version
153
+ version: '0'
154
+ requirements: []
155
+ rubyforge_project:
156
+ rubygems_version: 1.8.23
157
+ signing_key:
158
+ specification_version: 3
159
+ summary: Use dynamic subdomains in your Rails website
160
+ test_files: []