gameplan-subdomain-fu 0.5.4

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,20 @@
1
+ == 2009-09-13
2
+
3
+ * Added current_domain method
4
+ * Added controller & view usage to readme
5
+ * Added more tests
6
+ * Fixing load paths
7
+
8
+ == 2009-08-26
9
+
10
+ * Fixed needs_rewrite? method
11
+ * Added is_mirror? method
12
+ * Added tests, and fixed failing tests
13
+
14
+ == 2009-08-24
15
+
16
+ * Merged forks that added lots of features, tests, and fixes
17
+
18
+ == 2008-06-25
19
+
20
+ * 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,110 @@
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 gem, add it to your config/environment.rb:
16
+
17
+ config.gem '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
+ == Use in controllers and views
49
+
50
+ You have access to current_subdomain and current_domain methods.
51
+
52
+ [current_subdomain] returns all subdomains. For the URL http://awesome.website.stuff.example.com, it will return "awesome.website.stuff"
53
+
54
+ [current_domain] returns all subdomains except for the subdomain, including the TLD. For the URL http://awesome.website.stuff.example.com, it will return "website.stuff.example.com"
55
+
56
+ If what you really want is the entire domain, then use <tt>request.domain</tt> in
57
+ your controllers. The purpose of current_domain is to only strip off the first
58
+ subdomain, if any, and return what's left.
59
+
60
+ == Configuration
61
+
62
+ You may need to configure SubdomainFu based on your development setup. The
63
+ configuration required is:
64
+
65
+ === TLD Size
66
+
67
+ A hash for each environment of the size of the top-level domain name.
68
+ (something.com = 1, localhost = 0, etc.)
69
+
70
+ SubdomainFu.tld_size = 1 # sets for current environment
71
+ SubdomainFu.tld_sizes = {:development => 0,
72
+ :test => 0,
73
+ :production => 1} # set all at once (also the defaults)
74
+
75
+ === Mirrors
76
+
77
+ Mirrors are the subdomains that are equivalent to no subdomain (i.e. they 'mirror')
78
+ the usage of the root domain.
79
+
80
+ SubdomainFu.mirrors = %w(www site we) # Defaults to %w(www)
81
+
82
+ === Preferred Mirror
83
+
84
+ SubdomainFu also understands the notion of a 'preferred mirror', that is, if you
85
+ always want your links going to 'www.yourdomain.com' instead of 'yourdomain.com',
86
+ you can set the preferred mirror like so:
87
+
88
+ SubdomainFu.preferred_mirror = "www"
89
+
90
+ Now when you create a link with <tt>:subdomain => false</tt> in the options the subdomain
91
+ will default to the preferred mirror.
92
+
93
+ == Routing
94
+
95
+ 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 <tt>config/routes.rb</tt> file:
96
+
97
+ map.with_options :conditions => {:subdomain => 'admin'} do |admin|
98
+ admin.resources :posts
99
+ admin.resources :users
100
+ end
101
+
102
+ In addition to specifying a string, you could also specify <tt>false</tt> to require no subdomain (this includes mirrors that you've set up such as www) or a regular expression to match a range of subdomains.
103
+
104
+ == Resources
105
+
106
+ * GitHub Repository: http://github.com/mbleigh/subdomain-fu
107
+ * RDocs: http://rdoc.info/projects/mbleigh/subdomain-fu
108
+
109
+ Copyright (c) 2008 Michael Bleigh (http://www.mbleigh.com/) and
110
+ Intridea, Inc. (http://www.intridea.com/). Released under the MIT license
data/Rakefile ADDED
@@ -0,0 +1,56 @@
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.rubyforge_project = 'subdomain-fu'
18
+ gemspec.summary = "SubdomainFu is a Rails plugin that provides subdomain routing and URL writing helpers."
19
+ gemspec.email = "michael@intridea.com"
20
+ gemspec.homepage = "http://github.com/mbleigh/subdomain-fu"
21
+ gemspec.files = FileList["[A-Z]*", "{lib,spec,rails}/**/*"] - FileList["**/*.log"]
22
+ 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)."
23
+ gemspec.authors = ["Michael Bleigh"]
24
+ end
25
+ Jeweler::GemcutterTasks.new
26
+ rescue LoadError
27
+ puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
28
+ end
29
+
30
+
31
+ # These are new tasks
32
+ begin
33
+ require 'rake/contrib/sshpublisher'
34
+ namespace :rubyforge do
35
+
36
+ desc "Release gem and RDoc documentation to RubyForge"
37
+ task :release => ["rubyforge:release:gem", "rubyforge:release:docs"]
38
+
39
+ namespace :release do
40
+ desc "Publish RDoc to RubyForge."
41
+ task :docs => [:rdoc] do
42
+ config = YAML.load(
43
+ File.read(File.expand_path('~/.rubyforge/user-config.yml'))
44
+ )
45
+
46
+ host = "#{config['username']}@rubyforge.org"
47
+ remote_dir = "/var/www/gforge-projects/the-perfect-gem/"
48
+ local_dir = 'rdoc'
49
+
50
+ Rake::SshDirPublisher.new(host, remote_dir, local_dir).upload
51
+ end
52
+ end
53
+ end
54
+ rescue LoadError
55
+ puts "Rake SshDirPublisher is unavailable or your rubyforge environment is not configured."
56
+ end
data/VERSION.yml ADDED
@@ -0,0 +1,5 @@
1
+ ---
2
+ :major: 0
3
+ :build:
4
+ :minor: 5
5
+ :patch: 4
@@ -0,0 +1,163 @@
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
+ subdomain_string = (subdomain && subdomain.respond_to?(:to_param)) ? subdomain.to_param : subdomain
86
+
87
+ host = SubdomainFu.host_without_subdomain(host)
88
+ host = "#{subdomain_string}.#{host}" if subdomain_string
89
+ host
90
+ end
91
+
92
+ # Is this subdomain equivalent to the subdomain found in this host string?
93
+ def self.same_subdomain?(subdomain, host)
94
+ subdomain = nil unless subdomain
95
+ (subdomain == subdomain_from(host)) ||
96
+ (!has_subdomain?(subdomain) && !has_subdomain?(subdomain_from(host)))
97
+ end
98
+
99
+ def self.override_only_path?
100
+ self.override_only_path
101
+ end
102
+
103
+ def self.needs_rewrite?(subdomain, host)
104
+ case subdomain
105
+ when nil
106
+ #rewrite when there is a preferred mirror set and there is no subdomain on the host
107
+ return true if self.preferred_mirror && subdomain_from(host).nil?
108
+ return false
109
+ when false
110
+ h = subdomain_from(host)
111
+ #if the host has a subdomain
112
+ if !h.nil?
113
+ #rewrite when there is a subdomain in the host, and it is not a preferred mirror
114
+ return true if !preferred_mirror?(h)
115
+ #rewrite when there is a preferred mirror set and the subdomain of the host is not a mirror
116
+ return true if self.preferred_mirror && !is_mirror?(h)
117
+ #no rewrite if host already has mirror subdomain
118
+ #it { SubdomainFu.needs_rewrite?(false,"www.localhost").should be_false }
119
+ return false if is_mirror?(h)
120
+ end
121
+ return self.crazy_rewrite_rule(subdomain, host)
122
+ else
123
+ return self.crazy_rewrite_rule(subdomain, host)
124
+ end
125
+ end
126
+
127
+ #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!
128
+ def self.crazy_rewrite_rule(subdomain, host)
129
+ (!has_subdomain?(subdomain) && preferred_mirror?(subdomain) && !preferred_mirror?(subdomain_from(host))) ||
130
+ !same_subdomain?(subdomain, host)
131
+ end
132
+
133
+ def self.current_subdomain(request)
134
+ subdomain = request.subdomains(SubdomainFu.tld_size).join(".")
135
+ if has_subdomain?(subdomain)
136
+ subdomain
137
+ else
138
+ nil
139
+ end
140
+ end
141
+
142
+ #Enables subdomain-fu to more completely replace DHH's account_location plugin
143
+ def self.current_domain(request)
144
+ domain = ""
145
+ domain << request.subdomains[1..-1].join(".") + "." if request.subdomains.length > 1
146
+ domain << request.domain + request.port_string
147
+ end
148
+
149
+ module Controller
150
+ def self.included(controller)
151
+ controller.helper_method(:current_subdomain)
152
+ controller.helper_method(:current_domain)
153
+ end
154
+
155
+ protected
156
+ def current_subdomain
157
+ SubdomainFu.current_subdomain(request)
158
+ end
159
+ def current_domain
160
+ SubdomainFu.current_domain(request)
161
+ end
162
+ end
163
+ 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.current_subdomain(request))
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,6 @@
1
+ #Allow whatever Ruby Package tool is being used ot manage load paths. gem auto adds the gem's lib dir to load path.
2
+ require 'subdomain-fu' unless defined?(SubdomainFu)
3
+
4
+ ActionController::Base.send :include, SubdomainFu::Controller
5
+
6
+ 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,251 @@
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
+
139
+ it "should use to_param on the object passed to subdomain if it respond to it" do
140
+ @some_other_object = Paramed.new("p_is_awesome")
141
+
142
+ SubdomainFu.change_subdomain_of_host(@some_other_object,"localhost").should == "p_is_awesome.localhost"
143
+ end
144
+
145
+ end
146
+
147
+ describe "#current_subdomain" do
148
+ it "should return the current subdomain if there is one" do
149
+ request = mock("request", :subdomains => ["awesome"])
150
+ SubdomainFu.current_subdomain(request).should == "awesome"
151
+ end
152
+
153
+ it "should return nil if there's no subdomain" do
154
+ request = mock("request", :subdomains => [])
155
+ SubdomainFu.current_subdomain(request).should be_nil
156
+ end
157
+
158
+ it "should return nil if the current subdomain is a mirror" do
159
+ request = mock("request", :subdomains => ["www"])
160
+ SubdomainFu.current_subdomain(request).should be_nil
161
+ end
162
+
163
+ it "should return the whole thing (including a .) if there's multiple subdomains" do
164
+ request = mock("request", :subdomains => ["awesome","rad"])
165
+ SubdomainFu.current_subdomain(request).should == "awesome.rad"
166
+ end
167
+ end
168
+
169
+ describe "#current_domain" do
170
+ it "should return the current domain if there is one" do
171
+ request = mock("request", :subdomains => [], :domain => "example.com", :port_string => "")
172
+ SubdomainFu.current_domain(request).should == "example.com"
173
+ end
174
+
175
+ it "should return empty string if there is no domain" do
176
+ request = mock("request", :subdomains => [], :domain => "", :port_string => "")
177
+ SubdomainFu.current_domain(request).should == ""
178
+ end
179
+
180
+ it "should return the current domain if there is only one level of subdomains" do
181
+ request = mock("request", :subdomains => ["www"], :domain => "example.com", :port_string => "")
182
+ SubdomainFu.current_domain(request).should == "example.com"
183
+ end
184
+
185
+ it "should return everything but the first level of subdomain when there are multiple levels of subdomains" do
186
+ request = mock("request", :subdomains => ["awesome","rad","cheese","chevy","ford"], :domain => "example.com", :port_string => "")
187
+ SubdomainFu.current_domain(request).should == "rad.cheese.chevy.ford.example.com"
188
+ end
189
+
190
+ it "should return the domain with port if port is given" do
191
+ request = mock("request", :subdomains => ["awesome","rad","cheese","chevy","ford"], :domain => "example.com", :port_string => ":3000")
192
+ SubdomainFu.current_domain(request).should == "rad.cheese.chevy.ford.example.com:3000"
193
+ end
194
+ end
195
+
196
+ describe "#same_subdomain?" do
197
+ it { SubdomainFu.same_subdomain?("www","www.localhost").should be_true }
198
+ it { SubdomainFu.same_subdomain?("www","localhost").should be_true }
199
+ it { SubdomainFu.same_subdomain?("awesome","www.localhost").should be_false }
200
+ it { SubdomainFu.same_subdomain?("cool","awesome.localhost").should be_false }
201
+ it { SubdomainFu.same_subdomain?(nil,"www.localhost").should be_true }
202
+ it { SubdomainFu.same_subdomain?("www","awesome.localhost").should be_false }
203
+ end
204
+
205
+ describe "#needs_rewrite?" do
206
+ it { SubdomainFu.needs_rewrite?("www","www.localhost").should be_false }
207
+ it { SubdomainFu.needs_rewrite?("www","localhost").should be_false }
208
+ it { SubdomainFu.needs_rewrite?("awesome","www.localhost").should be_true }
209
+ it { SubdomainFu.needs_rewrite?("cool","awesome.localhost").should be_true }
210
+ it { SubdomainFu.needs_rewrite?(nil,"www.localhost").should be_false }
211
+ it { SubdomainFu.needs_rewrite?(nil,"awesome.localhost").should be_false }
212
+ it { SubdomainFu.needs_rewrite?(false,"awesome.localhost").should be_true }
213
+ it { SubdomainFu.needs_rewrite?(false,"www.localhost").should be_false }
214
+ it { SubdomainFu.needs_rewrite?("www","awesome.localhost").should be_true }
215
+
216
+ describe "when preferred_mirror is false" do
217
+ before do
218
+ SubdomainFu.preferred_mirror = false
219
+ end
220
+
221
+ it { SubdomainFu.needs_rewrite?("www","www.localhost").should be_false }
222
+ it { SubdomainFu.needs_rewrite?("www","localhost").should be_false }
223
+ it { SubdomainFu.needs_rewrite?("awesome","www.localhost").should be_true }
224
+ it { SubdomainFu.needs_rewrite?("cool","awesome.localhost").should be_true }
225
+ it { SubdomainFu.needs_rewrite?(nil,"www.localhost").should be_false }
226
+ it { SubdomainFu.needs_rewrite?(nil,"awesome.localhost").should be_false }
227
+ it { SubdomainFu.needs_rewrite?(false,"awesome.localhost").should be_true }
228
+ #Only one different from default set of tests
229
+ it { SubdomainFu.needs_rewrite?(false,"www.localhost").should be_true }
230
+ it { SubdomainFu.needs_rewrite?("www","awesome.localhost").should be_true }
231
+ end
232
+
233
+ describe "when preferred_mirror is string" do
234
+ before do
235
+ SubdomainFu.preferred_mirror = "www"
236
+ end
237
+
238
+ it { SubdomainFu.needs_rewrite?("www","www.localhost").should be_false }
239
+ it { SubdomainFu.needs_rewrite?("awesome","www.localhost").should be_true }
240
+ # Following is different from default set of tests
241
+ it { SubdomainFu.needs_rewrite?("www","localhost").should be_true }
242
+ it { SubdomainFu.needs_rewrite?("cool","awesome.localhost").should be_true }
243
+ it { SubdomainFu.needs_rewrite?(nil,"www.localhost").should be_false }
244
+ it { SubdomainFu.needs_rewrite?(nil,"awesome.localhost").should be_false }
245
+ it { SubdomainFu.needs_rewrite?(false,"awesome.localhost").should be_true }
246
+ it { SubdomainFu.needs_rewrite?(false,"www.localhost").should be_false }
247
+ it { SubdomainFu.needs_rewrite?("www","awesome.localhost").should be_true }
248
+ end
249
+
250
+ end
251
+ 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,76 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: gameplan-subdomain-fu
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 5
8
+ - 4
9
+ version: 0.5.4
10
+ platform: ruby
11
+ authors:
12
+ - Michael Bleigh
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-05-12 00:00:00 +08:00
18
+ default_executable:
19
+ dependencies: []
20
+
21
+ 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
+ email: michael@intridea.com
23
+ executables: []
24
+
25
+ extensions: []
26
+
27
+ extra_rdoc_files:
28
+ - README.rdoc
29
+ files:
30
+ - CHANGELOG
31
+ - MIT-LICENSE
32
+ - README.rdoc
33
+ - Rakefile
34
+ - VERSION.yml
35
+ - lib/subdomain-fu.rb
36
+ - lib/subdomain_fu/routing_extensions.rb
37
+ - lib/subdomain_fu/url_rewriter.rb
38
+ - rails/init.rb
39
+ - spec/spec.opts
40
+ - spec/spec_helper.rb
41
+ - spec/subdomain_fu_spec.rb
42
+ - spec/url_rewriter_spec.rb
43
+ has_rdoc: true
44
+ homepage: http://github.com/mbleigh/subdomain-fu
45
+ licenses: []
46
+
47
+ post_install_message:
48
+ rdoc_options:
49
+ - --charset=UTF-8
50
+ require_paths:
51
+ - lib
52
+ required_ruby_version: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ segments:
57
+ - 0
58
+ version: "0"
59
+ required_rubygems_version: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ segments:
64
+ - 0
65
+ version: "0"
66
+ requirements: []
67
+
68
+ rubyforge_project: subdomain-fu
69
+ rubygems_version: 1.3.6
70
+ signing_key:
71
+ specification_version: 3
72
+ summary: SubdomainFu is a Rails plugin that provides subdomain routing and URL writing helpers.
73
+ test_files:
74
+ - spec/spec_helper.rb
75
+ - spec/subdomain_fu_spec.rb
76
+ - spec/url_rewriter_spec.rb