subdomain-fu 0.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.
data/CHANGELOG ADDED
@@ -0,0 +1,13 @@
1
+ == 2009-08-26
2
+
3
+ * Fixed needs_rewrite? method
4
+ * Added is_mirror? method
5
+ * Added tests, and fixed failing tests
6
+
7
+ == 2009-08-24
8
+
9
+ * Merged forks that added lots of features, tests, and fixes
10
+
11
+ == 2008-06-25
12
+
13
+ * Removed stray puts
data/MIT-LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ Copyright (c) 2008 Michael Bleigh (http://www.mbleigh.com) and
2
+ Intridea, Inc (http://www.intridea.com)
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining
5
+ a copy of this software and associated documentation files (the
6
+ "Software"), to deal in the Software without restriction, including
7
+ without limitation the rights to use, copy, modify, merge, publish,
8
+ distribute, sublicense, and/or sell copies of the Software, and to
9
+ permit persons to whom the Software is furnished to do so, subject to
10
+ the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be
13
+ included in all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,96 @@
1
+ = SubdomainFu
2
+
3
+ SubdomainFu provides a modern implementation of subdomain handling in Rails.
4
+ It takes aspects from account_location, request_routing, and other snippets
5
+ found around the web and combines them to provide a single, simple solution
6
+ for subdomain-based route and url management.
7
+
8
+ == Installation
9
+
10
+ SubdomainFu is available both as a traditional plugin and a GemPlugin. To
11
+ install it as a traditional plugin (Rails 2.1 or later):
12
+
13
+ script/plugin install git://github.com/mbleigh/subdomain-fu.git
14
+
15
+ To use it as a GemPlugin, add it to your environment.rb:
16
+
17
+ config.gem 'mbleigh-subdomain-fu', :source => "http://gems.github.com", :lib => "subdomain-fu"
18
+
19
+
20
+ == Examples
21
+
22
+ SubdomainFu works inside of Rails's URL Writing mechanisms to provide an easy and seamless
23
+ way to link and otherwise understand cross-subdomain routing. You can use the :subdomain
24
+ option both in named and non-named routes as well as in generated resources routes.
25
+
26
+ Let's say my domain is 'intridea.com'. Here are some examples of the use of the :subdomain
27
+ option:
28
+
29
+ url_for(:controller => "my_controller",
30
+ :action => "my_action",
31
+ :subdomain => "awesome") # => http://awesome.intridea.com/my_controller/my_action
32
+
33
+ Now let's say I'm at http://awesome.intridea.com/ and I want back to the root.
34
+ Specifying "false" will remove any current subdomain:
35
+
36
+ users_url(:subdomain => false) # => http://intridea.com/users
37
+
38
+ Note that this plugin does not honor the :only_path notion of routing when doing
39
+ so would go against the intent of the command. For example, if I were at http://intridea.com
40
+ again:
41
+
42
+ users_path(:subdomain => "fun") # => http://fun.intridea.com/users
43
+ users_path(:subdomain => false) # => /users
44
+
45
+ In this way you can rest assured that you will never misdirect your links to the
46
+ same subdomain when you meant to change it.
47
+
48
+ == Configuration
49
+
50
+ You may need to configure SubdomainFu based on your development setup. The
51
+ configuration required is:
52
+
53
+ === TLD Size
54
+
55
+ A hash for each environment of the size of the top-level domain name.
56
+ (something.com = 1, localhost = 0, etc.)
57
+
58
+ SubdomainFu.tld_size = 1 # sets for current environment
59
+ SubdomainFu.tld_sizes = {:development => 0,
60
+ :test => 0,
61
+ :production => 1} # set all at once (also the defaults)
62
+
63
+ === Mirrors
64
+
65
+ Mirrors are the subdomains that are equivalent to no subdomain (i.e. they 'mirror')
66
+ the usage of the root domain.
67
+
68
+ SubdomainFu.mirrors = %w(www site we) # Defaults to %w(www)
69
+
70
+ === Preferred Mirror
71
+
72
+ SubdomainFu also understands the notion of a 'preferred mirror', that is, if you
73
+ always want your links going to 'www.yourdomain.com' instead of 'yourdomain.com',
74
+ you can set the preferred mirror like so:
75
+
76
+ SubdomainFu.preferred_mirror = "www"
77
+
78
+ Now when you create a link with subdomain => false in the options the subdomain
79
+ will default to the preferred mirror.
80
+
81
+ == Routing
82
+
83
+ SubdomainFu can also work within Rails' routing for subdomain-specific routes. For instance, if you only wanted your administrative tools available in the "admin" subdomain you could add this to your routes.rb file:
84
+
85
+ map.with_options :conditions => {:subdomain => 'admin} do |admin|
86
+ admin.resources :posts
87
+ admin.resources :users
88
+ end
89
+
90
+ == Resources
91
+
92
+ * GitHub Repository: http://github.com/mbleigh/subdomain-fu
93
+ * RDocs: http://rdoc.info/projects/mbleigh/subdomain-fu
94
+
95
+ Copyright (c) 2008 Michael Bleigh (http://www.mbleigh.com/) and
96
+ Intridea, Inc. (http://www.intridea.com/). Released under the MIT license
data/Rakefile ADDED
@@ -0,0 +1,27 @@
1
+ require 'rake'
2
+ require 'spec/rake/spectask'
3
+
4
+ desc 'Default: run specs.'
5
+ task :default => :spec
6
+
7
+ desc 'Run the specs'
8
+ Spec::Rake::SpecTask.new(:spec) do |t|
9
+ t.spec_opts = ['--colour --format progress --loadby mtime --reverse']
10
+ t.spec_files = FileList['spec/**/*_spec.rb']
11
+ end
12
+
13
+ begin
14
+ require 'jeweler'
15
+ Jeweler::Tasks.new do |gemspec|
16
+ gemspec.name = "subdomain-fu"
17
+ gemspec.summary = "SubdomainFu is a Rails plugin that provides subdomain routing and URL writing helpers."
18
+ gemspec.email = "michael@intridea.com"
19
+ gemspec.homepage = "http://github.com/mbleigh/subdomain-fu"
20
+ gemspec.files = FileList["[A-Z]*", "{lib,spec,rails}/**/*"] - FileList["**/*.log"]
21
+ gemspec.description = "SubdomainFu is a Rails plugin to provide all of the basic functionality necessary to handle multiple subdomain applications (such as Basecamp-esque subdomain accounts and more)."
22
+ gemspec.authors = ["Michael Bleigh"]
23
+ end
24
+ rescue LoadError
25
+ puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
26
+ end
27
+
data/VERSION.yml ADDED
@@ -0,0 +1,4 @@
1
+ ---
2
+ :minor: 4
3
+ :patch: 0
4
+ :major: 0
@@ -0,0 +1,150 @@
1
+ require 'subdomain_fu/routing_extensions'
2
+ require 'subdomain_fu/url_rewriter'
3
+
4
+ module SubdomainFu
5
+ # The length of the period-split top-level domain for each environment.
6
+ # For example, "localhost" has a tld_size of zero, and "something.co.uk"
7
+ # has a tld_size of two.
8
+ #
9
+ # To set a tld size for a given environment, just call SubdomainFu.tld_sizes[:environment] = value
10
+ DEFAULT_TLD_SIZES = {:development => 0, :test => 0, :production => 1}
11
+ mattr_accessor :tld_sizes
12
+ @@tld_sizes = DEFAULT_TLD_SIZES.dup
13
+
14
+ # Subdomains that are equivalent to going to the website with no subdomain at all.
15
+ # Defaults to "www" as the only member.
16
+ DEFAULT_MIRRORS = %w(www)
17
+ mattr_accessor :mirrors
18
+ @@mirrors = DEFAULT_MIRRORS.dup
19
+
20
+ mattr_accessor :preferred_mirror
21
+ @@preferred_mirror = nil
22
+
23
+ mattr_accessor :override_only_path
24
+ @@override_only_path = false
25
+
26
+ # Returns the TLD Size of the current environment.
27
+ def self.tld_size
28
+ tld_sizes[RAILS_ENV.to_sym]
29
+ end
30
+
31
+ # Sets the TLD Size of the current environment
32
+ def self.tld_size=(value)
33
+ tld_sizes[RAILS_ENV.to_sym] = value
34
+ end
35
+
36
+ # Is the current subdomain either nil or not a mirror?
37
+ def self.has_subdomain?(subdomain)
38
+ subdomain != false && !subdomain.blank? && !SubdomainFu.mirrors.include?(subdomain)
39
+ end
40
+
41
+ def self.is_mirror?(subdomain)
42
+ subdomain != false && !subdomain.blank? && SubdomainFu.mirrors.include?(subdomain)
43
+ end
44
+
45
+ # Is the subdomain a preferred mirror
46
+ def self.preferred_mirror?(subdomain)
47
+ subdomain == SubdomainFu.preferred_mirror || SubdomainFu.preferred_mirror.nil?
48
+ end
49
+
50
+ # Gets the subdomain from the host based on the TLD size
51
+ def self.subdomain_from(host)
52
+ return nil if host.nil? || /\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/.match(host)
53
+ parts = host.split('.')
54
+ sub = parts[0..-(SubdomainFu.tld_size+2)].join(".")
55
+ sub.blank? ? nil : sub
56
+ end
57
+
58
+ # Gets only non-mirror subdomains from the host based on the TLD size
59
+ def self.non_mirror_subdomain_from(host)
60
+ sub = subdomain_from(host)
61
+ has_subdomain?(sub) ? sub : nil
62
+ end
63
+
64
+ def self.host_without_subdomain(host)
65
+ parts = host.split('.')
66
+ parts[-(SubdomainFu.tld_size+1)..-1].join(".")
67
+ end
68
+
69
+ # Rewrites the subdomain of the host unless they are equivalent (i.e. mirrors of each other)
70
+ def self.rewrite_host_for_subdomains(subdomain, host)
71
+ if needs_rewrite?(subdomain, host)
72
+ change_subdomain_of_host(subdomain || SubdomainFu.preferred_mirror, host)
73
+ else
74
+ if has_subdomain?(subdomain) || preferred_mirror?(subdomain_from(host)) ||
75
+ (subdomain.nil? && has_subdomain?(subdomain_from(host)))
76
+ host
77
+ else
78
+ change_subdomain_of_host(SubdomainFu.preferred_mirror, host)
79
+ end
80
+ end
81
+ end
82
+
83
+ # Changes the subdomain of the host to whatever is passed in.
84
+ def self.change_subdomain_of_host(subdomain, host)
85
+ host = SubdomainFu.host_without_subdomain(host)
86
+ host = "#{subdomain}.#{host}" if subdomain
87
+ host
88
+ end
89
+
90
+ # Is this subdomain equivalent to the subdomain found in this host string?
91
+ def self.same_subdomain?(subdomain, host)
92
+ subdomain = nil unless subdomain
93
+ (subdomain == subdomain_from(host)) ||
94
+ (!has_subdomain?(subdomain) && !has_subdomain?(subdomain_from(host)))
95
+ end
96
+
97
+ def self.override_only_path?
98
+ self.override_only_path
99
+ end
100
+
101
+ def self.needs_rewrite?(subdomain, host)
102
+ case subdomain
103
+ when nil
104
+ #rewrite when there is a preferred mirror set and there is no subdomain on the host
105
+ return true if self.preferred_mirror && subdomain_from(host).nil?
106
+ return false
107
+ when false
108
+ h = subdomain_from(host)
109
+ #if the host has a subdomain
110
+ if !h.nil?
111
+ #rewrite when there is a subdomain in the host, and it is not a preferred mirror
112
+ return true if !preferred_mirror?(h)
113
+ #rewrite when there is a preferred mirror set and the subdomain of the host is not a mirror
114
+ return true if self.preferred_mirror && !is_mirror?(h)
115
+ #no rewrite if host already has mirror subdomain
116
+ #it { SubdomainFu.needs_rewrite?(false,"www.localhost").should be_false }
117
+ return false if is_mirror?(h)
118
+ end
119
+ return self.crazy_rewrite_rule(subdomain, host)
120
+ else
121
+ return self.crazy_rewrite_rule(subdomain, host)
122
+ end
123
+ end
124
+
125
+ #This is a black box of crazy! So I split some of the simpler logic out into the case statement above to make my brain happy!
126
+ def self.crazy_rewrite_rule(subdomain, host)
127
+ (!has_subdomain?(subdomain) && preferred_mirror?(subdomain) && !preferred_mirror?(subdomain_from(host))) ||
128
+ !same_subdomain?(subdomain, host)
129
+ end
130
+
131
+ def self.current_subdomain(request)
132
+ subdomain = request.subdomains(SubdomainFu.tld_size).join(".")
133
+ if has_subdomain?(subdomain)
134
+ subdomain
135
+ else
136
+ nil
137
+ end
138
+ end
139
+
140
+ module Controller
141
+ def self.included(controller)
142
+ controller.helper_method(:current_subdomain)
143
+ end
144
+
145
+ protected
146
+ def current_subdomain
147
+ SubdomainFu.current_subdomain(request)
148
+ end
149
+ end
150
+ end
@@ -0,0 +1,61 @@
1
+ # Thanks to Jamis Buck for ideas on this stuff
2
+ # http://weblog.jamisbuck.org/2006/10/26/monkey-patching-rails-extending-routes-2
3
+ # This is not yet a working part of SubdomainFu.
4
+
5
+ module SubdomainFu
6
+ module RouteExtensions
7
+ def self.included(base)
8
+ base.alias_method_chain :recognition_conditions, :subdomain
9
+ end
10
+
11
+ def recognition_conditions_with_subdomain
12
+ result = recognition_conditions_without_subdomain
13
+ result << "conditions[:subdomain] === env[:subdomain]" if conditions[:subdomain] && conditions[:subdomain] != true && conditions[:subdomain] != false
14
+ result << "SubdomainFu.has_subdomain?(env[:subdomain])" if conditions[:subdomain] == true
15
+ result << "!SubdomainFu.has_subdomain?(env[:subdomain])" if conditions[:subdomain] == false
16
+ result
17
+ end
18
+ end
19
+
20
+ module RouteSetExtensions
21
+ def self.included(base)
22
+ base.alias_method_chain :extract_request_environment, :subdomain
23
+ end
24
+
25
+ def extract_request_environment_with_subdomain(request)
26
+ env = extract_request_environment_without_subdomain(request)
27
+ env.merge(:host => request.host, :domain => request.domain, :subdomain => SubdomainFu.subdomain_from(request.host))
28
+ end
29
+ end
30
+
31
+ module MapperExtensions
32
+ def quick_map(has_unless, *args, &block)
33
+ options = args.find{|a| a.is_a?(Hash)}
34
+ namespace_str = options ? options.delete(:namespace).to_s : args.join('_or_')
35
+ namespace_str += '_' unless namespace_str.blank?
36
+ mapped_exp = args.map(&:to_s).join('|')
37
+ conditions_hash = { :subdomain => ( has_unless ? /[^(#{mapped_exp})]/ : /(#{mapped_exp})/) }
38
+ with_options(:conditions => conditions_hash, :name_prefix => namespace_str, &block)
39
+ end
40
+ # Adds methods to Mapper to apply an options with a method. Example
41
+ # map.subdomain :blog { |blog| blog.resources :pages }
42
+ # or
43
+ # map.unless_subdomain :blog { |not_blog| not_blog.resources :people }
44
+ def subdomain(*args, &block)
45
+ quick_map(false, *args, &block)
46
+ end
47
+ def unless_subdomain(*args, &block)
48
+ quick_map(true, *args, &block)
49
+ end
50
+ end
51
+ end
52
+
53
+ ActionController::Routing::RouteSet::Mapper.send :include, SubdomainFu::MapperExtensions
54
+ ActionController::Routing::RouteSet.send :include, SubdomainFu::RouteSetExtensions
55
+ ActionController::Routing::Route.send :include, SubdomainFu::RouteExtensions
56
+
57
+ # UrlRewriter::RESERVED_OPTIONS is only available in Rails >= 2.2
58
+ # http://www.portallabs.com/blog/2008/12/02/fixing-subdomain_fu-with-named-routes-rails-22/
59
+ if Rails::VERSION::MAJOR >= 2 and Rails::VERSION::MINOR >= 2
60
+ ActionController::UrlRewriter::RESERVED_OPTIONS << :subdomain
61
+ end
@@ -0,0 +1,48 @@
1
+ module ActionController
2
+ module UrlWriter
3
+ def url_for_with_subdomains(options)
4
+ if SubdomainFu.needs_rewrite?(options[:subdomain], options[:host] || default_url_options[:host]) || options[:only_path] == false
5
+ options[:only_path] = false if SubdomainFu.override_only_path?
6
+ options[:host] = SubdomainFu.rewrite_host_for_subdomains(options.delete(:subdomain), options[:host] || default_url_options[:host])
7
+ else
8
+ options.delete(:subdomain)
9
+ end
10
+ url_for_without_subdomains(options)
11
+ end
12
+ alias_method_chain :url_for, :subdomains
13
+ end
14
+
15
+ class UrlRewriter #:nodoc:
16
+ private
17
+
18
+ def rewrite_url_with_subdomains(options)
19
+ if SubdomainFu.needs_rewrite?(options[:subdomain], (options[:host] || @request.host_with_port)) || options[:only_path] == false
20
+ options[:only_path] = false if SubdomainFu.override_only_path?
21
+ options[:host] = SubdomainFu.rewrite_host_for_subdomains(options.delete(:subdomain), options[:host] || @request.host_with_port)
22
+ puts "options[:host]: #{options[:host].inspect}"
23
+ else
24
+ options.delete(:subdomain)
25
+ end
26
+ rewrite_url_without_subdomains(options)
27
+ end
28
+ alias_method_chain :rewrite_url, :subdomains
29
+ end
30
+
31
+ if Rails::VERSION::MAJOR >= 2 and Rails::VERSION::MINOR <= 1
32
+ # hack for http://www.portallabs.com/blog/2008/10/22/fixing-subdomain_fu-with-named-routes/
33
+ module Routing
34
+ module Optimisation
35
+ class PositionalArgumentsWithAdditionalParams
36
+ def guard_condition_with_subdomains
37
+ # don't allow optimisation if a subdomain is present - fixes a problem
38
+ # with the subdomain appearing in the query instead of being rewritten
39
+ # see http://mbleigh.lighthouseapp.com/projects/13148/tickets/8-improper-generated-urls-with-named-routes-for-a-singular-resource
40
+ guard_condition_without_subdomains + " && !args.last.has_key?(:subdomain)"
41
+ end
42
+
43
+ alias_method_chain :guard_condition, :subdomains
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
data/rails/init.rb ADDED
@@ -0,0 +1,8 @@
1
+ # Add this path to ruby load path
2
+ $:.unshift "#{File.dirname(__FILE__)}/../lib"
3
+
4
+ require 'subdomain-fu' unless defined?(SubdomainFu)
5
+
6
+ ActionController::Base.send :include, SubdomainFu::Controller
7
+
8
+ RAILS_DEFAULT_LOGGER.info("** SubdomainFu: initialized properly")
data/spec/spec.opts ADDED
@@ -0,0 +1,7 @@
1
+ --colour
2
+ --format
3
+ specdoc
4
+ --loadby
5
+ mtime
6
+ --reverse
7
+ --backtrace
@@ -0,0 +1,42 @@
1
+ begin
2
+ require File.dirname(__FILE__) + '/../../../../spec/spec_helper'
3
+ rescue LoadError
4
+ puts "You need to install rspec in your base app"
5
+ exit
6
+ end
7
+
8
+ plugin_spec_dir = File.dirname(__FILE__)
9
+ ActiveRecord::Base.logger = Logger.new(plugin_spec_dir + "/debug.log")
10
+
11
+ ActionController::Routing::Routes.draw do |map|
12
+ map.needs_subdomain '/needs_subdomain', :controller => "fu", :action => "awesome"
13
+ map.no_subdomain '/no_subdomain', :controller => "fu", :action => "lame"
14
+ map.needs_awesome '/needs_awesome', :controller => "fu", :action => "lame"
15
+
16
+ map.resources :foos do |fu|
17
+ fu.resources :bars
18
+ end
19
+
20
+ map.connect '/', :controller => "site", :action => "home", :conditions => {:subdomain => false}
21
+ map.connect '/', :controller => "app", :action => "home", :conditions => {:subdomain => true}
22
+ map.connect '/', :controller => "mobile", :action => "home", :conditions => {:subdomain => "m"}
23
+
24
+ map.connect '/subdomain_here', :controller => "app", :action => "success", :conditions => {:subdomain => true}
25
+ map.connect '/no_subdomain_here', :controller => "site", :action => "success", :conditions => {:subdomain => false}
26
+ map.connect '/m_subdomain_here', :controller => "mobile", :action => "success", :conditions => {:subdomain => "m"}
27
+ map.connect '/numbers_only_here', :controller => "numbers", :action => "success", :conditions => {:subdomain => /[0-9]+/}
28
+
29
+ map.connect '/:controller/:action/:id'
30
+ end
31
+
32
+ class Paramed
33
+ def initialize(param)
34
+ @param = param
35
+ end
36
+
37
+ def to_param
38
+ @param || "param"
39
+ end
40
+ end
41
+
42
+ include ActionController::UrlWriter
@@ -0,0 +1,217 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ describe "SubdomainFu" do
4
+ before do
5
+ SubdomainFu.tld_sizes = SubdomainFu::DEFAULT_TLD_SIZES.dup
6
+ SubdomainFu.mirrors = SubdomainFu::DEFAULT_MIRRORS.dup
7
+ SubdomainFu.preferred_mirror = nil
8
+ end
9
+
10
+ describe "TLD Sizes" do
11
+ before do
12
+ SubdomainFu.tld_sizes = SubdomainFu::DEFAULT_TLD_SIZES.dup
13
+ end
14
+
15
+ it { SubdomainFu.tld_sizes.should be_kind_of(Hash) }
16
+
17
+ it "should have default values for development, test, and production" do
18
+ SubdomainFu.tld_sizes[:development].should == 0
19
+ SubdomainFu.tld_sizes[:test].should == 0
20
+ SubdomainFu.tld_sizes[:production].should == 1
21
+ end
22
+
23
+ it "#tld_size should be for the current environment" do
24
+ SubdomainFu.tld_size.should == SubdomainFu.tld_sizes[RAILS_ENV.to_sym]
25
+ end
26
+
27
+ it "should be able to be set for the current environment" do
28
+ SubdomainFu.tld_size = 5
29
+ SubdomainFu.tld_size.should == 5
30
+ SubdomainFu.tld_sizes[:test].should == 5
31
+ end
32
+ end
33
+
34
+ describe "#has_subdomain?" do
35
+ it "should be true for non-mirrored subdomains" do
36
+ SubdomainFu.has_subdomain?("awesome").should be_true
37
+ end
38
+
39
+ it "should be false for mirrored subdomains" do
40
+ SubdomainFu.has_subdomain?(SubdomainFu.mirrors.first).should be_false
41
+ end
42
+
43
+ it "shoud be false for a nil or blank subdomain" do
44
+ SubdomainFu.has_subdomain?("").should be_false
45
+ SubdomainFu.has_subdomain?(nil).should be_false
46
+ SubdomainFu.has_subdomain?(false).should be_false
47
+ end
48
+ end
49
+
50
+ describe "#subdomain_from" do
51
+ it "should return the subdomain based on the TLD of the current environment" do
52
+ SubdomainFu.subdomain_from("awesome.localhost").should == "awesome"
53
+ SubdomainFu.tld_size = 2
54
+ SubdomainFu.subdomain_from("awesome.localhost.co.uk").should == "awesome"
55
+ SubdomainFu.tld_size = 1
56
+ SubdomainFu.subdomain_from("awesome.localhost.com").should == "awesome"
57
+ SubdomainFu.tld_size = 0
58
+ end
59
+
60
+ it "should join deep subdomains with a period" do
61
+ SubdomainFu.subdomain_from("awesome.coolguy.localhost").should == "awesome.coolguy"
62
+ end
63
+
64
+ it "should return nil for no subdomain" do
65
+ SubdomainFu.subdomain_from("localhost").should be_nil
66
+ end
67
+ end
68
+
69
+ it "#host_without_subdomain should chop of the subdomain and return the rest" do
70
+ SubdomainFu.host_without_subdomain("awesome.localhost:3000").should == "localhost:3000"
71
+ SubdomainFu.host_without_subdomain("something.awful.localhost:3000").should == "localhost:3000"
72
+ end
73
+
74
+ describe "#preferred_mirror?" do
75
+ describe "when preferred_mirror is false" do
76
+ before do
77
+ SubdomainFu.preferred_mirror = false
78
+ end
79
+
80
+ it "should return true for false" do
81
+ SubdomainFu.preferred_mirror?(false).should be_true
82
+ end
83
+ end
84
+ end
85
+
86
+ describe "#rewrite_host_for_subdomains" do
87
+ it "should not change the same subdomain" do
88
+ SubdomainFu.rewrite_host_for_subdomains("awesome","awesome.localhost").should == "awesome.localhost"
89
+ end
90
+
91
+ it "should not change an equivalent (mirrored) subdomain" do
92
+ SubdomainFu.rewrite_host_for_subdomains("www","localhost").should == "localhost"
93
+ end
94
+
95
+ it "should change the subdomain if it's different" do
96
+ SubdomainFu.rewrite_host_for_subdomains("cool","www.localhost").should == "cool.localhost"
97
+ end
98
+
99
+ it "should remove the subdomain if passed false when it's not a mirror" do
100
+ SubdomainFu.rewrite_host_for_subdomains(false,"cool.localhost").should == "localhost"
101
+ end
102
+
103
+ it "should not remove the subdomain if passed false when it is a mirror" do
104
+ SubdomainFu.rewrite_host_for_subdomains(false,"www.localhost").should == "www.localhost"
105
+ end
106
+
107
+ it "should not remove the subdomain if passed nil when it's not a mirror" do
108
+ SubdomainFu.rewrite_host_for_subdomains(nil,"cool.localhost").should == "cool.localhost"
109
+ end
110
+
111
+ describe "when preferred_mirror is false" do
112
+ before do
113
+ SubdomainFu.preferred_mirror = false
114
+ end
115
+
116
+ it "should remove the subdomain if passed false when it is a mirror" do
117
+ SubdomainFu.rewrite_host_for_subdomains(false,"www.localhost").should == "localhost"
118
+ end
119
+
120
+ it "should not remove the subdomain if passed nil when it's not a mirror" do
121
+ SubdomainFu.rewrite_host_for_subdomains(nil,"cool.localhost").should == "cool.localhost"
122
+ end
123
+ end
124
+ end
125
+
126
+ describe "#change_subdomain_of_host" do
127
+ it "should change it if passed a different one" do
128
+ SubdomainFu.change_subdomain_of_host("awesome","cool.localhost").should == "awesome.localhost"
129
+ end
130
+
131
+ it "should remove it if passed nil" do
132
+ SubdomainFu.change_subdomain_of_host(nil,"cool.localhost").should == "localhost"
133
+ end
134
+
135
+ it "should add it if there isn't one" do
136
+ SubdomainFu.change_subdomain_of_host("awesome","localhost").should == "awesome.localhost"
137
+ end
138
+ end
139
+
140
+ describe "#current_subdomain" do
141
+ it "should return the current subdomain if there is one" do
142
+ request = mock("request", :subdomains => ["awesome"])
143
+ SubdomainFu.current_subdomain(request).should == "awesome"
144
+ end
145
+
146
+ it "should return nil if there's no subdomain" do
147
+ request = mock("request", :subdomains => [])
148
+ SubdomainFu.current_subdomain(request).should be_nil
149
+ end
150
+
151
+ it "should return nil if the current subdomain is a mirror" do
152
+ request = mock("request", :subdomains => ["www"])
153
+ SubdomainFu.current_subdomain(request).should be_nil
154
+ end
155
+
156
+ it "should return the whole thing (including a .) if there's multiple subdomains" do
157
+ request = mock("request", :subdomains => ["awesome","rad"])
158
+ SubdomainFu.current_subdomain(request).should == "awesome.rad"
159
+ end
160
+ end
161
+
162
+ describe "#same_subdomain?" do
163
+ it { SubdomainFu.same_subdomain?("www","www.localhost").should be_true }
164
+ it { SubdomainFu.same_subdomain?("www","localhost").should be_true }
165
+ it { SubdomainFu.same_subdomain?("awesome","www.localhost").should be_false }
166
+ it { SubdomainFu.same_subdomain?("cool","awesome.localhost").should be_false }
167
+ it { SubdomainFu.same_subdomain?(nil,"www.localhost").should be_true }
168
+ it { SubdomainFu.same_subdomain?("www","awesome.localhost").should be_false }
169
+ end
170
+
171
+ describe "#needs_rewrite?" do
172
+ it { SubdomainFu.needs_rewrite?("www","www.localhost").should be_false }
173
+ it { SubdomainFu.needs_rewrite?("www","localhost").should be_false }
174
+ it { SubdomainFu.needs_rewrite?("awesome","www.localhost").should be_true }
175
+ it { SubdomainFu.needs_rewrite?("cool","awesome.localhost").should be_true }
176
+ it { SubdomainFu.needs_rewrite?(nil,"www.localhost").should be_false }
177
+ it { SubdomainFu.needs_rewrite?(nil,"awesome.localhost").should be_false }
178
+ it { SubdomainFu.needs_rewrite?(false,"awesome.localhost").should be_true }
179
+ it { SubdomainFu.needs_rewrite?(false,"www.localhost").should be_false }
180
+ it { SubdomainFu.needs_rewrite?("www","awesome.localhost").should be_true }
181
+
182
+ describe "when preferred_mirror is false" do
183
+ before do
184
+ SubdomainFu.preferred_mirror = false
185
+ end
186
+
187
+ it { SubdomainFu.needs_rewrite?("www","www.localhost").should be_false }
188
+ it { SubdomainFu.needs_rewrite?("www","localhost").should be_false }
189
+ it { SubdomainFu.needs_rewrite?("awesome","www.localhost").should be_true }
190
+ it { SubdomainFu.needs_rewrite?("cool","awesome.localhost").should be_true }
191
+ it { SubdomainFu.needs_rewrite?(nil,"www.localhost").should be_false }
192
+ it { SubdomainFu.needs_rewrite?(nil,"awesome.localhost").should be_false }
193
+ it { SubdomainFu.needs_rewrite?(false,"awesome.localhost").should be_true }
194
+ #Only one different from default set of tests
195
+ it { SubdomainFu.needs_rewrite?(false,"www.localhost").should be_true }
196
+ it { SubdomainFu.needs_rewrite?("www","awesome.localhost").should be_true }
197
+ end
198
+
199
+ describe "when preferred_mirror is string" do
200
+ before do
201
+ SubdomainFu.preferred_mirror = "www"
202
+ end
203
+
204
+ it { SubdomainFu.needs_rewrite?("www","www.localhost").should be_false }
205
+ it { SubdomainFu.needs_rewrite?("awesome","www.localhost").should be_true }
206
+ # Following is different from default set of tests
207
+ it { SubdomainFu.needs_rewrite?("www","localhost").should be_true }
208
+ it { SubdomainFu.needs_rewrite?("cool","awesome.localhost").should be_true }
209
+ it { SubdomainFu.needs_rewrite?(nil,"www.localhost").should be_false }
210
+ it { SubdomainFu.needs_rewrite?(nil,"awesome.localhost").should be_false }
211
+ it { SubdomainFu.needs_rewrite?(false,"awesome.localhost").should be_true }
212
+ it { SubdomainFu.needs_rewrite?(false,"www.localhost").should be_false }
213
+ it { SubdomainFu.needs_rewrite?("www","awesome.localhost").should be_true }
214
+ end
215
+
216
+ end
217
+ end
@@ -0,0 +1,149 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ describe "SubdomainFu URL Writing" do
4
+ before do
5
+ SubdomainFu.tld_size = 1
6
+ SubdomainFu.mirrors = SubdomainFu::DEFAULT_MIRRORS.dup
7
+ SubdomainFu.override_only_path = true
8
+ SubdomainFu.preferred_mirror = nil
9
+ default_url_options[:host] = "example.com"
10
+ end
11
+
12
+ describe "#url_for" do
13
+ it "should be able to add a subdomain" do
14
+ url_for(:controller => "something", :action => "other", :subdomain => "awesome").should == "http://awesome.example.com/something/other"
15
+ end
16
+
17
+ it "should be able to remove a subdomain" do
18
+ url_for(:controller => "something", :action => "other", :subdomain => false, :host => "awesome.example.com").should == "http://example.com/something/other"
19
+ end
20
+
21
+ it "should not change a mirrored subdomain" do
22
+ url_for(:controller => "something", :action => "other", :subdomain => false, :host => "www.example.com").should == "http://www.example.com/something/other"
23
+ end
24
+
25
+ it "should should not force the full url with :only_path if override_only_path is false (default)" do
26
+ SubdomainFu.override_only_path = false
27
+ url_for(:controller => "something", :action => "other", :subdomain => "awesome", :only_path => true).should == "/something/other"
28
+ end
29
+
30
+ it "should should force the full url, even with :only_path if override_only_path is true" do
31
+ SubdomainFu.override_only_path = true
32
+ url_for(:controller => "something", :action => "other", :subdomain => "awesome", :only_path => true).should == "http://awesome.example.com/something/other"
33
+ end
34
+ end
35
+
36
+ describe "Standard Routes" do
37
+ it "should be able to add a subdomain" do
38
+ needs_subdomain_url(:subdomain => "awesome").should == "http://awesome.example.com/needs_subdomain"
39
+ end
40
+
41
+ it "should be able to remove a subdomain" do
42
+ default_url_options[:host] = "awesome.example.com"
43
+ needs_subdomain_url(:subdomain => false).should == "http://example.com/needs_subdomain"
44
+ end
45
+
46
+ it "should not change a mirrored subdomain" do
47
+ default_url_options[:host] = "www.example.com"
48
+ needs_subdomain_url(:subdomain => false).should == "http://www.example.com/needs_subdomain"
49
+ end
50
+
51
+ it "should should force the full url, even with _path" do
52
+ needs_subdomain_path(:subdomain => "awesome").should == needs_subdomain_url(:subdomain => "awesome")
53
+ end
54
+
55
+ it "should not force the full url if it's the same as the current subdomain" do
56
+ default_url_options[:host] = "awesome.example.com"
57
+ needs_subdomain_path(:subdomain => "awesome").should == "/needs_subdomain"
58
+ end
59
+
60
+ it "should force the full url if it's a different subdomain" do
61
+ default_url_options[:host] = "awesome.example.com"
62
+ needs_subdomain_path(:subdomain => "crazy").should == "http://crazy.example.com/needs_subdomain"
63
+ end
64
+
65
+ it "should not force the full url if the current subdomain is nil and so is the target" do
66
+ needs_subdomain_path(:subdomain => nil).should == "/needs_subdomain"
67
+ end
68
+
69
+ it "should not force the full url if no :subdomain option is given" do
70
+ needs_subdomain_path.should == "/needs_subdomain"
71
+ default_url_options[:host] = "awesome.example.com"
72
+ needs_subdomain_path.should == "/needs_subdomain"
73
+ end
74
+ end
75
+
76
+ describe "Resourced Routes" do
77
+ it "should be able to add a subdomain" do
78
+ foo_path(:id => "something", :subdomain => "awesome").should == "http://awesome.example.com/foos/something"
79
+ end
80
+
81
+ it "should be able to remove a subdomain" do
82
+ default_url_options[:host] = "awesome.example.com"
83
+ foo_path(:id => "something", :subdomain => false).should == "http://example.com/foos/something"
84
+ end
85
+
86
+ it "should work when passed in a paramable object" do
87
+ foo_path(Paramed.new("something"), :subdomain => "awesome").should == "http://awesome.example.com/foos/something"
88
+ end
89
+
90
+ it "should work when passed in a paramable object" do
91
+ foo_path(Paramed.new("something"), :subdomain => "awesome").should == "http://awesome.example.com/foos/something"
92
+ end
93
+
94
+ it "should work when passed in a paramable object and no subdomain to a _path" do
95
+ default_url_options[:host] = "awesome.example.com"
96
+ foo_path(Paramed.new("something")).should == "/foos/something"
97
+ end
98
+
99
+ it "should work when passed in a paramable object and no subdomain to a _url" do
100
+ default_url_options[:host] = "awesome.example.com"
101
+ foo_url(Paramed.new("something")).should == "http://awesome.example.com/foos/something"
102
+ end
103
+
104
+ it "should work on nested resource collections" do
105
+ foo_bars_path(Paramed.new("something"), :subdomain => "awesome").should == "http://awesome.example.com/foos/something/bars"
106
+ end
107
+
108
+ it "should work on nested resource members" do
109
+ foo_bar_path(Paramed.new("something"),Paramed.new("else"), :subdomain => "awesome").should == "http://awesome.example.com/foos/something/bars/else"
110
+ end
111
+ end
112
+
113
+ describe "Preferred Mirror" do
114
+ before do
115
+ SubdomainFu.preferred_mirror = "www"
116
+ SubdomainFu.override_only_path = true
117
+ end
118
+
119
+ it "should switch to the preferred mirror instead of no subdomain" do
120
+ default_url_options[:host] = "awesome.example.com"
121
+ needs_subdomain_url(:subdomain => false).should == "http://www.example.com/needs_subdomain"
122
+ end
123
+
124
+ it "should switch to the preferred mirror automatically" do
125
+ default_url_options[:host] = "example.com"
126
+ needs_subdomain_url.should == "http://www.example.com/needs_subdomain"
127
+ end
128
+
129
+ it "should work when passed in a paramable object and no subdomain to a _url" do
130
+ default_url_options[:host] = "awesome.example.com"
131
+ foo_url(Paramed.new("something")).should == "http://awesome.example.com/foos/something"
132
+ end
133
+
134
+ it "should force a switch to no subdomain on a mirror if preferred_mirror is false" do
135
+ SubdomainFu.preferred_mirror = false
136
+ default_url_options[:host] = "www.example.com"
137
+ needs_subdomain_url(:subdomain => false).should == "http://example.com/needs_subdomain"
138
+ end
139
+
140
+ after do
141
+ SubdomainFu.preferred_mirror = nil
142
+ end
143
+ end
144
+
145
+ after do
146
+ SubdomainFu.tld_size = 0
147
+ default_url_options[:host] = "localhost"
148
+ end
149
+ end
metadata ADDED
@@ -0,0 +1,69 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: subdomain-fu
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.4.0
5
+ platform: ruby
6
+ authors:
7
+ - Michael Bleigh
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-08-31 00:00:00 -04:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: SubdomainFu is a Rails plugin to provide all of the basic functionality necessary to handle multiple subdomain applications (such as Basecamp-esque subdomain accounts and more).
17
+ email: michael@intridea.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - README.rdoc
24
+ files:
25
+ - CHANGELOG
26
+ - MIT-LICENSE
27
+ - README.rdoc
28
+ - Rakefile
29
+ - VERSION.yml
30
+ - lib/subdomain-fu.rb
31
+ - lib/subdomain_fu/routing_extensions.rb
32
+ - lib/subdomain_fu/url_rewriter.rb
33
+ - rails/init.rb
34
+ - spec/spec.opts
35
+ - spec/spec_helper.rb
36
+ - spec/subdomain_fu_spec.rb
37
+ - spec/url_rewriter_spec.rb
38
+ has_rdoc: true
39
+ homepage: http://github.com/mbleigh/subdomain-fu
40
+ licenses: []
41
+
42
+ post_install_message:
43
+ rdoc_options:
44
+ - --charset=UTF-8
45
+ require_paths:
46
+ - lib
47
+ required_ruby_version: !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - ">="
50
+ - !ruby/object:Gem::Version
51
+ version: "0"
52
+ version:
53
+ required_rubygems_version: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ version: "0"
58
+ version:
59
+ requirements: []
60
+
61
+ rubyforge_project:
62
+ rubygems_version: 1.3.3
63
+ signing_key:
64
+ specification_version: 3
65
+ summary: SubdomainFu is a Rails plugin that provides subdomain routing and URL writing helpers.
66
+ test_files:
67
+ - spec/spec_helper.rb
68
+ - spec/subdomain_fu_spec.rb
69
+ - spec/url_rewriter_spec.rb