add validations to site
This commit is contained in:
parent
ff6fcf43f1
commit
3b8a6c67df
8
Gemfile
8
Gemfile
@ -15,10 +15,10 @@ gem "devise", ">= 1.1.rc0"
|
|||||||
# Development environment
|
# Development environment
|
||||||
group :development do
|
group :development do
|
||||||
# Using mongrel instead of webrick (default server)
|
# Using mongrel instead of webrick (default server)
|
||||||
gem "mongrel"
|
# gem "mongrel"
|
||||||
gem "cgi_multipart_eof_fix"
|
# gem "cgi_multipart_eof_fix"
|
||||||
gem "fastthread"
|
# gem "fastthread"
|
||||||
gem "mongrel_experimental"
|
# gem "mongrel_experimental"
|
||||||
end
|
end
|
||||||
|
|
||||||
group :test do
|
group :test do
|
||||||
|
@ -4,29 +4,51 @@ class Site
|
|||||||
|
|
||||||
## fields ##
|
## fields ##
|
||||||
field :name
|
field :name
|
||||||
|
field :subdomain, :type => String
|
||||||
field :domains, :type => Array, :default => []
|
field :domains, :type => Array, :default => []
|
||||||
|
|
||||||
## validations ##
|
## validations ##
|
||||||
validates_presence_of :name
|
validates_presence_of :name, :subdomain
|
||||||
validates_length_of :domains, :minimum => 1
|
validates_uniqueness_of :subdomain
|
||||||
# validates_each :domains, :logic => :domains_are_unique_and_valid
|
validates_exclusion_of :subdomain, :in => Locomotive::Configuration.forbidden_subdomains
|
||||||
|
validates_format_of :subdomain, :with => Locomotive::Regexps::SUBDOMAIN, :allow_blank => true
|
||||||
|
validate :domains_must_be_valid_and_unique
|
||||||
|
|
||||||
|
## callbacks ##
|
||||||
|
before_save :add_subdomain_to_domains
|
||||||
|
|
||||||
|
## named scopes ##
|
||||||
|
named_scope :match_domain, lambda { |domain| { :where => { :domains => domain } } }
|
||||||
|
named_scope :match_domain_with_exclusion_of, lambda { |domain, site| { :where => { :domains => domain, :id.ne => site.id } } }
|
||||||
|
|
||||||
## behaviours ##
|
## behaviours ##
|
||||||
# timestamps!
|
add_dirty_methods :domains
|
||||||
|
|
||||||
## methods ##
|
## methods ##
|
||||||
|
|
||||||
def subdomain=(value)
|
def add_subdomain_to_domains
|
||||||
return if value.blank?
|
self.domains ||= []
|
||||||
(self.domains << "#{value}.#{Locomotive::Configuration.default_domain_name}").uniq!
|
(self.domains << "#{self.subdomain}.#{Locomotive::Configuration.default_domain}").uniq!
|
||||||
|
end
|
||||||
|
|
||||||
|
def domains_without_subdomain
|
||||||
|
(self.domains || []) - ["#{self.subdomain}.#{Locomotive::Configuration.default_domain}"]
|
||||||
end
|
end
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
||||||
def domains_are_unique_and_valid
|
def domains_must_be_valid_and_unique
|
||||||
# self.domains.each do |domain|
|
return if self.domains.empty? || (!self.new_record? && !self.domains_changed?)
|
||||||
# self.errors.add(:domains, t())
|
|
||||||
# end
|
(self.domains_without_subdomain - (self.domains_was || [])) .each do |domain|
|
||||||
|
if not self.class.match_domain_with_exclusion_of(domain, self).first.nil?
|
||||||
|
self.errors.add(:domains, :domain_taken, :value => domain)
|
||||||
|
end
|
||||||
|
|
||||||
|
if not domain =~ Locomotive::Regexps::DOMAIN
|
||||||
|
self.errors.add(:domains, :invalid_domain, :value => domain)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
@ -1,3 +1,3 @@
|
|||||||
Locomotive::Configuration.setup do |config|
|
Locomotive::Configuration.setup do |config|
|
||||||
config.default_domain_name = 'example.com'
|
config.default_domain = 'example.com'
|
||||||
end
|
end
|
2
config/locales/admin_ui_en.yml
Normal file
2
config/locales/admin_ui_en.yml
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
en:
|
||||||
|
hello: "Hello world"
|
2
config/locales/admin_ui_fr.yml
Normal file
2
config/locales/admin_ui_fr.yml
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
fr:
|
||||||
|
hello: 'Bonjour le monde'
|
5
config/locales/default_en.yml
Normal file
5
config/locales/default_en.yml
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
en:
|
||||||
|
errors:
|
||||||
|
messages:
|
||||||
|
domain_taken: "{{value}} is already taken"
|
||||||
|
invalid_domain: "{{value}} is invalid"
|
29
config/locales/default_fr.yml
Normal file
29
config/locales/default_fr.yml
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
fr:
|
||||||
|
errors:
|
||||||
|
# The default format use in full error messages.
|
||||||
|
format: "{{attribute}} {{message}}"
|
||||||
|
|
||||||
|
# The values :model, :attribute and :value are always available for interpolation
|
||||||
|
# The value :count is available when applicable. Can be used for pluralization.
|
||||||
|
messages:
|
||||||
|
inclusion: "n'est pas inclus(e) dans la liste"
|
||||||
|
exclusion: "n'est pas disponible"
|
||||||
|
invalid: "n'est pas valide"
|
||||||
|
confirmation: "ne concorde pas avec la confirmation"
|
||||||
|
accepted: "doit être accepté(e)"
|
||||||
|
empty: "doit être rempli(e)"
|
||||||
|
blank: "doit être rempli(e)"
|
||||||
|
too_long: "est trop long (pas plus de {{count}} caractères)"
|
||||||
|
too_short: "est trop court (au moins {{count}} caractères)"
|
||||||
|
wrong_length: "ne fait pas la bonne longueur (doit comporter {{count}} caractères)"
|
||||||
|
taken: "n'est pas disponible"
|
||||||
|
not_a_number: "n'est pas un nombre"
|
||||||
|
greater_than: "doit être supérieur à {{count}}"
|
||||||
|
greater_than_or_equal_to: "doit être supérieur ou égal à {{count}}"
|
||||||
|
equal_to: "doit être égal à {{count}}"
|
||||||
|
less_than: "doit être inférieur à {{count}}"
|
||||||
|
less_than_or_equal_to: "doit être inférieur ou égal à {{count}}"
|
||||||
|
odd: "doit être impair"
|
||||||
|
even: "doit être pair"
|
||||||
|
|
||||||
|
domain_taken: "{{value}} a été déjà pris"
|
@ -1,5 +0,0 @@
|
|||||||
# Sample localization file for English. Add more files in this directory for other locales.
|
|
||||||
# See http://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale for starting points.
|
|
||||||
|
|
||||||
en:
|
|
||||||
hello: "Hello world"
|
|
16
doc/site.txt
Normal file
16
doc/site.txt
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
h1. Sites
|
||||||
|
|
||||||
|
Site is the parent model of all pages, assets, ...etc.
|
||||||
|
|
||||||
|
h2. Subdomain
|
||||||
|
|
||||||
|
A site must have a subdomain in case of all the other domains are not reachable (dns problems, ...etc).
|
||||||
|
|
||||||
|
h2. Domains
|
||||||
|
|
||||||
|
When a request reaches the application, the site dispatcher method looks for a site responding to the domain name specified in the request. New domains can be added further by the administrator of the site.
|
||||||
|
The very first domain is the one built from the subdomain.
|
||||||
|
A site must own at least one domain.
|
||||||
|
|
||||||
|
*Note:* domains like www.example.com and example.com are equals
|
||||||
|
|
@ -22,7 +22,8 @@ module Locomotive
|
|||||||
class Configuration
|
class Configuration
|
||||||
|
|
||||||
DEFAULT_SETTINGS = {
|
DEFAULT_SETTINGS = {
|
||||||
:default_domain_name => 'localhost'
|
:default_domain => 'localhost',
|
||||||
|
:forbidden_subdomains => %w{www admin email blog webmail mail support help site sites}
|
||||||
}
|
}
|
||||||
|
|
||||||
cattr_accessor :settings
|
cattr_accessor :settings
|
||||||
|
6
lib/locomotive/regexps.rb
Normal file
6
lib/locomotive/regexps.rb
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
module Locomotive
|
||||||
|
module Regexps
|
||||||
|
SUBDOMAIN = /^[a-z][a-z0-9_]*[a-z0-9]{1}$/
|
||||||
|
DOMAIN = /^[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(:[0-9]{1,5})?(\/.*)?$/ix
|
||||||
|
end
|
||||||
|
end
|
@ -14,11 +14,77 @@ describe Site do
|
|||||||
site.errors[:name].should == ["can't be blank"]
|
site.errors[:name].should == ["can't be blank"]
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'should have a domain at minimum' do
|
it 'should validate presence of subdomain' do
|
||||||
site = Factory.build(:site, :subdomain => nil)
|
site = Factory.build(:site, :subdomain => nil)
|
||||||
site.should_not be_valid
|
site.should_not be_valid
|
||||||
site.domains = %w{acme.net}
|
site.errors[:subdomain].should == ["can't be blank"]
|
||||||
site.should be_valid
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
%w{test foo_bar test42}.each do |subdomain|
|
||||||
|
it "should accept subdomain like '#{subdomain}'" do
|
||||||
|
Factory.build(:site, :subdomain => subdomain).should be_valid
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
['-', '_test', 'test_', 't est', '42', '42test'].each do |subdomain|
|
||||||
|
it "should not accept subdomain like '#{subdomain}'" do
|
||||||
|
(site = Factory.build(:site, :subdomain => subdomain)).should_not be_valid
|
||||||
|
site.errors[:subdomain].should == ['is invalid']
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should not use reserved keywords as subdomain" do
|
||||||
|
%w{www admin email blog webmail mail support help site sites}.each do |subdomain|
|
||||||
|
(site = Factory.build(:site, :subdomain => subdomain)).should_not be_valid
|
||||||
|
site.errors[:subdomain].should == ['is reserved']
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should validate uniqueness of subdomain' do
|
||||||
|
Factory(:site)
|
||||||
|
(site = Factory.build(:site)).should_not be_valid
|
||||||
|
site.errors[:subdomain].should == ["is already taken"]
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should validate uniqueness of domains' do
|
||||||
|
Factory(:site, :domains => %w{www.acme.net www.acme.com})
|
||||||
|
(site = Factory.build(:site, :domains => %w{www.acme.com})).should_not be_valid
|
||||||
|
site.errors[:domains].should == ["www.acme.com is already taken"]
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should validate format of domains' do
|
||||||
|
site = Factory.build(:site, :domains => ['barformat.superlongextension', '-foo.net'])
|
||||||
|
site.should_not be_valid
|
||||||
|
site.errors[:domains].should == ['barformat.superlongextension is invalid', '-foo.net is invalid']
|
||||||
|
end
|
||||||
|
|
||||||
|
## Named scopes ##
|
||||||
|
|
||||||
|
it 'should retrieve sites by domain' do
|
||||||
|
site_1 = Factory(:site, :domains => %w{www.acme.net})
|
||||||
|
site_2 = Factory(:site, :subdomain => 'test', :domains => %w{www.example.com})
|
||||||
|
|
||||||
|
sites = Site.match_domain('www.acme.net')
|
||||||
|
sites.size.should == 1
|
||||||
|
sites.first.should == site_1
|
||||||
|
|
||||||
|
sites = Site.match_domain('www.example.com')
|
||||||
|
sites.size.should == 1
|
||||||
|
sites.first.should == site_2
|
||||||
|
|
||||||
|
sites = Site.match_domain('test.example.com')
|
||||||
|
sites.size.should == 1
|
||||||
|
sites.first.should == site_2
|
||||||
|
|
||||||
|
sites = Site.match_domain('www.unknown.com')
|
||||||
|
sites.should be_empty
|
||||||
|
end
|
||||||
|
|
||||||
|
## Methods ##
|
||||||
|
|
||||||
|
it 'should return domains without subdomain' do
|
||||||
|
site = Factory(:site, :domains => %w{www.acme.net www.acme.com})
|
||||||
|
site.domains.should == %w{www.acme.net www.acme.com acme.example.com}
|
||||||
|
site.domains_without_subdomain.should == %w{www.acme.net www.acme.com}
|
||||||
|
end
|
||||||
end
|
end
|
Loading…
Reference in New Issue
Block a user