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
|
||||
group :development do
|
||||
# Using mongrel instead of webrick (default server)
|
||||
gem "mongrel"
|
||||
gem "cgi_multipart_eof_fix"
|
||||
gem "fastthread"
|
||||
gem "mongrel_experimental"
|
||||
# gem "mongrel"
|
||||
# gem "cgi_multipart_eof_fix"
|
||||
# gem "fastthread"
|
||||
# gem "mongrel_experimental"
|
||||
end
|
||||
|
||||
group :test do
|
||||
|
@ -4,29 +4,51 @@ class Site
|
||||
|
||||
## fields ##
|
||||
field :name
|
||||
field :subdomain, :type => String
|
||||
field :domains, :type => Array, :default => []
|
||||
|
||||
## validations ##
|
||||
validates_presence_of :name
|
||||
validates_length_of :domains, :minimum => 1
|
||||
# validates_each :domains, :logic => :domains_are_unique_and_valid
|
||||
validates_presence_of :name, :subdomain
|
||||
validates_uniqueness_of :subdomain
|
||||
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 ##
|
||||
# timestamps!
|
||||
add_dirty_methods :domains
|
||||
|
||||
## methods ##
|
||||
|
||||
def subdomain=(value)
|
||||
return if value.blank?
|
||||
(self.domains << "#{value}.#{Locomotive::Configuration.default_domain_name}").uniq!
|
||||
def add_subdomain_to_domains
|
||||
self.domains ||= []
|
||||
(self.domains << "#{self.subdomain}.#{Locomotive::Configuration.default_domain}").uniq!
|
||||
end
|
||||
|
||||
def domains_without_subdomain
|
||||
(self.domains || []) - ["#{self.subdomain}.#{Locomotive::Configuration.default_domain}"]
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def domains_are_unique_and_valid
|
||||
# self.domains.each do |domain|
|
||||
# self.errors.add(:domains, t())
|
||||
# end
|
||||
def domains_must_be_valid_and_unique
|
||||
return if self.domains.empty? || (!self.new_record? && !self.domains_changed?)
|
||||
|
||||
(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
|
@ -1,3 +1,3 @@
|
||||
Locomotive::Configuration.setup do |config|
|
||||
config.default_domain_name = 'example.com'
|
||||
config.default_domain = 'example.com'
|
||||
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
|
||||
|
||||
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
|
||||
|
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"]
|
||||
end
|
||||
|
||||
it 'should have a domain at minimum' do
|
||||
it 'should validate presence of subdomain' do
|
||||
site = Factory.build(:site, :subdomain => nil)
|
||||
site.should_not be_valid
|
||||
site.domains = %w{acme.net}
|
||||
site.should be_valid
|
||||
site.errors[:subdomain].should == ["can't be blank"]
|
||||
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
|
Loading…
Reference in New Issue
Block a user