merging with the last version of the master branch
This commit is contained in:
commit
5dd9481ec2
2
.gitignore
vendored
2
.gitignore
vendored
@ -33,4 +33,6 @@ gem_graph.png
|
||||
sites/
|
||||
permanent
|
||||
doc/bushido
|
||||
*.swp
|
||||
|
||||
|
||||
|
14
Gemfile
14
Gemfile
@ -4,7 +4,7 @@ source :rubygems
|
||||
|
||||
gem 'rake', '0.9.2'
|
||||
|
||||
gem 'rails', '3.0.9'
|
||||
gem 'rails', '3.0.10'
|
||||
|
||||
gem 'warden'
|
||||
gem 'devise', '1.3.4'
|
||||
@ -27,21 +27,21 @@ gem 'carrierwave', '0.5.6'
|
||||
gem 'dragonfly', '~> 0.9.1'
|
||||
gem 'rack-cache', :require => 'rack/cache'
|
||||
|
||||
gem 'custom_fields', '1.0.0.beta.23'
|
||||
gem 'custom_fields', '1.0.0.beta.25'
|
||||
gem 'cancan'
|
||||
gem 'fog', '0.8.2'
|
||||
gem 'mimetype-fu'
|
||||
gem 'actionmailer-with-request', :require => 'actionmailer_with_request'
|
||||
gem 'heroku', '1.19.1'
|
||||
gem 'httparty', '>= 0.6.1'
|
||||
gem 'RedCloth', '4.2.7'
|
||||
gem 'RedCloth', '4.2.8'
|
||||
gem 'delayed_job', '2.1.4'
|
||||
gem 'delayed_job_mongoid', '1.0.2'
|
||||
gem 'rubyzip'
|
||||
gem 'locomotive_jammit-s3', :require => 'jammit-s3'
|
||||
gem 'SystemTimer', :platforms => :ruby_18
|
||||
gem 'cells'
|
||||
|
||||
gem 'sanitize'
|
||||
gem 'highline'
|
||||
|
||||
# The rest of the dependencies are for use when in the locomotive dev environment
|
||||
@ -57,7 +57,7 @@ end
|
||||
group :test, :development do
|
||||
gem 'linecache', '0.43', :platforms => :mri_18
|
||||
gem 'ruby-debug', :platforms => :mri_18
|
||||
gem 'ruby-debug19', :platforms => :mri_19
|
||||
gem 'ruby-debug19', :platforms => :mri_19, :require => 'ruby-debug'
|
||||
|
||||
gem 'bushido_stub', '0.0.3'
|
||||
|
||||
@ -69,7 +69,7 @@ group :test do
|
||||
gem 'ZenTest'
|
||||
gem 'growl-glue'
|
||||
gem 'rspec-rails', '2.6.1'
|
||||
gem 'factory_girl_rails'
|
||||
gem 'factory_girl_rails', '~> 1.1'
|
||||
gem 'pickle'
|
||||
gem 'xpath', '~> 0.1.4'
|
||||
gem 'capybara'
|
||||
@ -77,7 +77,7 @@ group :test do
|
||||
|
||||
gem 'spork', '~> 0.9.0.rc'
|
||||
gem 'launchy'
|
||||
gem 'mocha', :git => 'git://github.com/floehopper/mocha.git'
|
||||
gem 'mocha', '0.9.12' # :git => 'git://github.com/floehopper/mocha.git'
|
||||
end
|
||||
|
||||
group :production do
|
||||
|
80
Gemfile.lock
80
Gemfile.lock
@ -1,10 +1,3 @@
|
||||
GIT
|
||||
remote: git://github.com/floehopper/mocha.git
|
||||
revision: afa87804ca2124ff5e77f007a84a26ee0667eec8
|
||||
specs:
|
||||
mocha (0.9.12)
|
||||
metaclass (~> 0.0.1)
|
||||
|
||||
GEM
|
||||
remote: http://rubygems.org/
|
||||
specs:
|
||||
@ -12,18 +5,18 @@ GEM
|
||||
Platform (>= 0.4.0)
|
||||
open4
|
||||
Platform (0.4.0)
|
||||
RedCloth (4.2.7)
|
||||
RedCloth (4.2.8)
|
||||
SystemTimer (1.2.3)
|
||||
ZenTest (4.6.1)
|
||||
abstract (1.0.0)
|
||||
actionmailer (3.0.9)
|
||||
actionpack (= 3.0.9)
|
||||
actionmailer (3.0.10)
|
||||
actionpack (= 3.0.10)
|
||||
mail (~> 2.2.19)
|
||||
actionmailer-with-request (0.3.0)
|
||||
rails (>= 3)
|
||||
actionpack (3.0.9)
|
||||
activemodel (= 3.0.9)
|
||||
activesupport (= 3.0.9)
|
||||
actionpack (3.0.10)
|
||||
activemodel (= 3.0.10)
|
||||
activesupport (= 3.0.10)
|
||||
builder (~> 2.1.2)
|
||||
erubis (~> 2.6.6)
|
||||
i18n (~> 0.5.0)
|
||||
@ -31,19 +24,19 @@ GEM
|
||||
rack-mount (~> 0.6.14)
|
||||
rack-test (~> 0.5.7)
|
||||
tzinfo (~> 0.3.23)
|
||||
activemodel (3.0.9)
|
||||
activesupport (= 3.0.9)
|
||||
activemodel (3.0.10)
|
||||
activesupport (= 3.0.10)
|
||||
builder (~> 2.1.2)
|
||||
i18n (~> 0.5.0)
|
||||
activerecord (3.0.9)
|
||||
activemodel (= 3.0.9)
|
||||
activesupport (= 3.0.9)
|
||||
activerecord (3.0.10)
|
||||
activemodel (= 3.0.10)
|
||||
activesupport (= 3.0.10)
|
||||
arel (~> 2.0.10)
|
||||
tzinfo (~> 0.3.23)
|
||||
activeresource (3.0.9)
|
||||
activemodel (= 3.0.9)
|
||||
activesupport (= 3.0.9)
|
||||
activesupport (3.0.9)
|
||||
activeresource (3.0.10)
|
||||
activemodel (= 3.0.10)
|
||||
activesupport (= 3.0.10)
|
||||
activesupport (3.0.10)
|
||||
archive-tar-minitar (0.5.2)
|
||||
arel (2.0.10)
|
||||
autotest (4.4.6)
|
||||
@ -87,7 +80,11 @@ GEM
|
||||
capybara (>= 1.0.0)
|
||||
cucumber (~> 1.0.0)
|
||||
nokogiri (>= 1.4.6)
|
||||
<<<<<<< HEAD
|
||||
custom_fields (1.0.0.beta.23)
|
||||
=======
|
||||
custom_fields (1.0.0.beta.25)
|
||||
>>>>>>> master
|
||||
activesupport (~> 3.0.9)
|
||||
mongoid (= 2.0.2)
|
||||
daemons (1.1.4)
|
||||
@ -170,10 +167,10 @@ GEM
|
||||
i18n (>= 0.4.0)
|
||||
mime-types (~> 1.16)
|
||||
treetop (~> 1.4.8)
|
||||
metaclass (0.0.1)
|
||||
mime-types (1.16)
|
||||
mimemagic (0.1.8)
|
||||
mimetype-fu (0.1.2)
|
||||
mocha (0.9.12)
|
||||
mongo (1.3.1)
|
||||
bson (>= 1.3.1)
|
||||
mongoid (2.0.2)
|
||||
@ -199,23 +196,23 @@ GEM
|
||||
rack (>= 1.0.0)
|
||||
rack-test (0.5.7)
|
||||
rack (>= 1.0)
|
||||
rails (3.0.9)
|
||||
actionmailer (= 3.0.9)
|
||||
actionpack (= 3.0.9)
|
||||
activerecord (= 3.0.9)
|
||||
activeresource (= 3.0.9)
|
||||
activesupport (= 3.0.9)
|
||||
rails (3.0.10)
|
||||
actionmailer (= 3.0.10)
|
||||
actionpack (= 3.0.10)
|
||||
activerecord (= 3.0.10)
|
||||
activeresource (= 3.0.10)
|
||||
activesupport (= 3.0.10)
|
||||
bundler (~> 1.0)
|
||||
railties (= 3.0.9)
|
||||
railties (3.0.9)
|
||||
actionpack (= 3.0.9)
|
||||
activesupport (= 3.0.9)
|
||||
railties (= 3.0.10)
|
||||
railties (3.0.10)
|
||||
actionpack (= 3.0.10)
|
||||
activesupport (= 3.0.10)
|
||||
rake (>= 0.8.7)
|
||||
rdoc (~> 3.4)
|
||||
thor (~> 0.14.4)
|
||||
raindrops (0.7.0)
|
||||
rake (0.9.2)
|
||||
rdoc (3.9.2)
|
||||
rdoc (3.9.4)
|
||||
responders (0.6.4)
|
||||
rest-client (1.6.3)
|
||||
mime-types (>= 1.16)
|
||||
@ -258,6 +255,8 @@ GEM
|
||||
rubyzip (0.9.4)
|
||||
s3 (0.3.8)
|
||||
proxies (~> 0.2.0)
|
||||
sanitize (2.0.3)
|
||||
nokogiri (>= 1.4.4, < 1.6)
|
||||
sass (3.1.2)
|
||||
selenium-webdriver (2.4.0)
|
||||
childprocess (>= 0.2.1)
|
||||
@ -287,7 +286,7 @@ PLATFORMS
|
||||
ruby
|
||||
|
||||
DEPENDENCIES
|
||||
RedCloth (= 4.2.7)
|
||||
RedCloth (= 4.2.8)
|
||||
SystemTimer
|
||||
ZenTest
|
||||
actionmailer-with-request
|
||||
@ -300,14 +299,18 @@ DEPENDENCIES
|
||||
carrierwave (= 0.5.6)
|
||||
cells
|
||||
cucumber-rails (= 1.0.2)
|
||||
<<<<<<< HEAD
|
||||
custom_fields (= 1.0.0.beta.23)
|
||||
=======
|
||||
custom_fields (= 1.0.0.beta.25)
|
||||
>>>>>>> master
|
||||
database_cleaner
|
||||
delayed_job (= 2.1.4)
|
||||
delayed_job_mongoid (= 1.0.2)
|
||||
devise (= 1.3.4)
|
||||
devise_bushido_authenticatable (= 1.0.0.alpha10)
|
||||
dragonfly (~> 0.9.1)
|
||||
factory_girl_rails
|
||||
factory_girl_rails (~> 1.1)
|
||||
fog (= 0.8.2)
|
||||
formtastic (~> 1.2.3)
|
||||
growl-glue
|
||||
@ -322,12 +325,12 @@ DEPENDENCIES
|
||||
locomotive_liquid (= 2.2.2)
|
||||
locomotive_mongoid_acts_as_tree (= 0.1.5.7)
|
||||
mimetype-fu
|
||||
mocha!
|
||||
mocha (= 0.9.12)
|
||||
mongoid (~> 2.0.2)
|
||||
mongoid_i18n
|
||||
pickle
|
||||
rack-cache
|
||||
rails (= 3.0.9)
|
||||
rails (= 3.0.10)
|
||||
rake (= 0.9.2)
|
||||
rmagick (= 2.12.2)
|
||||
rspec-cells
|
||||
@ -335,6 +338,7 @@ DEPENDENCIES
|
||||
ruby-debug
|
||||
ruby-debug19
|
||||
rubyzip
|
||||
sanitize
|
||||
sass (= 3.1.2)
|
||||
spork (~> 0.9.0.rc)
|
||||
unicorn
|
||||
|
@ -19,8 +19,8 @@ h2. Gems
|
||||
|
||||
Here is a short list of main gems used in the application.
|
||||
|
||||
* Rails 3.0.9
|
||||
* Mongoid 2.0.2 (with MongoDB 1.6)
|
||||
* Rails 3.0.10
|
||||
* Mongoid 2.0.2 (with MongoDB 1.8)
|
||||
* Liquid
|
||||
* Devise
|
||||
* Carrierwave
|
||||
@ -34,8 +34,8 @@ See the "official website":http://www.locomotivecms.com
|
||||
|
||||
h2. Team
|
||||
|
||||
* Developers: "Didier Lafforgue":http://www.nocoffee.fr, "Jacques Crocker":http://www.railsjedi.com
|
||||
* Contributors: "Dirk Kelly":http://www.dirkkelly.com, "Mario Visic":http://www.mariovisic.com, "Raphael Costa":http://raphaelcosta.net (Brazilian Portuguese translation), "Bernd Hauser":http://www.designhunger.de (German translation), "Andrea Frigido":http://www.frisoft.it (Italian translation), "Enrique García":https://github.com/kikito (Spanish translation), "Lars Smit":https://github.com/larssmit (Dutch translation)
|
||||
* Developers: "Didier Lafforgue":http://www.nocoffee.fr, "Jacques Crocker":http://www.railsjedi.com, "Mario Visic":http://www.mariovisic.com
|
||||
* Contributors: "Dirk Kelly":http://www.dirkkelly.com, "Raphael Costa":http://raphaelcosta.net (Brazilian Portuguese translation), "Bernd Hauser":http://www.designhunger.de (German translation), "Andrea Frigido":http://www.frisoft.it (Italian translation), "Enrique García":https://github.com/kikito (Spanish translation), "Lars Smit":https://github.com/larssmit (Dutch translation), "PitOn":https://github.com/GarPit (Russian translation)
|
||||
* UI Designer: "Sacha Greif":http://www.sachagreif.com
|
||||
* IE maintainer: "Alex Sanford":https://github.com/alexsanford
|
||||
|
||||
|
@ -7,6 +7,10 @@ module Admin
|
||||
|
||||
before_filter :set_content_type
|
||||
|
||||
before_filter :block_content_type_with_disabled_api
|
||||
|
||||
before_filter :sanitize_content_params, :only => :create
|
||||
|
||||
def create
|
||||
@content = @content_type.contents.build(params[:content])
|
||||
|
||||
@ -32,7 +36,23 @@ module Admin
|
||||
|
||||
def set_content_type
|
||||
@content_type = current_site.content_types.where(:slug => params[:slug]).first
|
||||
render :json => { :error => 'Api not enabled' } and return false unless @content_type.api_enabled
|
||||
end
|
||||
|
||||
def block_content_type_with_disabled_api
|
||||
unless @content_type.api_enabled?
|
||||
respond_to do |format|
|
||||
format.json { render :json => { :error => 'Api not enabled' }, :status => :forbidden }
|
||||
format.html { render :text => 'Api not enabled', :status => :forbidden }
|
||||
end
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
def sanitize_content_params
|
||||
(params[:content] || {}).each do |key, value|
|
||||
next unless value.is_a?(String)
|
||||
params[:content][key] = Sanitize.clean(value, Sanitize::Config::BASIC)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
@ -9,10 +9,10 @@ module Admin
|
||||
|
||||
before_filter :require_site
|
||||
|
||||
load_and_authorize_resource
|
||||
|
||||
before_filter :validate_site_membership
|
||||
|
||||
load_and_authorize_resource
|
||||
|
||||
before_filter :set_locale
|
||||
|
||||
before_filter :set_site_locale
|
||||
|
@ -6,10 +6,17 @@ module Admin
|
||||
include Locomotive::Render
|
||||
|
||||
before_filter :require_site
|
||||
before_filter :authenticate_admin!, :only => [:edit]
|
||||
before_filter :validate_site_membership, :only => [:edit]
|
||||
|
||||
def show
|
||||
render_locomotive_page
|
||||
end
|
||||
|
||||
def edit
|
||||
@editing = true
|
||||
render_locomotive_page
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
@ -7,7 +7,7 @@ module Admin::ContentTypesHelper
|
||||
|
||||
@content_types = current_site.content_types.ordered.
|
||||
limit(:contents => Locomotive.config.lastest_items_nb).
|
||||
only(:name, :slug, :highlighted_field_name, :content_custom_fields_version, :order_by, :serialized_item_template).to_a
|
||||
only(:site_id, :name, :slug, :highlighted_field_name, :content_custom_fields_version, :order_by, :serialized_item_template, :raw_item_template).to_a
|
||||
|
||||
if @content_type && @content_type.persisted? && @content_types.index(@content_type) >= MAX_DISPLAYED_CONTENTS
|
||||
@content_types.delete(@content_type)
|
||||
|
@ -22,7 +22,7 @@ module Admin::CustomFieldsHelper
|
||||
def options_for_highlighted_field(content_type, collection_name)
|
||||
custom_fields_collection_name = "ordered_#{collection_name.singularize}_custom_fields".to_sym
|
||||
collection = content_type.send(custom_fields_collection_name)
|
||||
collection.delete_if { |f| f.label == 'field name' || f.kind == 'file' }
|
||||
collection.delete_if { |f| f.label == 'field name' || %w(file has_one has_many).include?(f.kind) }
|
||||
collection.map { |field| [field.label, field._name] }
|
||||
end
|
||||
|
||||
@ -40,9 +40,7 @@ module Admin::CustomFieldsHelper
|
||||
end
|
||||
|
||||
def options_for_association_target
|
||||
current_site.content_types.collect do |c|
|
||||
c.persisted? ? [c.name, c.content_klass.to_s] : nil
|
||||
end.compact
|
||||
current_site.reload.content_types.collect { |c| [c.name, c.content_klass.to_s] }
|
||||
end
|
||||
|
||||
def options_for_reverse_lookups(my_content_type)
|
||||
@ -86,7 +84,7 @@ module Admin::CustomFieldsHelper
|
||||
end
|
||||
|
||||
def options_for_has_one_or_has_many(field, content = nil, &block)
|
||||
content_type = field.target.constantize._parent
|
||||
content_type = field.target.constantize._parent.reload
|
||||
|
||||
if content_type.groupable?
|
||||
grouped_contents = content_type.list_or_group_contents
|
||||
|
@ -61,6 +61,8 @@ class Ability
|
||||
|
||||
can :point, Site
|
||||
|
||||
cannot :create, Site
|
||||
|
||||
can :manage, Membership
|
||||
|
||||
cannot :change_role, Membership do |membership|
|
||||
|
@ -9,6 +9,7 @@ class EditableElement
|
||||
localized_field :default_content
|
||||
field :default_attribute
|
||||
field :hint
|
||||
field :priority, :type => Integer, :default => 0
|
||||
field :disabled, :type => Boolean, :default => false
|
||||
field :assignable, :type => Boolean, :default => true
|
||||
field :from_parent, :type => Boolean, :default => false
|
||||
@ -19,6 +20,9 @@ class EditableElement
|
||||
## validations ##
|
||||
validates_presence_of :slug
|
||||
|
||||
## scopes ##
|
||||
scope :by_priority, :order_by => [[:priority, :desc]]
|
||||
|
||||
## methods ##
|
||||
|
||||
end
|
@ -32,7 +32,7 @@ module Extensions
|
||||
end
|
||||
|
||||
def editable_elements_grouped_by_blocks
|
||||
all_enabled = self.editable_elements.reject { |el| el.disabled? }
|
||||
all_enabled = self.editable_elements.by_priority.reject { |el| el.disabled? }
|
||||
groups = all_enabled.group_by(&:block)
|
||||
groups.delete_if { |block, elements| elements.empty? }
|
||||
end
|
||||
|
@ -75,7 +75,7 @@ class Page
|
||||
if self.index? || self.not_found?
|
||||
self.slug
|
||||
else
|
||||
slugs = self.self_and_ancestors.map(&:slug)
|
||||
slugs = self.self_and_ancestors.sort_by(&:depth).map(&:slug)
|
||||
slugs.shift unless slugs.size == 1
|
||||
File.join slugs
|
||||
end
|
||||
|
@ -9,7 +9,7 @@ class ThemeAssetUploader < CarrierWave::Uploader::Base
|
||||
end
|
||||
|
||||
def extension_white_list
|
||||
%w(jpg jpeg gif png css js swf flv eot svg ttf woff otf ico)
|
||||
%w(jpg jpeg gif png css js swf flv eot svg ttf woff otf ico htc)
|
||||
end
|
||||
|
||||
def self.url_for(site, path)
|
||||
|
@ -6,10 +6,11 @@
|
||||
- content_for :actions do
|
||||
= render_cell 'admin/site_locale_picker', :show, :site => current_site, :locale => I18n.site_locale
|
||||
|
||||
- if can?(:manage, @site)
|
||||
- content_for :buttons do
|
||||
- content_for :buttons do
|
||||
- if can?(:manage, @site)
|
||||
= admin_button_tag :export, new_admin_export_url, :class => 'new'
|
||||
= admin_button_tag :import, new_admin_import_url, :class => 'new'
|
||||
- if can?(:create, Account)
|
||||
= admin_button_tag t('.new_membership'), new_admin_membership_url, :class => 'new'
|
||||
|
||||
%p!= t('.help')
|
||||
|
@ -1,5 +1,3 @@
|
||||
- field.target.constantize.reload_parent! # to make sure all the contents from the parent are loaded
|
||||
|
||||
= form.custom_input field._alias.to_sym, :label => field.label, :hint => field.hint, :css => 'has-many', :required => required do
|
||||
|
||||
.has-many-selector
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
- if multi_sites?
|
||||
- content_for :buttons do
|
||||
= admin_button_tag t('.new_site'), new_admin_site_url, :class => 'new' if can?(:manage, Site)
|
||||
= admin_button_tag t('.new_site'), new_admin_site_url, :class => 'new' if can?(:create, Site)
|
||||
|
||||
%p= t('.help')
|
||||
|
||||
|
@ -15,7 +15,7 @@
|
||||
%li{ :id => "block-#{index}", :class => 'block', :style => "display: #{index == 0 ? 'block' : 'none' }" }
|
||||
%fieldset.inputs
|
||||
%ol
|
||||
- elements.each_with_index do |el, index|
|
||||
- elements.each do |el|
|
||||
= f.fields_for 'editable_elements', el, :child_index => el._index do |g|
|
||||
- case el
|
||||
- when EditableLongText
|
||||
|
@ -9,5 +9,5 @@
|
||||
%span!= t('.updated_at')
|
||||
%span.date= l asset.updated_at, :format => :short
|
||||
|
||||
- if edit
|
||||
- if edit && can?(:destroy, asset)
|
||||
= link_to image_tag('admin/list/icons/trash.png'), admin_theme_asset_path(asset), :class => 'remove', :confirm => t('admin.messages.confirm'), :method => :delete
|
||||
|
@ -1,7 +1,7 @@
|
||||
<%
|
||||
rerun = File.file?('rerun.txt') ? IO.read('rerun.txt') : ""
|
||||
rerun_opts = rerun.to_s.strip.empty? ? "--format #{ENV['CUCUMBER_FORMAT'] || 'progress'} features" : "--format #{ENV['CUCUMBER_FORMAT'] || 'pretty'} #{rerun}"
|
||||
std_opts = "--format #{ENV['CUCUMBER_FORMAT'] || 'progress'} --strict --tags ~@wip"
|
||||
std_opts = "--format #{ENV['CUCUMBER_FORMAT'] || 'progress'} --require features --strict --tags ~@wip"
|
||||
%>
|
||||
default: <%= std_opts %> features
|
||||
wip: --tags @wip:3 --wip features
|
||||
|
@ -8,6 +8,7 @@ de:
|
||||
it: "Italienisch"
|
||||
nl: "Holländer"
|
||||
es: "Spanisch"
|
||||
ru: "Russisch"
|
||||
|
||||
buttons:
|
||||
login: Einloggen
|
||||
|
@ -8,6 +8,7 @@ en:
|
||||
it: Italian
|
||||
nl: Dutch
|
||||
es: Spanish
|
||||
ru: Russian
|
||||
|
||||
buttons:
|
||||
login: Log in
|
||||
|
@ -173,6 +173,7 @@ es:
|
||||
it: Italiano
|
||||
nl: holandés
|
||||
es: Español
|
||||
ru: Ruso
|
||||
ask_for_name: "Por favor escriba su nuevo nombre"
|
||||
|
||||
theme_assets:
|
||||
|
@ -8,6 +8,7 @@ fr:
|
||||
it: "en Italien"
|
||||
nl: "en Hollandais"
|
||||
es: en Espagnol
|
||||
ru: en Russe
|
||||
|
||||
errors:
|
||||
"500":
|
||||
|
@ -173,6 +173,7 @@ it:
|
||||
it: Italiano
|
||||
nl: Olandese
|
||||
es: Spagnolo
|
||||
ru: Russo
|
||||
ask_for_name: "Prego, digita il tuo nome"
|
||||
|
||||
theme_assets:
|
||||
|
@ -159,6 +159,7 @@ nl:
|
||||
pt-BR: "Braziliaans Portugees"
|
||||
it: Italiaans
|
||||
nl: Nederlands
|
||||
ru: Russisch
|
||||
ask_for_name: "Voer uw nieuwe naam in"
|
||||
|
||||
theme_assets:
|
||||
|
@ -159,6 +159,7 @@ pt-BR:
|
||||
it: Italiano
|
||||
nl: Holandês
|
||||
es: Espanhol
|
||||
ru: Russo
|
||||
ask_for_name: "Por favor preencha o novo nome"
|
||||
|
||||
theme_assets:
|
||||
|
303
config/locales/admin_ui.ru.yml
Normal file
303
config/locales/admin_ui.ru.yml
Normal file
@ -0,0 +1,303 @@
|
||||
ru:
|
||||
admin:
|
||||
buttons:
|
||||
login: Войти
|
||||
send_password: Отправить
|
||||
change_password: Изменить
|
||||
new_item: "+ добавить"
|
||||
switch_to_site: Сайт
|
||||
delete: "Удалить"
|
||||
|
||||
messages:
|
||||
confirm: Вы уверены ?
|
||||
|
||||
shared:
|
||||
header:
|
||||
welcome: Привет, %{name}
|
||||
see: Сайт
|
||||
switch: К другому сайту
|
||||
help: Справка
|
||||
logout: Выйти
|
||||
menu:
|
||||
contents: Содержимое
|
||||
assets: Файлы
|
||||
settings: Настройки
|
||||
pages: Страницы
|
||||
snippets: Сниппеты
|
||||
account: Аккаунт
|
||||
site: Сайт
|
||||
theme_assets: Файлы темы
|
||||
footer:
|
||||
who_is_behind: "Service developed by %{development} and designed by <a href=\"http://www.sachagreif.com\">Sacha Greif</a>"
|
||||
form_actions:
|
||||
back: Назад без сохранения
|
||||
create: Создать
|
||||
update: Сохранить
|
||||
send: Отправить
|
||||
|
||||
errors:
|
||||
"500":
|
||||
title: Ошибка Приложения
|
||||
notice: "Мы сожалеем, но что-то пошло не так"
|
||||
link: "→ Назад в приложение"
|
||||
"404":
|
||||
title: Страница не найдена
|
||||
notice: "Запрашиваемая страница не существует."
|
||||
link: "→ Назад в приложение"
|
||||
|
||||
notifications:
|
||||
new_content_instance:
|
||||
subject: "[%{type}] новый"
|
||||
title: "Привет %{name}, просто сообщаем, что новый элемент был создан %{date}"
|
||||
type: "Модель: %{type}"
|
||||
|
||||
sites_picker:
|
||||
new: + new site
|
||||
|
||||
custom_fields:
|
||||
edit:
|
||||
title: Редактирование пользовательского поля
|
||||
text_formatting:
|
||||
none: None
|
||||
html: HTML
|
||||
edit_field:
|
||||
title: Редактировать поле
|
||||
edit_category:
|
||||
title: Редактировать опции
|
||||
help: Управляйте списком опций для поля выбора select.
|
||||
collection_label: Списко опций
|
||||
types:
|
||||
category:
|
||||
edit_categories: Редактировать опции
|
||||
file:
|
||||
delete_file: Удалить файл
|
||||
has_many:
|
||||
empty: Пусто
|
||||
index:
|
||||
is_required: является обязательным
|
||||
default_label: Название поля
|
||||
|
||||
sessions:
|
||||
new:
|
||||
title: Войти
|
||||
link: "Я забыл свой пароль"
|
||||
email: "Email"
|
||||
password: "Пароль"
|
||||
|
||||
passwords:
|
||||
new:
|
||||
title: Забыли пароль
|
||||
link: "→ Назад к странице входа"
|
||||
email: "Ваш email"
|
||||
edit:
|
||||
title: Изменить мой пароль
|
||||
link: "→ Назад к странице логина"
|
||||
password: "Ваш новый пароль"
|
||||
password_confirmation: "Подтверждение нового пароля"
|
||||
|
||||
pages:
|
||||
index:
|
||||
title: Список страниц
|
||||
help: "Страницы организованы в виде дерева. Вы можете сортировать как страницы, так и папки"
|
||||
no_items: "There are no pages for now. Just click <a href=\"%{url}\">here</a> to create the first one."
|
||||
new: новая страница
|
||||
lastest_items: Страницы за последнее время
|
||||
new:
|
||||
title: Новая страница
|
||||
help: "Заполните форму, приведенную ниже, для создания страницы. Будьте осторожны, по умолчанию, страница не опубликована."
|
||||
page:
|
||||
updated_at: обновлено
|
||||
edit:
|
||||
show: смотреть
|
||||
help: "Заголовок страницы может быть изменен, если кликнуть на нем. Чтобы применить изменения, нажмите кнопку \"Сохранить\"."
|
||||
ask_for_title: "Пожалуйста введите новое имя страницы"
|
||||
form:
|
||||
delete_file: Удалить файл
|
||||
default_block: По умолчанию
|
||||
cache_strategy:
|
||||
none: Нет
|
||||
simple: Простая
|
||||
hour: 1 час
|
||||
day: 1 день
|
||||
week: 1 неделя
|
||||
month: 1 месяц
|
||||
|
||||
snippets:
|
||||
index:
|
||||
title: Список сниппетов
|
||||
help: "Сниппеты это куски HTML кода, которые могут быть использованы в разных местах в рамках сайта (таких, как \"футер\" к примеру)."
|
||||
no_items: "Пока нет ни одного сниппета. Нажмите <a href=\"%{url}\">здесь</a> для создания первого сниппета."
|
||||
new: новый сниппет
|
||||
new:
|
||||
title: Новый сниппет
|
||||
help: "Заполните форму, приведенную ниже, для изменения сниппета."
|
||||
edit:
|
||||
title: Редактирование сниппета
|
||||
help: "Включите ваш сниппет в шаблоны страницы с помощью следующего кода liquid : <span class='code'>{% include '%{slug}' %}</span>."
|
||||
snippet:
|
||||
updated_at: Обновлено
|
||||
|
||||
sites:
|
||||
new:
|
||||
title: Новый сайт
|
||||
help: "Заполните форму, приведенную ниже, чтобы создать новый сайт."
|
||||
|
||||
current_site:
|
||||
edit:
|
||||
export: экспорт
|
||||
import: импорт
|
||||
new_membership: добавить аккаунт
|
||||
help: "Название сайта может быть изменено, если кликнуть на нем. Чтобы применить изменения, нажмите кнопку \"Save\"."
|
||||
ask_for_name: "Пожалуйста введите новое имя сайта"
|
||||
|
||||
memberships:
|
||||
roles:
|
||||
admin: Администратор
|
||||
designer: Дизайнер
|
||||
author: Автор
|
||||
new:
|
||||
title: Новая учетная запись
|
||||
help: "Пожалуйста для добавления предоставьте email аккаунта. Если он не существует, вы будете перенаправлены на форму создания аккаунта."
|
||||
|
||||
accounts:
|
||||
new:
|
||||
title: Новый аккаунт
|
||||
help: "Заполните форму, приведенную ниже, чтобы добавить новый аккаунт."
|
||||
|
||||
my_account:
|
||||
edit:
|
||||
help: "Вы можете изменить логин просто кликнув на нем. Чтобы применить изменения, нажмите кнопку \"Сохранить\"."
|
||||
new_site: новый сайт
|
||||
en: Английский
|
||||
de: Немецкий
|
||||
fr: Французский
|
||||
pt-BR: "Бразильский - Португальский"
|
||||
it: Итальянский
|
||||
nl: Голландский
|
||||
es: Испанский
|
||||
ask_for_name: "Пожалуйста введите ваш новый логин"
|
||||
|
||||
theme_assets:
|
||||
index:
|
||||
title: Список файлов темы
|
||||
help: "Секция файлов темы это место, где вы можете управлять файлами, необходимыми для вашего шаблона, сниппетов и т.д. Если вам необходимо управление галереей изображений, создайте новый тип контента.<br/><b>Внимание:</b> вы можете не увидеть всех файлов - в зависимости от ваших прав."
|
||||
new: новый файл
|
||||
snippets: Сниппеты
|
||||
css_and_js: Стили и javascript
|
||||
fonts: Шрифты
|
||||
images: Изображения
|
||||
medias: Медиа
|
||||
no_items: "Пока нет ни одного файла."
|
||||
asset:
|
||||
updated_at: Обновлено
|
||||
new:
|
||||
title: Новый файл
|
||||
help: "У вас есть выбор - либо загрузить файл, либо копировать/вставить стиль CSS или javascript в виде текста."
|
||||
edit:
|
||||
title: "Редактирование %{file}"
|
||||
help: "Этот файл доступен по следующему url: <a href='%{url}'>%{url}</a>"
|
||||
help_image: "Включите ваше изображение в шаблоны страницы или сниппеты с помощью следующего liquid кода : <span class='code'>{{ '%{path}' | theme_image_tag }}</span>.<br/>Your current image dimensions : <b>%{width}px x %{height}px</b>.<br/>"
|
||||
help_javascript: "Включите ваш javascript файл в шаблоны страницы или сниппеты с помощью следующего кода : <span class='code'>{{ '%{path}' | javascript_tag }}</span>.<br/>"
|
||||
help_stylesheet: "Включите ваш файл стилей CSS в шаблоны страницы или сниппеты с помощью следующего кода : <span class='code'>{{ '%{path}' | stylesheet_tag }}</span>.<br/>"
|
||||
form:
|
||||
picker_link: Вставить файл в код
|
||||
choose_file: Выбрать файл
|
||||
choose_plain_text: Выбрать простой текст
|
||||
images:
|
||||
title: Список изображений
|
||||
no_items: "Пока нет ни одного файла."
|
||||
|
||||
assets:
|
||||
new:
|
||||
title: Новый файл
|
||||
help: "Заполните форму, приведенную ниже, для создания файла (asset)."
|
||||
edit:
|
||||
title: Редактировать файл
|
||||
help: "Заполните форму, приведенную ниже, для изменения файла."
|
||||
|
||||
content_types:
|
||||
index:
|
||||
new: новая модель
|
||||
new:
|
||||
title: Новая модель
|
||||
help: "Создайте ваши собственные модели данных (Проекты, Персоны, ...и т.д.). Модель должна иметь по крайней мере одно поле. Элементы, созданные из этого типа содержимого, будут иметь первое поле как обязательное."
|
||||
edit:
|
||||
title: Редактирование модели
|
||||
help: "Ваша модель должна иметь по крайней мере одно поле. Элементы, созданные из этого типа содержимого, будут иметь это поле как обязательное."
|
||||
show_items: смотреть элементы
|
||||
new_item: новый элемент
|
||||
form:
|
||||
order_by:
|
||||
created_at: 'По дате создания'
|
||||
updated_at: 'По дате обновления'
|
||||
position_in_list: Вручную
|
||||
order_direction:
|
||||
asc: По возрастанию
|
||||
desc: По убыванию
|
||||
|
||||
contents:
|
||||
index:
|
||||
title: 'Список "%{type}"'
|
||||
edit: редактировать модель
|
||||
destroy: удалить модель
|
||||
download: скачать элементы
|
||||
new: новый элемент
|
||||
category_noname: "Без имени"
|
||||
lastest_items: "Элементы за последнее время"
|
||||
updated_at: "Обновлено"
|
||||
list:
|
||||
no_items: "На данный момент нет ни одного элемента. Нажмите <a href=\"%{url}\">здесь</a> для создания первого элемента."
|
||||
new:
|
||||
title:
|
||||
default: '%{type} — новый элемент'
|
||||
breadcrumb: '%{root} » %{type} — новый элемент'
|
||||
edit:
|
||||
title:
|
||||
default: '%{type} — редактирование элемента'
|
||||
breadcrumb: '%{root} » %{type} — редактирование элемента'
|
||||
form:
|
||||
has_many:
|
||||
new_item: Новый элемент
|
||||
|
||||
image_picker:
|
||||
link: Вставить изображение в код
|
||||
|
||||
cross_domain_sessions:
|
||||
new:
|
||||
title: Кроссдоменная аутентификация
|
||||
notice: Вы будете перенаправлены на вебсайт в течение нескольких секунд.
|
||||
|
||||
import:
|
||||
new:
|
||||
title: Импортировать шаблон сайта
|
||||
help: "Будьте осторожны при загрузке нового шаблона для существующего сайта, ваши текущие данные могут быть изменены или даже удалены."
|
||||
show:
|
||||
title: Выполняется импорт
|
||||
help: "Ваш сайт обновляется из zip файла темы, который вы только что загрузили. Это займет несколько секунд."
|
||||
steps:
|
||||
site: Информация сайта
|
||||
content_types: Пользовательские типы содержимого
|
||||
assets: Файлы темы
|
||||
snippets: Сниппеты
|
||||
pages: Страницы
|
||||
messages:
|
||||
success: "Ваш сайт был успешно обновлен."
|
||||
failure: "Импорт не работает."
|
||||
|
||||
installation:
|
||||
common:
|
||||
title: Первая установка Locomotive
|
||||
next: Следующий шаг
|
||||
step_1:
|
||||
title: "Шаг 1/2 — Создайте аккаунт"
|
||||
name: Логин
|
||||
email: Email
|
||||
password: Пароль
|
||||
password_confirmation: Подтверждение пароля
|
||||
done: "Вы уже добавили учетную запись:<br/><strong>%{name}</strong>, <em>%{email}</em>"
|
||||
next: Создать аккаунт
|
||||
step_2:
|
||||
title: "Шаг 2/2 — Создайте первый сайт"
|
||||
explanations: "Если вы уже загрузили шаблон сайта по умолчанию (см. инструкцию), вы можете использовать его прямо сейчас. Или вы можете загрузить шаблон сайта как zip файл (доступные бесплатные шаблоны <a href=\"http://www.locomotivecms.com/support/themes\">здесь</a>)."
|
||||
back_to_default_template: "Нажмите <a href='#'>здесь</a> для выбора шаблона сайта по умолчанию"
|
||||
next: Создать сайт
|
4
config/locales/carrierwave.ru.yml
Normal file
4
config/locales/carrierwave.ru.yml
Normal file
@ -0,0 +1,4 @@
|
||||
ru:
|
||||
carrierwave:
|
||||
errors:
|
||||
integrity: 'не допустимый тип файла.'
|
@ -1,7 +1,143 @@
|
||||
nl:
|
||||
date:
|
||||
number:
|
||||
format:
|
||||
separator: ","
|
||||
precision: 2
|
||||
delimiter: .
|
||||
human:
|
||||
storage_units:
|
||||
format: "%n %u"
|
||||
units:
|
||||
kb: KB
|
||||
tb: TB
|
||||
gb: GB
|
||||
byte:
|
||||
one: Byte
|
||||
other: Bytes
|
||||
mb: MB
|
||||
currency:
|
||||
format:
|
||||
format: "%u %n"
|
||||
unit: !binary |
|
||||
4oKs
|
||||
|
||||
separator: .
|
||||
precision: 2
|
||||
delimiter: .
|
||||
|
||||
time:
|
||||
am: "'s ochtends"
|
||||
formats:
|
||||
default: "%m/%d/%Y"
|
||||
default: "%a %d %b %Y %H:%M:%S %Z"
|
||||
time: "%H:%M"
|
||||
short: "%d %b %H:%M"
|
||||
only_second: "%S"
|
||||
datetime:
|
||||
formats:
|
||||
default: "%d-%m-%YT%H:%M:%S%Z"
|
||||
long: "%d %B %Y %H:%M"
|
||||
pm: "'s middages"
|
||||
date:
|
||||
month_names:
|
||||
-
|
||||
- Januari
|
||||
- Februari
|
||||
- Maart
|
||||
- April
|
||||
- Mei
|
||||
- Juni
|
||||
- Juli
|
||||
- Augustus
|
||||
- September
|
||||
- Oktober
|
||||
- November
|
||||
- December
|
||||
abbr_day_names:
|
||||
- Zon
|
||||
- Maa
|
||||
- Din
|
||||
- Woe
|
||||
- Don
|
||||
- Vri
|
||||
- Zat
|
||||
order:
|
||||
- :day
|
||||
- :month
|
||||
- :year
|
||||
formats:
|
||||
only_day: "%e"
|
||||
default: "%d/%m/%Y"
|
||||
short: "%e %b"
|
||||
long: "%e %B %Y"
|
||||
day_names:
|
||||
- Zondag
|
||||
- Maandag
|
||||
- Dinsdag
|
||||
- Woensdag
|
||||
- Donderdag
|
||||
- Vrijdag
|
||||
- Zaterdag
|
||||
abbr_month_names:
|
||||
-
|
||||
- Jan
|
||||
- Feb
|
||||
- Mar
|
||||
- Apr
|
||||
- Mei
|
||||
- Jun
|
||||
- Jul
|
||||
- Aug
|
||||
- Sep
|
||||
- Okt
|
||||
- Nov
|
||||
- Dec
|
||||
support:
|
||||
array:
|
||||
words_connector: ","
|
||||
last_word_connector: ", en"
|
||||
two_words_connector: en
|
||||
datetime:
|
||||
format:
|
||||
default: "%Y-%m-%dT%H:%M:%S%Z"
|
||||
prompts:
|
||||
minute: Minuut
|
||||
second: Seconden
|
||||
month: Maand
|
||||
hour: Uur
|
||||
day: Dag
|
||||
year: Jaar
|
||||
distance_in_words:
|
||||
less_than_x_minutes:
|
||||
one: "minder dan \xC3\xA9\xC3\xA9n minuut"
|
||||
other: minder dan {{count}} minuten
|
||||
x_days:
|
||||
one: 1 dag
|
||||
other: "{{count}} dagen"
|
||||
x_seconds:
|
||||
one: 1 seconde
|
||||
other: "{{count}} seconden"
|
||||
about_x_hours:
|
||||
one: "ongeveer \xC3\xA9\xC3\xA9n uur"
|
||||
other: ongeveer {{count}} uur
|
||||
less_than_x_seconds:
|
||||
one: "minder dan \xC3\xA9\xC3\xA9n seconde"
|
||||
other: minder dan {{count}} seconden
|
||||
x_months:
|
||||
one: 1 maand
|
||||
other: "{{count}} maanden"
|
||||
x_minutes:
|
||||
one: 1 minuut
|
||||
other: "{{count}} minuten"
|
||||
about_x_years:
|
||||
one: "ongeveer \xC3\xA9\xC3\xA9n jaar"
|
||||
other: ongeveer {{count}} jaren
|
||||
about_x_months:
|
||||
one: "ongeveer \xC3\xA9\xC3\xA9n maand"
|
||||
other: ongeveer {{count}} maanden
|
||||
over_x_years:
|
||||
one: "langer dan \xC3\xA9\xC3\xA9n jaar"
|
||||
other: langer {{count}} jaar
|
||||
half_a_minute: halve minuut
|
||||
|
||||
errors:
|
||||
messages:
|
||||
@ -27,7 +163,7 @@ nl:
|
||||
title: "Pagina niet gevonden"
|
||||
body: "Inhoud van de 404 pagina"
|
||||
other:
|
||||
body: "{% breid 'parent' uit %}"
|
||||
body: "{% extends 'parent' %}"
|
||||
|
||||
pagination:
|
||||
previous: "« Vorige"
|
||||
|
281
config/locales/default.ru.yml
Normal file
281
config/locales/default.ru.yml
Normal file
@ -0,0 +1,281 @@
|
||||
ru:
|
||||
|
||||
errors:
|
||||
messages:
|
||||
domain_taken: "%{value} уже занято"
|
||||
invalid_domain: "%{value} имеет неверное значение"
|
||||
needs_admin_account: "Обязателен хотя бы один аккаунт администратора"
|
||||
protected_page: "Вы не можете удалять стартовую или 404 страницы"
|
||||
extname_changed: "Новый файл не имеет оригинального расширения"
|
||||
array_too_short: "слишком мал (минимальное число элементов %{count})"
|
||||
liquid_syntax: "Ошибка синтаксиса Liquid ('%{error}')"
|
||||
invalid_theme_file: "не может быть пустым или не является zip файлом"
|
||||
|
||||
too_short: "слишком короткий (не менее %{count} символов)"
|
||||
blank: "не может быть пустым"
|
||||
invalid: "имеет неверное значение"
|
||||
confirmation: "не совпадает с подтверждением"
|
||||
page:
|
||||
liquid_syntax: "Ошибка синтаксиса Liquid ('%{error}' в '%{fullpath}')"
|
||||
liquid_extend: "Страница '%{fullpath}' расширяет шаблон, который не существует"
|
||||
|
||||
attributes:
|
||||
defaults:
|
||||
pages:
|
||||
index:
|
||||
title: "Стартовая страница"
|
||||
body: "Содержимое стартовой страницы"
|
||||
"404":
|
||||
title: "Страница не найдена"
|
||||
body: "Содержимое страницы 404"
|
||||
other:
|
||||
body: "{% расширяет 'parent' %}"
|
||||
|
||||
mongoid:
|
||||
attributes:
|
||||
page:
|
||||
title: Имя
|
||||
parent: Родитель
|
||||
slug: Ссылка
|
||||
templatized: Шаблонизирована
|
||||
published: Опубликована
|
||||
listed: Меню
|
||||
redirect: Перенаправлена
|
||||
redirect_url: Адрес перенаправления
|
||||
cache_strategy: Стратегия кеширования
|
||||
content_type:
|
||||
name: Имя
|
||||
description: Описание
|
||||
slug: Ссылка
|
||||
order_by: Сортировать по
|
||||
order_direction: Направление сортировки
|
||||
highlighted_field_name: Выделенное имя поля
|
||||
group_by_field_name: Группировка по имени поля
|
||||
api_enabled: API включен
|
||||
asset:
|
||||
source: Файл
|
||||
account:
|
||||
email: Email
|
||||
name: Имя
|
||||
language: Язык
|
||||
password: Пароль
|
||||
password_confirmation: Подтверждение пароля
|
||||
snippet:
|
||||
body: Код
|
||||
slug: Ссылка
|
||||
name: Название
|
||||
theme_asset:
|
||||
content_type: Тип содержимого
|
||||
site:
|
||||
name: Имя сайта
|
||||
domain_name: Домен
|
||||
subdomain: Поддомен
|
||||
restricted_access: Активный ?
|
||||
access_login: Имя пользователя
|
||||
access_password: "Пароль"
|
||||
|
||||
pagination:
|
||||
previous: "« Предыдущая"
|
||||
next: "Следующая »"
|
||||
|
||||
date:
|
||||
formats:
|
||||
# Форматы указываются в виде, поддерживаемом strftime.
|
||||
# По умолчанию используется default.
|
||||
# Можно добавлять собственные форматы
|
||||
#
|
||||
#
|
||||
# Use the strftime parameters for formats.
|
||||
# When no format has been given, it uses default.
|
||||
# You can provide other formats here if you like!
|
||||
default: "%d.%m.%Y"
|
||||
short: "%d %b"
|
||||
long: "%d %B %Y"
|
||||
|
||||
# Названия дней недели -- контекстные и отдельностоящие
|
||||
day_names: [воскресенье, понедельник, вторник, среда, четверг, пятница, суббота]
|
||||
standalone_day_names: [Воскресенье, Понедельник, Вторник, Среда, Четверг, Пятница, Суббота]
|
||||
abbr_day_names: [Вс, Пн, Вт, Ср, Чт, Пт, Сб]
|
||||
|
||||
# Названия месяцев -- сокращенные и полные, плюс отдельностоящие.
|
||||
# Не забудьте nil в начале массиве (~)
|
||||
#
|
||||
#
|
||||
# Don't forget the nil at the beginning; there's no such thing as a 0th month
|
||||
month_names: [~, января, февраля, марта, апреля, мая, июня, июля, августа, сентября, октября, ноября, декабря]
|
||||
standalone_month_names: [~, Январь, Февраль, Март, Апрель, Май, Июнь, Июль, Август, Сентябрь, Октябрь, Ноябрь, Декабрь]
|
||||
abbr_month_names: [~, янв., февр., марта, апр., мая, июня, июля, авг., сент., окт., нояб., дек.]
|
||||
standalone_abbr_month_names: [~, янв., февр., март, апр., май, июнь, июль, авг., сент., окт., нояб., дек.]
|
||||
|
||||
# Порядок компонентов даты для хелперов
|
||||
#
|
||||
#
|
||||
# Used in date_select and datime_select.
|
||||
order:
|
||||
- :day
|
||||
- :month
|
||||
- :year
|
||||
|
||||
time:
|
||||
# Форматы времени
|
||||
formats:
|
||||
default: "%a, %d %b %Y, %H:%M:%S %z"
|
||||
short: "%d %b, %H:%M"
|
||||
long: "%d %B %Y, %H:%M"
|
||||
|
||||
# am/pm решено перевести как "утра/вечера" :)
|
||||
am: "утра"
|
||||
pm: "вечера"
|
||||
|
||||
number:
|
||||
# Используется в number_with_delimiter()
|
||||
# Также является установками по умолчанию для 'currency', 'percentage', 'precision', 'human'
|
||||
#
|
||||
# Used in number_with_delimiter()
|
||||
# These are also the defaults for 'currency', 'percentage', 'precision', and 'human'
|
||||
format:
|
||||
# Sets the separator between the units, for more precision (e.g. 1.0 / 2.0 == 0.5)
|
||||
separator: "."
|
||||
# Delimets thousands (e.g. 1,000,000 is a million) (always in groups of three)
|
||||
delimiter: " "
|
||||
# Number of decimals, behind the separator (the number 1 with a precision of 2 gives: 1.00)
|
||||
precision: 3
|
||||
|
||||
# Used in number_to_currency()
|
||||
currency:
|
||||
format:
|
||||
# Формат отображения валюты и обозначение самой валюты
|
||||
#
|
||||
#
|
||||
# Where is the currency sign? %u is the currency unit, %n the number (default: $5.00)
|
||||
format: "%n %u"
|
||||
unit: "руб."
|
||||
# These three are to override number.format and are optional
|
||||
separator: "."
|
||||
delimiter: " "
|
||||
precision: 2
|
||||
|
||||
# Used in number_to_percentage()
|
||||
percentage:
|
||||
format:
|
||||
# These three are to override number.format and are optional
|
||||
# separator:
|
||||
delimiter: ""
|
||||
|
||||
# Used in number_to_precision()
|
||||
precision:
|
||||
format:
|
||||
# These three are to override number.format and are optional
|
||||
# separator:
|
||||
delimiter: ""
|
||||
# precision:
|
||||
|
||||
# Used in number_to_human_size()
|
||||
human:
|
||||
format:
|
||||
# These three are to override number.format and are optional
|
||||
# separator:
|
||||
delimiter: ""
|
||||
precision: 1
|
||||
|
||||
# Rails 2.2
|
||||
# storage_units: [байт, КБ, МБ, ГБ, ТБ]
|
||||
|
||||
# Rails 2.3
|
||||
storage_units:
|
||||
# Storage units output formatting.
|
||||
# %u is the storage unit, %n is the number (default: 2 MB)
|
||||
format: "%n %u"
|
||||
units:
|
||||
byte:
|
||||
one: "байт"
|
||||
few: "байта"
|
||||
many: "байт"
|
||||
other: "байта"
|
||||
kb: "КБ"
|
||||
mb: "МБ"
|
||||
gb: "ГБ"
|
||||
tb: "ТБ"
|
||||
|
||||
# Используется в хелперах distance_of_time_in_words(), distance_of_time_in_words_to_now(), time_ago_in_words()
|
||||
#
|
||||
#
|
||||
# Used in distance_of_time_in_words(), distance_of_time_in_words_to_now(), time_ago_in_words()
|
||||
datetime:
|
||||
distance_in_words:
|
||||
half_a_minute: "меньше минуты"
|
||||
less_than_x_seconds:
|
||||
one: "меньше %{count} секунды"
|
||||
few: "меньше %{count} секунд"
|
||||
many: "меньше %{count} секунд"
|
||||
other: "меньше %{count} секунды"
|
||||
x_seconds:
|
||||
one: "%{count} секунда"
|
||||
few: "%{count} секунды"
|
||||
many: "%{count} секунд"
|
||||
other: "%{count} секунды"
|
||||
less_than_x_minutes:
|
||||
one: "меньше %{count} минуты"
|
||||
few: "меньше %{count} минут"
|
||||
many: "меньше %{count} минут"
|
||||
other: "меньше %{count} минуты"
|
||||
x_minutes:
|
||||
one: "%{count} минуту"
|
||||
few: "%{count} минуты"
|
||||
many: "%{count} минут"
|
||||
other: "%{count} минуты"
|
||||
about_x_hours:
|
||||
one: "около %{count} часа"
|
||||
few: "около %{count} часов"
|
||||
many: "около %{count} часов"
|
||||
other: "около %{count} часа"
|
||||
x_days:
|
||||
one: "%{count} день"
|
||||
few: "%{count} дня"
|
||||
many: "%{count} дней"
|
||||
other: "%{count} дня"
|
||||
about_x_months:
|
||||
one: "около %{count} месяца"
|
||||
few: "около %{count} месяцев"
|
||||
many: "около %{count} месяцев"
|
||||
other: "около %{count} месяца"
|
||||
x_months:
|
||||
one: "%{count} месяц"
|
||||
few: "%{count} месяца"
|
||||
many: "%{count} месяцев"
|
||||
other: "%{count} месяца"
|
||||
about_x_years:
|
||||
one: "около %{count} года"
|
||||
few: "около %{count} лет"
|
||||
many: "около %{count} лет"
|
||||
other: "около %{count} лет"
|
||||
over_x_years:
|
||||
one: "больше %{count} года"
|
||||
few: "больше %{count} лет"
|
||||
many: "больше %{count} лет"
|
||||
other: "больше %{count} лет"
|
||||
almost_x_years:
|
||||
one: "почти %{count} год"
|
||||
few: "почти %{count} года"
|
||||
many: "почти %{count} лет"
|
||||
other: "почти %{count} лет"
|
||||
prompts:
|
||||
year: "Год"
|
||||
month: "Месяц"
|
||||
day: "День"
|
||||
hour: "Часов"
|
||||
minute: "Минут"
|
||||
second: "Секунд"
|
||||
|
||||
|
||||
# Used in array.to_sentence.
|
||||
support:
|
||||
array:
|
||||
# Rails 2.2
|
||||
sentence_connector: "и"
|
||||
skip_last_comma: true
|
||||
|
||||
# Rails 2.3
|
||||
words_connector: ", "
|
||||
two_words_connector: " и "
|
||||
last_word_connector: " и "
|
63
config/locales/devise.ru.yml
Normal file
63
config/locales/devise.ru.yml
Normal file
@ -0,0 +1,63 @@
|
||||
ru:
|
||||
errors:
|
||||
messages:
|
||||
not_found: "не найден"
|
||||
already_confirmed: "был уже подтвержден"
|
||||
not_locked: "не был заблокирован"
|
||||
|
||||
devise:
|
||||
failure:
|
||||
admin:
|
||||
unauthenticated: 'Вам необходимо войти или зарегистрироваться перед тем, как продолжить.'
|
||||
unconfirmed: 'Вы должны подтвердить аккаунт перед продолжением.'
|
||||
locked: 'Ваш аккаунт заблокирован.'
|
||||
invalid: 'Неверный email или пароль.'
|
||||
no_membership: 'Ваш аккаунт не зарегистирован на сайте, пожалуйста обратитесь к администратору сайта для получения доступа.'
|
||||
invalid_token: 'Неверный authentication token.'
|
||||
timeout: 'Срок действия вашей сессии истек, пожалуйста залогиньтесь для продолжения.'
|
||||
inactive: 'Ваш аккаунт еще не был активирован.'
|
||||
sessions:
|
||||
admin:
|
||||
signed_in: 'Вход выполнен успешно.'
|
||||
signed_out: 'Выход выполнен успешно.'
|
||||
passwords:
|
||||
admin:
|
||||
send_instructions: 'Вы получите письмо с инструкциями о том, как сбросить ваш пароль, через несколько минут.'
|
||||
updated: 'Ваш пароль был успешно изменен. Вы вошли в систему.'
|
||||
confirmations:
|
||||
admin:
|
||||
send_instructions: 'Вы получите письмо с инструкциями о том, как подтвердить ваш аккаунт, через несколько минут.'
|
||||
confirmed: 'Ваша учетная запись была успешно подтверждена. Вы вошли в систему.'
|
||||
registrations:
|
||||
admin:
|
||||
signed_up: 'Вы успешно зарегистрировались.'
|
||||
updated: 'Вы успешно обновили ваш аккаунт.'
|
||||
destroyed: 'До свидания! Ваш аккаунт был успешно отменен. Мы надеемся скоро увидеть вас снова.'
|
||||
unlocks:
|
||||
admin:
|
||||
send_instructions: 'Вам будет отправлено письмо с инструкциями о том, как разблокировать ваш аккаунт, в течение нескольких минут.'
|
||||
unlocked: 'Ваша учетная запись была успешно разблокирована. Вы вошли в систему.'
|
||||
mailer:
|
||||
admin:
|
||||
confirmation_instructions: 'Инструкции подтверждения'
|
||||
reset_password_instructions: 'Инструкции по сбросу пароля'
|
||||
unlock_instructions: 'Инструкции по разблокированию'
|
||||
|
||||
|
||||
admin:
|
||||
mailer:
|
||||
common:
|
||||
hello: Здравствуйте
|
||||
|
||||
confirmation_instructions:
|
||||
you_can_confirm_your_account_through_the_link_below: "Вы можете подтвердить ваш аккаунт с помощью ссылки, расположенной ниже:"
|
||||
confirm_my_account: "Подтвердить мой аккаунт"
|
||||
reset_password_instructions:
|
||||
reset_password_instruction: "Кто-то запросил ссылку для изменения вашего пароля, и вы можете сделать это через ссылку, приведенную ниже:"
|
||||
change_my_password: "Изменить мой пароль"
|
||||
wrong_request_instruction: "Если вы не запрашивали это, пожалуйста проигнорируйте это письмо."
|
||||
unchange_password_message: "Ваш пароль не будет изменен до тех пор, пока вы не получите доступ к ссылке, приведенной выше, и создатите новую."
|
||||
unlock_instructions:
|
||||
locked_account_message: "Ваша учетная запись была заблокирована из-за чрезмерного количества безуспешных попыток входа."
|
||||
unlock_account_instruction: "Нажмите ссылку ниже, чтобы разблокировать ваш аккаунт:"
|
||||
unlock_my_account: "Разблокировать мой аккаунт"
|
106
config/locales/flash.ru.yml
Normal file
106
config/locales/flash.ru.yml
Normal file
@ -0,0 +1,106 @@
|
||||
ru:
|
||||
flash:
|
||||
admin:
|
||||
pages:
|
||||
create:
|
||||
notice: "Страница успешно создана."
|
||||
alert: "Страница не создана."
|
||||
update:
|
||||
notice: "Страница успешно обновлена."
|
||||
alert: "Страница не обновлена."
|
||||
sort:
|
||||
notice: "Страницы успешно отсортированы."
|
||||
destroy:
|
||||
notice: "Страницы успешно удалены."
|
||||
|
||||
contents:
|
||||
create:
|
||||
notice: "Контент успешно создан."
|
||||
alert: "Контент не создан."
|
||||
update:
|
||||
notice: "Контент успешно обновлен."
|
||||
alert: "Контент не обновлен."
|
||||
sort:
|
||||
notice: "Содержимое успешно отсортировано."
|
||||
destroy:
|
||||
notice: "Содержимое успешно удалено."
|
||||
|
||||
content_types:
|
||||
create:
|
||||
notice: "Модель успешно создана."
|
||||
alert: "Модель не создана."
|
||||
update:
|
||||
notice: "Модель успешно обновлена."
|
||||
alert: "Модель не обновлена."
|
||||
destroy:
|
||||
notice: "Модель успешно удалена."
|
||||
|
||||
current_site:
|
||||
update:
|
||||
notice: "Мой сайт успешно обновлен."
|
||||
alert: "Мой сайт не обновлен."
|
||||
|
||||
snippets:
|
||||
create:
|
||||
notice: "Сниппет успешно создан."
|
||||
alert: "Сниппет не создан."
|
||||
update:
|
||||
notice: "Сниппет успешно обновлен."
|
||||
alert: "Сниппет не обновлен."
|
||||
destroy:
|
||||
notice: "Сниппет успешно удален."
|
||||
|
||||
accounts:
|
||||
create:
|
||||
notice: "Аккаунт успешно создан."
|
||||
alert: "Аккаунт не создан."
|
||||
|
||||
my_account:
|
||||
update:
|
||||
notice: "Мой аккаунт успешно обновлен."
|
||||
alert: "Мой аккаунт не обновлен."
|
||||
|
||||
sites:
|
||||
create:
|
||||
notice: "Сайт успешно создан."
|
||||
alert: "Сайт не создан."
|
||||
destroy:
|
||||
notice: "Сайт успешно удален."
|
||||
|
||||
memberships:
|
||||
create:
|
||||
notice: "Учетная запись успешно создана."
|
||||
alert: "Учетная запись не создана."
|
||||
already_created: "Учетная запись уже добавлена в текущий сайт."
|
||||
|
||||
assets:
|
||||
create:
|
||||
notice: "Файл успешно создан."
|
||||
alert: "Файл не создан."
|
||||
update:
|
||||
notice: "Файл успешно обновлен."
|
||||
alert: "Файл не обновлен."
|
||||
|
||||
theme_assets:
|
||||
create:
|
||||
notice: "Файл успешно создан."
|
||||
alert: "Файл не создан."
|
||||
update:
|
||||
notice: "Файл успешно обновлен."
|
||||
alert: "Файл не обновлен."
|
||||
destroy:
|
||||
notice: "Файл успешно удален."
|
||||
|
||||
custom_fields:
|
||||
update:
|
||||
alert: "Поле не обновлено"
|
||||
|
||||
cross_domain_sessions:
|
||||
create:
|
||||
alert: "Вам необходимо войти"
|
||||
|
||||
import:
|
||||
create:
|
||||
done: "Ваш сайт успешно обновлен"
|
||||
notice: "Ваш сайт обновляется"
|
||||
alert: "Импорт не завершен."
|
99
config/locales/formtastic.ru.yml
Normal file
99
config/locales/formtastic.ru.yml
Normal file
@ -0,0 +1,99 @@
|
||||
ru:
|
||||
formtastic:
|
||||
titles:
|
||||
information: Основная информация
|
||||
advanced_options: Дополнительные настройки
|
||||
meta: SEO Metadata
|
||||
seo: SEO настройки
|
||||
robots_txt: Robots.txt файл
|
||||
code: Код
|
||||
raw_template: Шаблон
|
||||
credentials: Учетная запись
|
||||
language: Язык
|
||||
sites: Сайты
|
||||
access_points: Точки доступа
|
||||
memberships: Учетные записи
|
||||
membership_email: Email аккаунта
|
||||
file: Файл
|
||||
preview: Предпросмотр
|
||||
options: Дополнительные настройки
|
||||
custom_fields: Пользовательские поля
|
||||
other_fields: Другая информация
|
||||
presentation: Представление
|
||||
attributes: Аттрибуты
|
||||
upload: Загрузить
|
||||
labels:
|
||||
theme_asset:
|
||||
plain_text_name: Имя файла
|
||||
content_type: Тип файла
|
||||
new:
|
||||
source: Файл
|
||||
edit:
|
||||
source: Заменить файл
|
||||
custom_fields:
|
||||
field:
|
||||
_alias: Алиас
|
||||
import:
|
||||
new:
|
||||
source: Файл
|
||||
samples: Копировать образцы
|
||||
reset: Сбросить сайт
|
||||
default_site_template: "Используйте шаблон сайта по умолчанию. Нажмите <a href='#'>здесь</a> для загрузки шаблона сайта в виде zip файла."
|
||||
content_type:
|
||||
item_template: Шаблон элемента
|
||||
api_accounts: Уведомленные аккаунты
|
||||
content_instance:
|
||||
_slug: Постоянная ссылка
|
||||
account:
|
||||
edit:
|
||||
password: Новый пароль
|
||||
password_confirmation: Подтверждение нового пароля
|
||||
page:
|
||||
seo_title: Название
|
||||
|
||||
hints:
|
||||
page:
|
||||
published: "Только аутентифицированным пользователям разрешается просматривать неопубликованные страницы."
|
||||
cache_strategy: "Кэшировать страницу для лучшей производительности. Вариант 'Простое' является хорошим компромиссом."
|
||||
templatized: "Используйте страницу в качестве шаблона для определенной вами модели."
|
||||
listed: "Контролируйте возможность показа страницы из сгенерированных меню."
|
||||
content_type_id: "Тип содержимого, для которого эта страница будет выступать в качестве шаблона."
|
||||
seo_title: "Определите заголовок страницы, который будет использоваться как значение тэга title в секции head. Оставьте пустым, если вы хотите использовать значение по умолчанию из настроек сайта."
|
||||
meta_keywords: "Переопределяет meta keywords сайта, используемые внутри тэга head страницы. Они разделены запятыми."
|
||||
meta_description: "Переопределяет meta description сайта, используемые внутри тэга head страницы."
|
||||
snippet:
|
||||
slug: "Вам необходимо знать это для вставки сниппета в страницу"
|
||||
site:
|
||||
seo_title: "Задайте глобальное значение здесь, которое будет использовано как значение для тэга title в секции head."
|
||||
meta_keywords: "Meta keywords используются внутри тэга head страницы. Они разделяются запятыми. Требуется для SEO."
|
||||
meta_description: "Meta description используются для тэга head страницы. Необходимо для SEO."
|
||||
domain_name: "ex: locomotiveapp.org"
|
||||
robots_txt: "Содержимое файла <span class='code'>/robots.txt</span>. См. <a href='http://www.w3.org/TR/html4/appendix/notes.html#h-B.4.1.1'>url</a> для получения большей информации."
|
||||
theme_asset:
|
||||
slug: "Ва не нужно добавлять расширение файла (.css or .js)"
|
||||
edit:
|
||||
source: "Вы можете заменить это файлом, имеющим такое же расширение"
|
||||
asset:
|
||||
source: "Все типы файлов приняты."
|
||||
edit:
|
||||
source: "Текущий файл доступен здесь %{url}"
|
||||
update:
|
||||
source: "Текущий файл доступен здесь %{url}"
|
||||
custom_fields:
|
||||
field:
|
||||
_alias: "Свойство, доступное в шаблонах liquid"
|
||||
hint: "Текст, отображенный в форме модели, находится ниже поля"
|
||||
content_instance:
|
||||
_slug: "Свойство, используемое для генерации ссылки (url) на страницу, работающей как шаблон для этого типа содержимого (ex: \"template_page/{{ your_object._permalink }})\"."
|
||||
seo_title: "Значение, вводимое вами, будет заменять SEO заголовок шаблонизированной страницы, связанной с вашей моделью."
|
||||
meta_keywords: "Переопределяет meta keywords сайта, используемые внутри тэга head страницы. Разделяются запятыми."
|
||||
meta_description: "Переопределяет meta description сайта, используемые внутри тэга head страницы."
|
||||
import:
|
||||
source: "Файл zip, содержащий database.yml вместе с файлами и шаблонами"
|
||||
samples: "Если включено, процесс импорта также скопирует содержимое и файлы"
|
||||
reset: "Если включено, все данные вашего сайта будут уничтожены перед импортом нового сайта"
|
||||
content_type:
|
||||
item_template: "Вы можете задавать текст, отображаемый для каждого элемента в списке. Просто используйте Liquid. Пр.: {{ content.name }})"
|
||||
api_enabled: "Это используется для того, чтобы дать людям извне возможность создавать новые экземляры (пример: сообщения в форме контакта)"
|
||||
api_accounts: "Письмо с уведомлением будет отправлено на каждый аккаунт из списка выше, когда создан новый экземпляр"
|
||||
|
@ -65,6 +65,6 @@ Rails.application.routes.draw do
|
||||
|
||||
# magic urls
|
||||
match '/' => 'admin/rendering#show'
|
||||
match '*path/edit' => 'admin/rendering#show', :defaults => { :editing => true }
|
||||
match '*path/edit' => 'admin/rendering#edit'
|
||||
match '*path' => 'admin/rendering#show'
|
||||
end
|
||||
|
@ -1,9 +0,0 @@
|
||||
account = Account.create! :name => 'Admin', :email => 'admin@example.com', :password => 'locomotive', :password_confirmation => 'locomotive'
|
||||
|
||||
site = Site.new :name => 'Locomotive test website', :subdomain => 'test'
|
||||
site.memberships.build :account => account, :admin => true
|
||||
site.save!
|
||||
|
||||
puts "Your first website has been created !"
|
||||
puts "Admin url: http://test.example.com:3000/admin"
|
||||
puts "Crendetials: admin@example.com / locomotive"
|
1
doc/TODO
1
doc/TODO
@ -70,7 +70,6 @@ BUGS:
|
||||
|
||||
NICE TO HAVE:
|
||||
- export site
|
||||
|
||||
- super_finder
|
||||
- traffic statistics
|
||||
- asset picker (content instance)
|
||||
|
@ -7,3 +7,7 @@
|
||||
- better spanish translations (#161, #162)
|
||||
- fix carrierwave version to 0.5.6 (#163)
|
||||
- has_many target is not exported correctly (issue #165) + fix the import module as well
|
||||
- XSS vulnerability when adding new content from the api_contents_controller (#170)
|
||||
- small bugs: #169, #171, #179
|
||||
- russian version (#188)
|
||||
-
|
28
features/admin/authorization/account_settings.feature
Normal file
28
features/admin/authorization/account_settings.feature
Normal file
@ -0,0 +1,28 @@
|
||||
Feature: Account Settings
|
||||
In order to ensure sites are not tampered with
|
||||
As an admin, designer or author
|
||||
I will be restricted based on my role
|
||||
|
||||
Background:
|
||||
Given I have the site: "test site" set up
|
||||
And I have a designer and an author
|
||||
|
||||
Scenario: As an unauthenticated user
|
||||
Given I am not authenticated
|
||||
When I go to account settings
|
||||
Then I should see "Log in"
|
||||
|
||||
Scenario: Accessing site settings as an Admin
|
||||
Given I am an authenticated "admin"
|
||||
When I go to account settings
|
||||
Then I should see "new site"
|
||||
|
||||
Scenario: Accessing site settings as a Designer
|
||||
Given I am an authenticated "designer"
|
||||
When I go to account settings
|
||||
Then I should not see "new site"
|
||||
|
||||
Scenario: Accessing site settings as an Author
|
||||
Given I am an authenticated "author"
|
||||
When I go to account settings
|
||||
Then I should not see "new site"
|
@ -30,7 +30,7 @@ Background:
|
||||
Given I am an authenticated "designer"
|
||||
When I go to site settings
|
||||
Then I should see "import"
|
||||
And I should see "add account"
|
||||
And I should not see "add account"
|
||||
And I should see "SEO settings"
|
||||
And I should see "Access points"
|
||||
And I should not see the role dropdown on myself
|
||||
|
@ -0,0 +1,48 @@
|
||||
@javascript
|
||||
Feature: Inline frontend editing
|
||||
In order to ensure site content is not tampered with
|
||||
As an admin, designer or author
|
||||
I will be restricted based on my role
|
||||
|
||||
Background:
|
||||
Given I have the site: "test site" set up
|
||||
And I have a designer and an author
|
||||
Given a page named "about" with the template:
|
||||
"""
|
||||
<html>
|
||||
<head>{% inline_editor %}</head>
|
||||
<body>Page Content</body>
|
||||
</html>
|
||||
"""
|
||||
|
||||
Scenario: As an unauthenticated user
|
||||
Given I am not authenticated
|
||||
When I view the rendered page at "/about"
|
||||
Then I should not see "edit"
|
||||
When I view the rendered page at "/about/edit"
|
||||
Then I should not see "Page Content"
|
||||
And I should see "Log in"
|
||||
|
||||
Scenario: Inline editing as an Admin
|
||||
Given I am an authenticated "admin"
|
||||
When I view the rendered page at "/about"
|
||||
Then I should see "admin"
|
||||
And I should see "edit"
|
||||
When I view the rendered page at "/about/edit"
|
||||
Then I should see "Page Content"
|
||||
|
||||
Scenario: Inline editing as a Designer
|
||||
Given I am an authenticated "designer"
|
||||
When I view the rendered page at "/about"
|
||||
Then I should see "admin"
|
||||
And I should see "edit"
|
||||
When I view the rendered page at "/about/edit"
|
||||
Then I should see "Page Content"
|
||||
|
||||
Scenario: Inline editing as an Author
|
||||
Given I am an authenticated "author"
|
||||
When I view the rendered page at "/about"
|
||||
Then I should see "admin"
|
||||
And I should see "edit"
|
||||
When I view the rendered page at "/about/edit"
|
||||
Then I should see "Page Content"
|
@ -6,6 +6,7 @@ Feature: Theme Assets
|
||||
Background:
|
||||
Given I have the site: "test site" set up
|
||||
And I have a designer and an author
|
||||
And I have an image theme asset named "dog.png"
|
||||
|
||||
Scenario: As an unauthenticated user
|
||||
Given I am not authenticated
|
||||
@ -20,6 +21,8 @@ Background:
|
||||
And I should see "Snippets"
|
||||
And I should see "Style and javascript"
|
||||
And I should see "Images"
|
||||
And I should see "dog.png"
|
||||
And I should see a delete image button
|
||||
|
||||
Scenario: Accessing theme assets as a Designer
|
||||
Given I am an authenticated "designer"
|
||||
@ -29,6 +32,8 @@ Background:
|
||||
And I should see "Snippets"
|
||||
And I should see "Style and javascript"
|
||||
And I should see "Images"
|
||||
And I should see "dog.png"
|
||||
And I should see a delete image button
|
||||
|
||||
Scenario: Accessing theme assets as an Author
|
||||
Given I am an authenticated "author"
|
||||
@ -38,3 +43,5 @@ Background:
|
||||
And I should not see "Snippets"
|
||||
And I should not see "Style and javascript"
|
||||
And I should see "Images"
|
||||
And I should see "dog.png"
|
||||
And I should not see a delete image button
|
||||
|
@ -6,16 +6,28 @@ Feature: Login
|
||||
Background:
|
||||
Given I have the site: "test site" set up
|
||||
|
||||
Scenario: Successful authentication
|
||||
Scenario: Successfully logging in
|
||||
When I go to login
|
||||
And I fill in "Email" with "admin@locomotiveapp.org"
|
||||
And I fill in "Password" with "easyone"
|
||||
And I press "Log in"
|
||||
Then I should see "Listing pages"
|
||||
|
||||
Scenario: Failed authentication
|
||||
Scenario: Attempting to login with an invalid emai or password
|
||||
When I go to login
|
||||
And I fill in "Email" with "admin@locomotiveapp.org"
|
||||
And I fill in "Password" with ""
|
||||
And I press "Log in"
|
||||
Then I should not see "Listing pages"
|
||||
And I should see "Invalid email or password"
|
||||
|
||||
Scenario: Attempting to login with an account without a membership
|
||||
Given the following accounts exist:
|
||||
| email | password | password_confirmation |
|
||||
| john@locomotiveapp.org | bluecheese | bluecheese |
|
||||
When I go to login
|
||||
And I fill in "Email" with "john@locomotiveapp.org"
|
||||
And I fill in "Password" with "bluecheese"
|
||||
And I press "Log in"
|
||||
Then I should not see "Listing pages"
|
||||
And I should see "not a member of this site"
|
||||
|
@ -16,21 +16,3 @@ Scenario: Simple Page
|
||||
"""
|
||||
Hello World
|
||||
"""
|
||||
|
||||
# @wip
|
||||
# Scenario: Simple Page with Admin Inline Editing
|
||||
# Given a simple page named "hello-world-inline" with the body:
|
||||
# """
|
||||
# {% block hello %}Hello World{% endblock %}
|
||||
# """
|
||||
# When And I'm an admin
|
||||
# And I view the rendered page at "/hello-world-inline"
|
||||
# Then the rendered output shoud look like:
|
||||
# """
|
||||
# <div class="inline-editing" data-url="/admin/parts/XXXX" data-title="hello">Hello World</div>
|
||||
# """
|
||||
#
|
||||
# {% block main %}Didier{% endblock %}
|
||||
#
|
||||
# {% block body %}{% block main %}{{ block.super }}Jacques{% endblock %}{% endblock %}
|
||||
# {% block body %}Hello mister Jacques{% endblock %}
|
25
features/engine/inline_front_end_editing.feature
Normal file
25
features/engine/inline_front_end_editing.feature
Normal file
@ -0,0 +1,25 @@
|
||||
@javascript
|
||||
Feature: Engine
|
||||
As an author
|
||||
In order to easily be able to modify the contents of my website
|
||||
I want to be able to edit the sites content on the front end
|
||||
|
||||
Background:
|
||||
Given I have the site: "test site" set up
|
||||
And I am an authenticated "author"
|
||||
|
||||
Scenario: Editing a short text field
|
||||
Given a page named "about" with the template:
|
||||
"""
|
||||
<html>
|
||||
<head>{% inline_editor %}</head>
|
||||
<body>{% editable_short_text 'owner' %}Tom{% endeditable_short_text %} owns this website</body>
|
||||
</html>
|
||||
"""
|
||||
When I view the rendered page at "/about"
|
||||
Then I should see "edit"
|
||||
When I follow "edit"
|
||||
And I type the content "Mario" into the first editable field
|
||||
And I follow "save"
|
||||
And I view the rendered page at "/about"
|
||||
Then I should see "Mario owns this website"
|
42
features/engine/tablerow.feature
Normal file
42
features/engine/tablerow.feature
Normal file
@ -0,0 +1,42 @@
|
||||
Feature: TableRow liquid tags
|
||||
As a designer
|
||||
I want to be able to use the tablerow liquid tag with locomotive contents
|
||||
|
||||
Background:
|
||||
Given I have the site: "test site" set up
|
||||
And I have a custom model named "Projects" with
|
||||
| label | kind | required |
|
||||
| Name | string | true |
|
||||
And I have entries for "Projects" with
|
||||
| name |
|
||||
| Project 1 |
|
||||
| Project 2 |
|
||||
| Project 3 |
|
||||
|
||||
Scenario: Use the tablerow tag
|
||||
Given a page named "project-table" with the template:
|
||||
"""
|
||||
<h1>Projects</h1>
|
||||
<table>
|
||||
{% tablerow project in contents.projects cols: 2 %}
|
||||
{{ project.name }}
|
||||
{% endtablerow %}
|
||||
</table>
|
||||
"""
|
||||
When I view the rendered page at "/project-table"
|
||||
Then the rendered output should look like:
|
||||
"""
|
||||
<h1>Projects</h1>
|
||||
<table>
|
||||
<tr class="row1">
|
||||
<td class="col1">
|
||||
Project 1
|
||||
</td><td class="col2">
|
||||
Project 2
|
||||
</td></tr>
|
||||
<tr class="row2"><td class="col1">
|
||||
Project 3
|
||||
</td></tr>
|
||||
|
||||
</table>
|
||||
"""
|
@ -5,7 +5,7 @@ Given /^I am not authenticated$/ do
|
||||
end
|
||||
|
||||
Given /^I am an authenticated "([^"]*)"$/ do |role|
|
||||
@member = Site.first.memberships.where(:role => role.downcase).first || Factory(role.downcase.to_sym, :site => Site.first)
|
||||
@member = Site.first.memberships.where(:role => role.downcase).first || FactoryGirl.create(role.downcase.to_sym, :site => Site.first)
|
||||
|
||||
Given %{I go to login}
|
||||
And %{I fill in "Email" with "#{@member.account.email}"}
|
||||
|
@ -1,6 +1,6 @@
|
||||
Given %r{^I have a custom model named "([^"]*)" with$} do |name, fields|
|
||||
site = Site.first
|
||||
content_type = Factory.build(:content_type, :site => site, :name => name)
|
||||
content_type = FactoryGirl.build(:content_type, :site => site, :name => name)
|
||||
fields.hashes.each do |field|
|
||||
if (target_name = field.delete('target')).present?
|
||||
target_content_type = site.content_types.where(:name => target_name).first
|
||||
|
@ -1,7 +1,3 @@
|
||||
Given /^a simple page named "([^"]*)" with the body:$/ do |page_slug, page_contents|
|
||||
@page = create_content_page(page_slug, page_contents)
|
||||
end
|
||||
|
||||
# modify an editable element
|
||||
Given /^the editable element "([^"]*)" in the "([^"]*)" page with the content "([^"]*)"$/ do |slug, page_slug, content|
|
||||
page = @site.pages.where(:slug => page_slug).first
|
||||
@ -15,3 +11,14 @@ Given /^the editable element "([^"]*)" for the "([^"]*)" block in the "([^"]*)"
|
||||
page.find_editable_element(block, slug).content = content
|
||||
page.save!
|
||||
end
|
||||
|
||||
When /^I type the content "([^"]*)" into the first editable field$/ do |content|
|
||||
page.execute_script %{
|
||||
$(document).ready(function() {
|
||||
editable = GENTICS.Aloha.editables[0];
|
||||
editable.obj.text('#{content}');
|
||||
editable.blur();
|
||||
});
|
||||
}
|
||||
end
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
# helps create a simple content page (parent: "index") with a slug, contents, and template
|
||||
def create_content_page(page_slug, page_contents, template = nil)
|
||||
@home = @site.pages.where(:slug => "index").first || Factory(:page)
|
||||
@home = @site.pages.where(:slug => "index").first || FactoryGirl.create(:page)
|
||||
page = @site.pages.create(:slug => page_slug, :body => page_contents, :parent => @home, :title => "some title", :published => true, :raw_template => template)
|
||||
page.should be_valid
|
||||
page
|
||||
@ -26,7 +26,12 @@ end
|
||||
|
||||
# try to render a page by slug
|
||||
When /^I view the rendered page at "([^"]*)"$/ do |path|
|
||||
# If we're running selenium then we need to use a differnt port
|
||||
if Capybara.current_driver == :selenium
|
||||
visit "http://#{@site.domains.first}:#{Capybara.server_port}#{path}"
|
||||
else
|
||||
visit "http://#{@site.domains.first}#{path}"
|
||||
end
|
||||
end
|
||||
|
||||
# checks to see if a string is in the slug
|
||||
|
@ -5,7 +5,7 @@
|
||||
# - I have the site: "some site" set up with name: "Something", domain: "test2"
|
||||
#
|
||||
Given /^I have the site: "([^"]*)" set up(?: with #{capture_fields})?$/ do |site_factory, fields|
|
||||
@site = Factory(site_factory, parse_fields(fields))
|
||||
@site = FactoryGirl.create(site_factory, parse_fields(fields))
|
||||
@site.should_not be_nil
|
||||
|
||||
@admin = @site.memberships.first.account
|
||||
@ -13,8 +13,8 @@ Given /^I have the site: "([^"]*)" set up(?: with #{capture_fields})?$/ do |site
|
||||
end
|
||||
|
||||
Given /^I have a designer and an author$/ do
|
||||
Factory(:designer, :site => Site.first)
|
||||
Factory(:author, :site => Site.first)
|
||||
FactoryGirl.create(:designer, :site => Site.first)
|
||||
FactoryGirl.create(:author, :site => Site.first)
|
||||
end
|
||||
|
||||
Then /^I should be a administrator of the "([^"]*)" site$/ do |name|
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
# helps create a theme asset
|
||||
def create_plain_text_asset(name, type)
|
||||
asset = Factory.build(:theme_asset, {
|
||||
asset = FactoryGirl.build(:theme_asset, {
|
||||
:site => @site,
|
||||
:plain_text_name => name,
|
||||
:plain_text => 'Lorem ipsum',
|
||||
@ -24,8 +24,23 @@ Given /^a stylesheet asset named "([^"]*)"$/ do |name|
|
||||
@asset = create_plain_text_asset(name, 'stylesheet')
|
||||
end
|
||||
|
||||
Given /^I have an image theme asset named "([^"]*)"$/ do |name|
|
||||
@asset = FactoryGirl.create(:theme_asset, :site => @site, :source => File.open(Rails.root.join('spec', 'fixtures', 'assets', '5k.png')))
|
||||
@asset.source_filename = name
|
||||
@asset.save!
|
||||
end
|
||||
|
||||
|
||||
# other stuff
|
||||
|
||||
Then /^I should see "([^"]*)" as theme asset code$/ do |code|
|
||||
find(:css, "#theme_asset_plain_text").text.should == code
|
||||
end
|
||||
|
||||
Then /^I should see a delete image button$/ do
|
||||
page.has_css?("ul.theme-assets li .more a.remove").should be_true
|
||||
end
|
||||
|
||||
Then /^I should not see a delete image button$/ do
|
||||
page.has_css?("ul.theme-assets li .more a.remove").should be_false
|
||||
end
|
||||
|
@ -21,7 +21,7 @@ module Locomotive
|
||||
:media => [/^video/, 'application/x-shockwave-flash', 'application/x-swf', /^audio/, 'application/ogg', 'application/x-mp3'],
|
||||
:pdf => ['application/pdf', 'application/x-pdf'],
|
||||
:stylesheet => ['text/css'],
|
||||
:javascript => ['text/javascript', 'text/js', 'application/x-javascript', 'application/javascript'],
|
||||
:javascript => ['text/javascript', 'text/js', 'application/x-javascript', 'application/javascript', 'text/x-component'],
|
||||
:font => ['application/x-font-ttf', 'application/vnd.ms-fontobject', 'image/svg+xml', 'application/x-woff']
|
||||
}
|
||||
end
|
||||
|
@ -7,8 +7,8 @@ module Locomotive
|
||||
:reserved_subdomains => %w{www admin email blog webmail mail support help site sites},
|
||||
# :forbidden_paths => %w{layouts snippets stylesheets javascripts assets admin system api},
|
||||
:reserved_slugs => %w{stylesheets javascripts assets admin images api pages edit},
|
||||
:locales => %w{en de fr pt-BR it nl es},
|
||||
:site_locales => %w{en de fr pt-BR it nl es},
|
||||
:locales => %w{en de fr pt-BR it nl es ru},
|
||||
:site_locales => %w{en de fr pt-BR it nl es ru},
|
||||
:cookie_key => '_locomotive_session',
|
||||
:enable_logs => false,
|
||||
:hosting => :auto,
|
||||
@ -24,7 +24,7 @@ module Locomotive
|
||||
:entitystore => URI.encode("file:#{Rails.root}/tmp/dragonfly/cache/body")
|
||||
},
|
||||
:devise_modules => [:database_authenticatable, :recoverable, :rememberable, :trackable, :validatable, :encryptable, { :encryptor => :sha1 }],
|
||||
:context_assign_extensions => { }
|
||||
:context_assign_extensions => {}
|
||||
}
|
||||
|
||||
cattr_accessor :settings
|
||||
|
@ -26,6 +26,7 @@ require 'dragonfly'
|
||||
require 'cancan'
|
||||
require 'RMagick'
|
||||
require 'cells'
|
||||
require 'sanitize'
|
||||
|
||||
$:.unshift File.dirname(__FILE__)
|
||||
|
||||
|
@ -29,10 +29,16 @@ module Locomotive
|
||||
self.collection.each(&block)
|
||||
end
|
||||
|
||||
def each_with_index(&block)
|
||||
self.collection.each_with_index(&block)
|
||||
end
|
||||
|
||||
def size
|
||||
self.collection.size
|
||||
end
|
||||
|
||||
alias :length :size
|
||||
|
||||
def empty?
|
||||
self.collection.empty?
|
||||
end
|
||||
|
@ -64,6 +64,7 @@ module Locomotive
|
||||
# example: 'about/myphoto.jpg' | theme_image # <img src="images/about/myphoto.jpg" />
|
||||
def theme_image_tag(input, *args)
|
||||
image_options = inline_options(args_to_options(args))
|
||||
|
||||
"<img src=\"#{theme_image_url(input)}\" #{image_options}/>"
|
||||
end
|
||||
|
||||
@ -71,6 +72,7 @@ module Locomotive
|
||||
# input: url of the image OR asset drop
|
||||
def image_tag(input, *args)
|
||||
image_options = inline_options(args_to_options(args))
|
||||
|
||||
"<img src=\"#{get_url_from_asset(input)}\" #{image_options}/>"
|
||||
end
|
||||
|
||||
|
@ -26,6 +26,7 @@ module Locomotive
|
||||
:block => @context[:current_block].try(:name),
|
||||
:slug => @slug,
|
||||
:hint => @options[:hint],
|
||||
:priority => @options[:priority] || 0,
|
||||
:default_attribute => @options[:default],
|
||||
:default_content => default_content_option,
|
||||
:assignable => @options[:assignable],
|
||||
|
@ -114,7 +114,7 @@ module Locomotive
|
||||
end
|
||||
end
|
||||
|
||||
render :text => output, :layout => false, :status => page_status
|
||||
render :text => output, :layout => false, :status => page_status unless performed?
|
||||
end
|
||||
|
||||
def not_found_page
|
||||
@ -122,7 +122,7 @@ module Locomotive
|
||||
end
|
||||
|
||||
def editing_page?
|
||||
self.params[:editing] == true && current_admin
|
||||
@editing
|
||||
end
|
||||
|
||||
def page_status
|
||||
|
@ -17,7 +17,7 @@ Gem::Specification.new do |s|
|
||||
s.required_rubygems_version = '>= 1.3.6'
|
||||
s.rubyforge_project = 'nowarning'
|
||||
|
||||
s.add_dependency 'rails', '>= 3.0.9'
|
||||
s.add_dependency 'rails', '>= 3.0.10'
|
||||
s.add_dependency 'warden'
|
||||
s.add_dependency 'devise', '1.3.4'
|
||||
s.add_dependency 'devise_bushido_authenticatable', '1.0.0.alpha10'
|
||||
@ -33,6 +33,8 @@ Gem::Specification.new do |s|
|
||||
s.add_dependency 'formtastic', '~> 1.2.3'
|
||||
s.add_dependency 'inherited_resources', '~> 1.1.2'
|
||||
s.add_dependency 'cells'
|
||||
s.add_dependency 'highline'
|
||||
s.add_dependency 'sanitize'
|
||||
|
||||
s.add_dependency 'json_pure', '1.5.1'
|
||||
s.add_dependency 'bushido'
|
||||
@ -43,13 +45,13 @@ Gem::Specification.new do |s|
|
||||
s.add_dependency 'dragonfly', '~> 0.9.1'
|
||||
s.add_dependency 'rack-cache'
|
||||
|
||||
s.add_dependency 'custom_fields', '1.0.0.beta.22'
|
||||
s.add_dependency 'custom_fields', '1.0.0.beta.25'
|
||||
s.add_dependency 'cancan', '~> 1.6.0'
|
||||
s.add_dependency 'fog', '0.8.2'
|
||||
s.add_dependency 'mimetype-fu'
|
||||
s.add_dependency 'actionmailer-with-request'
|
||||
s.add_dependency 'httparty', '>= 0.6.1'
|
||||
s.add_dependency 'RedCloth', '4.2.7'
|
||||
s.add_dependency 'RedCloth', '4.2.8'
|
||||
s.add_dependency 'delayed_job', '2.1.4'
|
||||
s.add_dependency 'delayed_job_mongoid', '1.0.2'
|
||||
s.add_dependency 'rubyzip'
|
||||
|
BIN
public/images/admin/icons/flags/ru.png
Normal file
BIN
public/images/admin/icons/flags/ru.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 403 B |
@ -11,10 +11,10 @@ $(document).ready(function() {
|
||||
|
||||
if (context.data.new_item) {
|
||||
var newItemInfo = context.data.new_item;
|
||||
var option = new Option(newItemInfo.label, newItemInfo.url, true, true);
|
||||
var option = makeOption(newItemInfo.label, newItemInfo.url, true, true);
|
||||
context.select.append(option);
|
||||
|
||||
context.select.append(new Option('-'.repeat(newItemInfo.label.length), '', false, false));
|
||||
context.select.append(makeOption('-'.repeat(newItemInfo.label.length), '', false, false));
|
||||
}
|
||||
|
||||
for (var i = 0; i < context.data.collection.length; i++) {
|
||||
@ -27,7 +27,7 @@ $(document).ready(function() {
|
||||
for (var j = 0; j < obj.items.length; j++) {
|
||||
var innerObj = obj.items[j];
|
||||
if ($.inArray(innerObj[1], context.data.taken_ids) == -1) {
|
||||
optgroup.append(new Option(innerObj[0], innerObj[1], false, false));
|
||||
optgroup.append(makeOption(innerObj[0], innerObj[1], false, false));
|
||||
size++;
|
||||
}
|
||||
}
|
||||
@ -36,8 +36,7 @@ $(document).ready(function() {
|
||||
} else {
|
||||
if ($.inArray(obj[1], context.data.taken_ids) == -1)
|
||||
{
|
||||
var option = new Option("", obj[1], false, false);
|
||||
$(option).text(obj[0]);
|
||||
var option = makeOption(obj[0], obj[1], false, false);
|
||||
context.select.append(option);
|
||||
}
|
||||
}
|
||||
|
@ -121,7 +121,6 @@ var InlineEditorToolbar = {
|
||||
|
||||
_bindEvents: function() {
|
||||
var self = this;
|
||||
var fullpath = $('meta[name=page-fullpath]').attr('content');
|
||||
|
||||
this.form.live('submit', function (e) { $(this).callRemote(); e.stopPropagation(); e.preventDefault();
|
||||
}).bind('ajax:complete', function() { self.resetForm();
|
||||
@ -146,7 +145,8 @@ var InlineEditorToolbar = {
|
||||
window.location.href = window.location.href; break;
|
||||
|
||||
case 'back': // back to the non edition mode
|
||||
window.location.href = fullpath; break;
|
||||
var url = window.location.href.replace(/\/edit$/, '');
|
||||
window.location.href = url; break;
|
||||
|
||||
case 'drawer': // expand / shrink toolbar
|
||||
self.toggle(); break;
|
||||
|
@ -61,8 +61,6 @@ $.fn.imagepicker = function(options) {
|
||||
asset.removeClass('new-asset');
|
||||
|
||||
$('.asset-picker p.no-items').hide();
|
||||
|
||||
$('.asset-picker ul').scrollTo($('li.asset:last'), 400);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -20,7 +20,7 @@ p.no-items {
|
||||
|
||||
ul.assets {
|
||||
overflow: auto;
|
||||
height: 571px;
|
||||
height: 275px;
|
||||
}
|
||||
|
||||
ul.assets li.asset h4 a {
|
||||
|
@ -15,7 +15,6 @@
|
||||
<script src="/javascripts/admin/plugins/plupload/plupload.html5.min.js" type="text/javascript"></script>
|
||||
<script src="/javascripts/admin/plugins/plupload/jquery.plupload.queue.min.js" type="text/javascript"></script>
|
||||
<script src="/javascripts/admin/plugins/plupload/jquery.plupload.queue.min.js" type="text/javascript"></script>
|
||||
<script src="/javascripts/admin/plugins/scrollTo.js" type="text/javascript"></script>
|
||||
|
||||
<script type="text/javascript" src="js/dialog.js"></script>
|
||||
|
||||
|
@ -174,8 +174,6 @@ var MediafileDialog = {
|
||||
asset.removeClass('new-asset');
|
||||
|
||||
$('p.no-items').hide();
|
||||
|
||||
$('ul').scrollTo($('li.asset:last'), 400);
|
||||
},
|
||||
|
||||
_destroyAsset: function(asset) {
|
||||
|
@ -52,3 +52,10 @@ Object.size = function(obj) {
|
||||
}
|
||||
return size;
|
||||
};
|
||||
|
||||
// Make a DOM option for a select box. This code works around a bug in IE
|
||||
function makeOption(text, value, defaultSelected, selected) {
|
||||
var option = new Option('', value, defaultSelected, selected);
|
||||
$(option).text(text);
|
||||
return option;
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ describe Admin::GlobalActionsCell do
|
||||
|
||||
render_views
|
||||
|
||||
let(:menu) { render_cell('admin/global_actions', :show, :current_admin => Factory.build('admin user'), :current_site_url => 'http://www.yahoo.fr') }
|
||||
let(:menu) { render_cell('admin/global_actions', :show, :current_admin => FactoryGirl.build('admin user'), :current_site_url => 'http://www.yahoo.fr') }
|
||||
|
||||
describe 'show menu' do
|
||||
|
||||
|
91
spec/controllers/admin/api_contents_controller_spec.rb
Normal file
91
spec/controllers/admin/api_contents_controller_spec.rb
Normal file
@ -0,0 +1,91 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe Admin::ApiContentsController do
|
||||
|
||||
before(:each) do
|
||||
@site = FactoryGirl.create('existing site')
|
||||
@site.content_types.first.tap do |content_type|
|
||||
content_type.content_custom_fields.build :label => 'Name', :kind => 'string', :required => true
|
||||
content_type.content_custom_fields.build :label => 'Description', :kind => 'text'
|
||||
content_type.content_custom_fields.build :label => 'File', :kind => 'file'
|
||||
content_type.content_custom_fields.build :label => 'Active', :kind => 'boolean'
|
||||
end.save
|
||||
|
||||
controller.stubs(:require_site).returns(true)
|
||||
controller.stubs(:current_site).returns(@site)
|
||||
end
|
||||
|
||||
describe 'API disabled' do
|
||||
|
||||
it 'blocks the creation of a new instance' do
|
||||
post 'create', default_post_params
|
||||
|
||||
response.code.should eq('403')
|
||||
response.body.should == 'Api not enabled'
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
describe 'API enabled' do
|
||||
|
||||
before(:each) do
|
||||
ContentType.any_instance.stubs(:api_enabled?).returns(true)
|
||||
end
|
||||
|
||||
it 'saves a content' do
|
||||
post 'create', default_post_params
|
||||
|
||||
response.should redirect_to('http://www.locomotivecms.com/success')
|
||||
|
||||
@site.reload.content_types.first.contents.size.should == 1
|
||||
end
|
||||
|
||||
it 'does not save a content if required parameters are missing' do
|
||||
post 'create', default_post_params(:content => { :name => '' })
|
||||
|
||||
response.should redirect_to('http://www.locomotivecms.com/failure')
|
||||
|
||||
@site.reload.content_types.first.contents.size.should == 0
|
||||
end
|
||||
|
||||
describe 'XSS vulnerability' do
|
||||
|
||||
it 'sanitizes the params (simple example)' do
|
||||
post 'create', default_post_params(:content => { :name => %(Hacking <script type="text/javascript">alert("You have been hacked")</script>) })
|
||||
|
||||
content = @site.reload.content_types.first.contents.first
|
||||
|
||||
content.name.should == "Hacking alert(\"You have been hacked\")"
|
||||
end
|
||||
|
||||
it 'sanitizes the params (more complex example)' do
|
||||
post 'create', default_post_params(:content => { :name => %(<img src=javascript:alert('Hello')><table background="javascript:alert('Hello')">Hacked) })
|
||||
|
||||
content = @site.reload.content_types.first.contents.first
|
||||
|
||||
content.name.should == "Hacked"
|
||||
end
|
||||
|
||||
it 'does not sanitize non string params' do
|
||||
lambda {
|
||||
post 'create', default_post_params(:content => {
|
||||
:active => true,
|
||||
:file => ActionDispatch::Http::UploadedFile.new(:tempfile => FixturedAsset.open('5k.png'), :filename => '5k.png', :content_type => 'image/png')
|
||||
})
|
||||
}.should_not raise_exception
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def default_post_params(options = {})
|
||||
{
|
||||
:slug => 'projects',
|
||||
:content => { :name => 'LocomotiveCMS', :description => 'Lorem ipsum' }.merge(options.delete(:content) || {}),
|
||||
:success_callback => 'http://www.locomotivecms.com/success',
|
||||
:error_callback => 'http://www.locomotivecms.com/failure'
|
||||
}.merge(options)
|
||||
end
|
||||
|
||||
end
|
@ -1,136 +1,141 @@
|
||||
## Site ##
|
||||
Factory.define :site do |s|
|
||||
s.name 'Acme Website'
|
||||
s.subdomain 'acme'
|
||||
s.created_at Time.now
|
||||
end
|
||||
FactoryGirl.define do
|
||||
|
||||
Factory.define "test site", :parent => :site do |s|
|
||||
s.name 'Locomotive test website'
|
||||
s.subdomain 'test'
|
||||
s.after_build do |site_test|
|
||||
## Site ##
|
||||
factory :site do
|
||||
name 'Acme Website'
|
||||
subdomain 'acme'
|
||||
created_at Time.now
|
||||
|
||||
factory "test site" do
|
||||
name 'Locomotive test website'
|
||||
subdomain 'test'
|
||||
|
||||
after_build do |site_test|
|
||||
site_test.memberships.build :account => Account.where(:name => "Admin").first || Factory("admin user"), :role => 'admin'
|
||||
end
|
||||
end
|
||||
|
||||
Factory.define "another site", :parent => "test site" do |s|
|
||||
s.name "Locomotive test website #2"
|
||||
s.subdomain "test2"
|
||||
end
|
||||
factory "another site" do
|
||||
name "Locomotive test website #2"
|
||||
subdomain "test2"
|
||||
end
|
||||
|
||||
Factory.define "existing site", :parent => "site" do |s|
|
||||
s.name "Locomotive site with existing models"
|
||||
s.subdomain "models"
|
||||
s.after_build do |site_with_models|
|
||||
end
|
||||
|
||||
factory "existing site" do
|
||||
name "Locomotive site with existing models"
|
||||
subdomain "models"
|
||||
after_build do |site_with_models|
|
||||
site_with_models.content_types.build(
|
||||
:slug => 'projects',
|
||||
:name => 'Existing name',
|
||||
:description => 'Existing description',
|
||||
:order_by => 'created_at')
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
factory "valid site" do
|
||||
# after_build { |valid_site| valid_site.stubs(:valid?).returns(true) }
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
# Accounts ##
|
||||
factory :account do
|
||||
name 'Bart Simpson'
|
||||
email 'bart@simpson.net'
|
||||
password 'easyone'
|
||||
password_confirmation 'easyone'
|
||||
locale 'en'
|
||||
|
||||
factory "admin user" do
|
||||
name "Admin"
|
||||
email "admin@locomotiveapp.org"
|
||||
end
|
||||
|
||||
factory "frenchy user" do
|
||||
name "Jean Claude"
|
||||
email "jean@frenchy.fr"
|
||||
locale 'fr'
|
||||
end
|
||||
|
||||
factory "brazillian user" do
|
||||
name "Jose Carlos"
|
||||
email "jose@carlos.com.br"
|
||||
locale 'pt-BR'
|
||||
end
|
||||
|
||||
factory "italian user" do
|
||||
name "Paolo Rossi"
|
||||
email "paolo@paolo-rossi.it"
|
||||
locale 'it'
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
## Memberships ##
|
||||
factory :membership do
|
||||
role 'admin'
|
||||
account { Account.where(:name => "Bart Simpson").first || Factory('admin user') }
|
||||
|
||||
factory :admin do
|
||||
role 'admin'
|
||||
account { Factory('admin user', :locale => 'en') }
|
||||
end
|
||||
|
||||
factory :designer do
|
||||
role 'designer'
|
||||
account { Factory('frenchy user', :locale => 'en') }
|
||||
end
|
||||
|
||||
factory :author do
|
||||
role 'author'
|
||||
account { Factory('brazillian user', :locale => 'en') }
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
## Pages ##
|
||||
factory :page do
|
||||
title 'Home page'
|
||||
slug 'index'
|
||||
published true
|
||||
site { Site.where(:subdomain => "acme").first || Factory(:site) }
|
||||
|
||||
factory :sub_page do
|
||||
title 'Subpage'
|
||||
slug 'subpage'
|
||||
published true
|
||||
site { Site.where(:subdomain => "acme").first || Factory(:site) }
|
||||
parent { Page.where(:slug => "index").first || Factory(:page) }
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
## Snippets ##
|
||||
factory :snippet do
|
||||
name 'My website title'
|
||||
slug 'header'
|
||||
template %{<title>Acme</title>}
|
||||
site { Site.where(:subdomain => "acme").first || Factory(:site) }
|
||||
end
|
||||
|
||||
|
||||
## Assets ##
|
||||
factory :asset do
|
||||
site { Site.where(:subdomain => "acme").first || Factory(:site) }
|
||||
end
|
||||
|
||||
|
||||
## Theme assets ##
|
||||
factory :theme_asset do
|
||||
site { Site.where(:subdomain => "acme").first || Factory(:site) }
|
||||
end
|
||||
|
||||
## Content types ##
|
||||
factory :content_type do
|
||||
name 'My project'
|
||||
site { Site.where(:subdomain => "acme").first || Factory(:site) }
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
Factory.define "valid site", :parent => "site" do |s|
|
||||
# s.after_build { |valid_site| valid_site.stubs(:valid?).returns(true) }
|
||||
end
|
||||
|
||||
|
||||
# Accounts ##
|
||||
Factory.define :account do |a|
|
||||
a.name 'Bart Simpson'
|
||||
a.email 'bart@simpson.net'
|
||||
a.password 'easyone'
|
||||
a.password_confirmation 'easyone'
|
||||
a.locale 'en'
|
||||
end
|
||||
|
||||
Factory.define "admin user", :parent => :account do |a|
|
||||
a.name "Admin"
|
||||
a.email "admin@locomotiveapp.org"
|
||||
end
|
||||
|
||||
Factory.define "frenchy user", :parent => :account do |a|
|
||||
a.name "Jean Claude"
|
||||
a.email "jean@frenchy.fr"
|
||||
a.locale 'fr'
|
||||
end
|
||||
|
||||
Factory.define "brazillian user", :parent => :account do |a|
|
||||
a.name "Jose Carlos"
|
||||
a.email "jose@carlos.com.br"
|
||||
a.locale 'pt-BR'
|
||||
end
|
||||
|
||||
Factory.define "italian user", :parent => :account do |a|
|
||||
a.name "Paolo Rossi"
|
||||
a.email "paolo@paolo-rossi.it"
|
||||
a.locale 'it'
|
||||
end
|
||||
|
||||
|
||||
## Memberships ##
|
||||
Factory.define :membership do |m|
|
||||
m.role 'admin'
|
||||
m.account { Account.where(:name => "Bart Simpson").first || Factory('admin user') }
|
||||
end
|
||||
|
||||
Factory.define :admin, :parent => :membership do |m|
|
||||
m.role 'admin'
|
||||
m.account { Factory('admin user', :locale => 'en') }
|
||||
end
|
||||
|
||||
Factory.define :designer, :parent => :membership do |m|
|
||||
m.role 'designer'
|
||||
m.account { Factory('frenchy user', :locale => 'en') }
|
||||
end
|
||||
|
||||
Factory.define :author, :parent => :membership do |m|
|
||||
m.role 'author'
|
||||
m.account { Factory('brazillian user', :locale => 'en') }
|
||||
end
|
||||
|
||||
|
||||
## Pages ##
|
||||
Factory.define :page do |p|
|
||||
p.title 'Home page'
|
||||
p.slug 'index'
|
||||
p.published true
|
||||
p.site { Site.where(:subdomain => "acme").first || Factory(:site) }
|
||||
end
|
||||
|
||||
Factory.define :sub_page, :parent => :page do |p|
|
||||
p.title 'Subpage'
|
||||
p.slug 'subpage'
|
||||
p.published true
|
||||
p.site { Site.where(:subdomain => "acme").first || Factory(:site) }
|
||||
p.parent { Page.where(:slug => "index").first || Factory(:page) }
|
||||
end
|
||||
|
||||
|
||||
## Snippets ##
|
||||
Factory.define :snippet do |s|
|
||||
s.name 'My website title'
|
||||
s.slug 'header'
|
||||
s.template %{<title>Acme</title>}
|
||||
s.site { Site.where(:subdomain => "acme").first || Factory(:site) }
|
||||
end
|
||||
|
||||
|
||||
## Assets ##
|
||||
Factory.define :asset do |a|
|
||||
a.site { Site.where(:subdomain => "acme").first || Factory(:site) }
|
||||
end
|
||||
|
||||
|
||||
## Theme assets ##
|
||||
Factory.define :theme_asset do |a|
|
||||
a.site { Site.where(:subdomain => "acme").first || Factory(:site) }
|
||||
end
|
||||
|
||||
|
||||
## Content types ##
|
||||
Factory.define :content_type do |t|
|
||||
t.name 'My project'
|
||||
t.site { Site.where(:subdomain => "acme").first || Factory(:site) }
|
||||
end
|
||||
|
||||
|
@ -66,7 +66,7 @@ describe 'Bushido support' do
|
||||
|
||||
before(:each) do
|
||||
configure_locomotive_with_bushido
|
||||
@site = Factory.build('test site')
|
||||
@site = FactoryGirl.build('test site')
|
||||
@account = @site.memberships.first.account
|
||||
Account.stubs(:first).returns(@account)
|
||||
end
|
||||
@ -83,7 +83,7 @@ describe 'Bushido support' do
|
||||
|
||||
before(:each) do
|
||||
configure_locomotive_with_bushido
|
||||
@site = Factory.build('valid site')
|
||||
@site = FactoryGirl.build('valid site')
|
||||
end
|
||||
|
||||
it 'calls add_bushido_domains after saving a site' do
|
||||
|
@ -5,7 +5,7 @@ describe Locomotive::Export do
|
||||
context '#content_type' do
|
||||
|
||||
before(:each) do
|
||||
site = Factory.build('another site')
|
||||
site = FactoryGirl.build('another site')
|
||||
Site.stubs(:find).returns(site)
|
||||
project_type = build_project_type(site)
|
||||
project_type.contents.build(:title => 'Project #1', :description => 'Lorem ipsum', :active => true)
|
||||
@ -39,7 +39,7 @@ describe Locomotive::Export do
|
||||
end
|
||||
|
||||
def build_project_type(site)
|
||||
Factory.build(:content_type, :site => site, :highlighted_field_name => 'custom_field_1').tap do |content_type|
|
||||
FactoryGirl.build(:content_type, :site => site, :highlighted_field_name => 'custom_field_1').tap do |content_type|
|
||||
content_type.content_custom_fields.build :label => 'Title', :_alias => 'title', :kind => 'string'
|
||||
content_type.content_custom_fields.build :label => 'My Description', :_alias => 'description', :kind => 'text'
|
||||
content_type.content_custom_fields.build :label => 'Active', :kind => 'boolean'
|
||||
@ -49,7 +49,7 @@ describe Locomotive::Export do
|
||||
def build_team_type(site, project_type)
|
||||
Object.send(:remove_const, 'TestProject') rescue nil
|
||||
klass = Object.const_set('TestProject', Class.new { def self.embedded?; false; end })
|
||||
content_type = Factory.build(:content_type, :site => site, :name => 'team', :highlighted_field_name => 'custom_field_1')
|
||||
content_type = FactoryGirl.build(:content_type, :site => site, :name => 'team', :highlighted_field_name => 'custom_field_1')
|
||||
content_type.content_custom_fields.build :label => 'Name', :_alias => 'name', :kind => 'string'
|
||||
content_type.content_custom_fields.build :label => 'Projects', :kind => 'has_many', :_alias => 'projects', :target => 'TestProject'
|
||||
content_type.content_custom_fields.build :label => 'Bio', :_alias => 'bio', :kind => 'text'
|
||||
@ -62,7 +62,7 @@ describe Locomotive::Export do
|
||||
context '#zipfile' do
|
||||
|
||||
before(:all) do
|
||||
@site = Factory('another site')
|
||||
@site = FactoryGirl.create('another site')
|
||||
|
||||
# first import a brand new site
|
||||
self.import_it
|
||||
|
@ -95,9 +95,7 @@ describe 'Heroku support' do
|
||||
|
||||
before(:each) do
|
||||
configure_locomotive_with_heroku
|
||||
# (@site = Factory.stub(:site)).stubs(:valid?).returns(true)
|
||||
@site = Factory.build('valid site')
|
||||
# (@site = Site.new(:name => 'foobar', :subdomain => 'acme')).stubs(:valid?).returns(true)
|
||||
@site = FactoryGirl.build('valid site')
|
||||
end
|
||||
|
||||
it 'calls add_heroku_domains after saving a site' do
|
||||
|
@ -2,15 +2,10 @@ require 'spec_helper'
|
||||
|
||||
describe Locomotive::Import::Job do
|
||||
|
||||
# before(:all) do
|
||||
# # Site.destroy_all
|
||||
# # Locomotive.configure_for_test(true)
|
||||
# end
|
||||
|
||||
context 'when successful' do
|
||||
|
||||
before(:all) do
|
||||
@site = Factory(:site)
|
||||
@site = FactoryGirl.create(:site)
|
||||
|
||||
job = Locomotive::Import::Job.new(FixturedTheme.duplicate_and_open('default.zip'), @site, { :samples => true, :reset => true })
|
||||
job.perform
|
||||
@ -115,7 +110,7 @@ describe Locomotive::Import::Job do
|
||||
|
||||
context 'with an existing site' do
|
||||
before(:all) do
|
||||
@site = Factory("existing site")
|
||||
@site = FactoryGirl.create('existing site')
|
||||
|
||||
job = Locomotive::Import::Job.new(FixturedTheme.duplicate_and_open('default.zip'), @site, { :samples => true, :reset => false })
|
||||
job.perform
|
||||
|
@ -3,8 +3,8 @@ require 'spec_helper'
|
||||
describe Locomotive::Liquid::Drops::Content do
|
||||
|
||||
before(:each) do
|
||||
@site = Factory.build(:site)
|
||||
content_type = Factory.build(:content_type)
|
||||
@site = FactoryGirl.build(:site)
|
||||
content_type = FactoryGirl.build(:content_type)
|
||||
content_type.content_custom_fields.build :label => 'anything', :kind => 'string'
|
||||
content_type.content_custom_fields.build :label => 'published_at', :kind => 'date'
|
||||
@content = content_type.contents.build({
|
||||
|
@ -3,8 +3,11 @@ require 'spec_helper'
|
||||
describe Locomotive::Liquid::Drops::Contents do
|
||||
|
||||
before(:each) do
|
||||
@site = Factory.build(:site)
|
||||
@content_type = Factory.build(:content_type, :site => @site, :slug => 'projects')
|
||||
# Reload the file (needed for spork)
|
||||
load File.join(Rails.root, 'lib', 'locomotive', 'liquid', 'drops', 'contents.rb')
|
||||
|
||||
@site = FactoryGirl.build(:site)
|
||||
@content_type = FactoryGirl.build(:content_type, :site => @site, :slug => 'projects')
|
||||
end
|
||||
|
||||
it 'retrieves a content type from a slug' do
|
||||
@ -22,6 +25,26 @@ describe Locomotive::Liquid::Drops::Contents do
|
||||
|
||||
end
|
||||
|
||||
describe Locomotive::Liquid::Drops::ProxyCollection do
|
||||
|
||||
before(:each) do
|
||||
populate_content_type
|
||||
@proxy_collection = Locomotive::Liquid::Drops::ProxyCollection.new(@content_type)
|
||||
@proxy_collection.context = {}
|
||||
end
|
||||
|
||||
it 'provides its size like an Array' do
|
||||
@proxy_collection.size.should == @proxy_collection.length
|
||||
end
|
||||
|
||||
it 'can be enumerated using each_with_index' do
|
||||
@proxy_collection.each_with_index do |item, index|
|
||||
item._slug.should == "item#{index + 1}"
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def render_template(template = '', assigns = {})
|
||||
assigns = {
|
||||
'contents' => Locomotive::Liquid::Drops::Contents.new
|
||||
@ -30,4 +53,11 @@ describe Locomotive::Liquid::Drops::Contents do
|
||||
Liquid::Template.parse(template).render(::Liquid::Context.new({}, assigns, { :site => @site }))
|
||||
end
|
||||
|
||||
def populate_content_type
|
||||
@content_type.order_by = :_slug
|
||||
@content_type.contents.build(:_slug => 'item1')
|
||||
@content_type.contents.build(:_slug => 'item2')
|
||||
@content_type.contents.build(:_slug => 'item3')
|
||||
end
|
||||
|
||||
end
|
||||
|
@ -3,8 +3,8 @@ require 'spec_helper'
|
||||
describe Locomotive::Liquid::Drops::Page do
|
||||
|
||||
before(:each) do
|
||||
site = Factory.build(:site)
|
||||
@home = Factory.build(:page, :site => site, :meta_keywords => 'Libidinous, Angsty', :meta_description => "Quite the combination.")
|
||||
site = FactoryGirl.build(:site)
|
||||
@home = FactoryGirl.build(:page, :site => site, :meta_keywords => 'Libidinous, Angsty', :meta_description => "Quite the combination.")
|
||||
end
|
||||
|
||||
context '#rendering tree' do
|
||||
@ -43,7 +43,7 @@ describe Locomotive::Liquid::Drops::Page do
|
||||
|
||||
context '#parent' do
|
||||
before(:each) do
|
||||
@sub_page = Factory.build(:sub_page, :meta_keywords => 'Sub Libidinous, Angsty', :meta_description => "Sub Quite the combination.")
|
||||
@sub_page = FactoryGirl.build(:sub_page, :meta_keywords => 'Sub Libidinous, Angsty', :meta_description => "Sub Quite the combination.")
|
||||
end
|
||||
|
||||
it 'renders title of parent page' do
|
||||
@ -55,7 +55,7 @@ describe Locomotive::Liquid::Drops::Page do
|
||||
|
||||
context '#breadcrumbs' do
|
||||
before(:each) do
|
||||
@sub_page = Factory.build(:sub_page, :meta_keywords => 'Sub Libidinous, Angsty', :meta_description => "Sub Quite the combination.")
|
||||
@sub_page = FactoryGirl.build(:sub_page, :meta_keywords => 'Sub Libidinous, Angsty', :meta_description => "Sub Quite the combination.")
|
||||
end
|
||||
|
||||
it 'renders breadcrumbs of current page' do
|
||||
@ -71,7 +71,7 @@ describe Locomotive::Liquid::Drops::Page do
|
||||
end
|
||||
|
||||
it 'renders the content instance highlighted field instead for a templatized page' do
|
||||
templatized = Factory.build(:page, :title => 'Lorem ipsum template', :templatized => true)
|
||||
templatized = FactoryGirl.build(:page, :title => 'Lorem ipsum template', :templatized => true)
|
||||
|
||||
content_instance = Locomotive::Liquid::Drops::Content.new(mock('content_instance', :highlighted_field_value => 'Locomotive rocks !'))
|
||||
|
||||
|
@ -3,9 +3,9 @@ require 'spec_helper'
|
||||
describe Locomotive::Liquid::Drops::Site do
|
||||
|
||||
before(:each) do
|
||||
@site = Factory.build(:site)
|
||||
page_1 = Factory.build(:page, :site => @site)
|
||||
page_2 = Factory.build(:page, :site => @site, :title => 'About us', :slug => 'about_us')
|
||||
@site = FactoryGirl.build(:site)
|
||||
page_1 = FactoryGirl.build(:page, :site => @site)
|
||||
page_2 = FactoryGirl.build(:page, :site => @site, :title => 'About us', :slug => 'about_us')
|
||||
@site.stubs(:pages).returns([page_1, page_2])
|
||||
end
|
||||
|
||||
|
@ -233,7 +233,7 @@ describe Locomotive::Liquid::Filters::Html do
|
||||
klass = Class.new
|
||||
klass.class_eval do
|
||||
def registers
|
||||
{ :site => Factory.build(:site, :id => fake_bson_id(42)) }
|
||||
{ :site => FactoryGirl.build(:site, :id => fake_bson_id(42)) }
|
||||
end
|
||||
|
||||
def fake_bson_id(id)
|
||||
|
@ -3,10 +3,10 @@ require 'spec_helper'
|
||||
describe Locomotive::Liquid::Filters::Resize do
|
||||
|
||||
before :each do
|
||||
@site = Factory.create(:site)
|
||||
@theme_asset = Factory.create(:theme_asset, :source => FixturedAsset.open('5k.png'), :site => @site)
|
||||
@site = FactoryGirl.create(:site)
|
||||
@theme_asset = FactoryGirl.create(:theme_asset, :source => FixturedAsset.open('5k.png'), :site => @site)
|
||||
@theme_asset_path = "/sites/#{@theme_asset.site_id}/theme/images/5k.png"
|
||||
@asset = Factory.create(:asset, :source => FixturedAsset.open('5k.png'), :site => @site)
|
||||
@asset = FactoryGirl.create(:asset, :source => FixturedAsset.open('5k.png'), :site => @site)
|
||||
@asset_url = @asset.source.url
|
||||
@asset_path = "/sites/#{@asset.site_id}/assets/#{@asset.id}/5k.png"
|
||||
@context = Liquid::Context.new( { }, { 'asset_url' => @asset_url, 'theme_asset' => @theme_asset.to_liquid }, { :site => @site })
|
||||
|
@ -27,8 +27,8 @@ describe Locomotive::Liquid::Tags::Editable::Content do
|
||||
context 'inheriting from a parent' do
|
||||
|
||||
before :each do
|
||||
@parent = Factory.build(:page)
|
||||
@child = Factory.build(:page)
|
||||
@parent = FactoryGirl.build(:page)
|
||||
@child = FactoryGirl.build(:page)
|
||||
|
||||
@child.stubs(:parent).returns(@parent)
|
||||
end
|
||||
@ -58,7 +58,7 @@ describe Locomotive::Liquid::Tags::Editable::Content do
|
||||
context 'reading from the same page' do
|
||||
|
||||
before :each do
|
||||
@page = Factory.build(:page)
|
||||
@page = FactoryGirl.build(:page)
|
||||
end
|
||||
|
||||
it 'should return the previously defined field' do
|
||||
|
@ -3,7 +3,7 @@ require 'spec_helper'
|
||||
describe Locomotive::Liquid::Tags::Nav do
|
||||
|
||||
before(:each) do
|
||||
@home = Factory.build(:page)
|
||||
@home = FactoryGirl.build(:page)
|
||||
home_children = [
|
||||
Page.new(:title => 'Child #1', :fullpath => 'child_1', :slug => 'child_1', :published => true),
|
||||
Page.new(:title => 'Child #2', :fullpath => 'child_2', :slug => 'child_2', :published => true)
|
||||
@ -24,7 +24,7 @@ describe Locomotive::Liquid::Tags::Nav do
|
||||
pages = [@home]
|
||||
pages.stubs(:root).returns(pages)
|
||||
pages.stubs(:minimal_attributes).returns(pages) # iso
|
||||
@site = Factory.build(:site)
|
||||
@site = FactoryGirl.build(:site)
|
||||
@site.stubs(:pages).returns(pages)
|
||||
end
|
||||
|
||||
|
@ -54,7 +54,7 @@ describe Locomotive::Liquid::Tags::Paginate do
|
||||
'projects' => options.has_key?(:collection) ? options[:collection] : PaginatedCollection.new(['Ruby on Rails', 'jQuery', 'mongodb', 'Liquid', 'sqlite3']),
|
||||
'current_page' => options[:page] || 1
|
||||
}, {
|
||||
:page => Factory.build(:page)
|
||||
:page => FactoryGirl.build(:page)
|
||||
}, true)
|
||||
end
|
||||
|
||||
|
@ -3,7 +3,7 @@ require 'spec_helper'
|
||||
describe Locomotive::Liquid::Tags::SEO do
|
||||
|
||||
let(:site) do
|
||||
Factory.build(:site, :seo_title => 'Site title (SEO)', :meta_description => 'A short site description', :meta_keywords => 'test only cat dog')
|
||||
FactoryGirl.build(:site, :seo_title => 'Site title (SEO)', :meta_description => 'A short site description', :meta_keywords => 'test only cat dog')
|
||||
end
|
||||
|
||||
describe 'rendering' do
|
||||
@ -80,7 +80,7 @@ describe Locomotive::Liquid::Tags::SEO do
|
||||
context "when content instance" do
|
||||
|
||||
let(:content_type) do
|
||||
Factory.build(:content_type, :site => site).tap do |ct|
|
||||
FactoryGirl.build(:content_type, :site => site).tap do |ct|
|
||||
ct.content_custom_fields.build :label => 'anything', :kind => 'String'
|
||||
end
|
||||
end
|
||||
|
@ -6,10 +6,10 @@ describe 'Locomotive rendering system' do
|
||||
before(:each) do
|
||||
@controller = Locomotive::TestController.new
|
||||
Site.any_instance.stubs(:create_default_pages!).returns(true)
|
||||
@site = Factory.build(:site)
|
||||
@site = FactoryGirl.build(:site)
|
||||
Site.stubs(:find).returns(@site)
|
||||
@controller.current_site = @site
|
||||
@page = Factory.build(:page, :site => nil, :published => true)
|
||||
@page = FactoryGirl.build(:page, :site => nil, :published => true)
|
||||
end
|
||||
|
||||
context '#liquid_context' do
|
||||
@ -125,7 +125,7 @@ describe 'Locomotive rendering system' do
|
||||
context 'templatized page' do
|
||||
|
||||
before(:each) do
|
||||
@content_type = Factory.build(:content_type, :site => nil)
|
||||
@content_type = FactoryGirl.build(:content_type, :site => nil)
|
||||
@content = @content_type.contents.build(:_visible => true)
|
||||
@page.templatized = true
|
||||
@page.content_type = @content_type
|
||||
|
@ -26,7 +26,7 @@ describe Locomotive::Routing::SiteDispatcher do
|
||||
|
||||
before :each do
|
||||
@request = Object.new
|
||||
@site = Factory.build(:site)
|
||||
@site = FactoryGirl.build(:site)
|
||||
|
||||
@controller.stubs(:request).returns(@request)
|
||||
@request.stubs(:host).returns('host')
|
||||
@ -48,7 +48,7 @@ describe Locomotive::Routing::SiteDispatcher do
|
||||
describe '#current_site' do
|
||||
|
||||
before :each do
|
||||
@site = Factory.build(:site)
|
||||
@site = FactoryGirl.build(:site)
|
||||
end
|
||||
|
||||
it 'returns the current site instance if available' do
|
||||
@ -157,8 +157,8 @@ describe Locomotive::Routing::SiteDispatcher do
|
||||
describe '#validate_site_membership' do
|
||||
|
||||
before :each do
|
||||
@account = Factory.build(:account)
|
||||
@site = Factory.build(:site)
|
||||
@account = FactoryGirl.build(:account)
|
||||
@site = FactoryGirl.build(:site)
|
||||
@request = ActionDispatch::Request.new({})
|
||||
|
||||
@controller.instance_variable_set('@_response', ActionDispatch::Response.new)
|
||||
|
@ -3,12 +3,12 @@ require 'spec_helper'
|
||||
describe Ability do
|
||||
|
||||
before :each do
|
||||
@site = Factory(:site)
|
||||
@account = Factory(:account)
|
||||
@site = FactoryGirl.create(:site)
|
||||
@account = FactoryGirl.create(:account)
|
||||
|
||||
@admin = Factory(:membership, :account => Factory.stub(:account), :site => Factory.stub(:site))
|
||||
@designer = Factory(:membership, :account => Factory.stub(:account), :site => @site, :role => %(designer))
|
||||
@author = Factory(:membership, :account => Factory.stub(:account), :site => @site, :role => %(author))
|
||||
@admin = FactoryGirl.create(:membership, :account => FactoryGirl.build(:account), :site => FactoryGirl.build(:site))
|
||||
@designer = FactoryGirl.create(:membership, :account => FactoryGirl.build(:account), :site => @site, :role => %(designer))
|
||||
@author = FactoryGirl.create(:membership, :account => FactoryGirl.build(:account), :site => @site, :role => %(author))
|
||||
end
|
||||
|
||||
context 'pages' do
|
||||
|
@ -3,14 +3,14 @@ require 'spec_helper'
|
||||
describe Account do
|
||||
|
||||
it 'should have a valid factory' do
|
||||
Factory.build(:account).should be_valid
|
||||
FactoryGirl.build(:account).should be_valid
|
||||
end
|
||||
|
||||
## Validations ##
|
||||
|
||||
%w{name email password}.each do |attr|
|
||||
it "should validate presence of #{attr}" do
|
||||
account = Factory.build(:account, attr.to_sym => nil)
|
||||
account = FactoryGirl.build(:account, attr.to_sym => nil)
|
||||
account.should_not be_valid
|
||||
account.errors[attr.to_sym].should include("can't be blank")
|
||||
end
|
||||
@ -22,26 +22,26 @@ describe Account do
|
||||
end
|
||||
|
||||
it "should validate uniqueness of email" do
|
||||
Factory(:account)
|
||||
(account = Factory.build(:account)).should_not be_valid
|
||||
FactoryGirl.create(:account)
|
||||
(account = FactoryGirl.build(:account)).should_not be_valid
|
||||
account.errors[:email].should == ["is already taken"]
|
||||
end
|
||||
|
||||
## Associations ##
|
||||
|
||||
it 'should own many sites' do
|
||||
account = Factory(:account)
|
||||
site_1 = Factory(:site, :memberships => [Membership.new(:account => account)])
|
||||
site_2 = Factory(:site, :subdomain => 'foo', :memberships => [Membership.new(:account => account)])
|
||||
account = FactoryGirl.create(:account)
|
||||
site_1 = FactoryGirl.create(:site, :memberships => [Membership.new(:account => account)])
|
||||
site_2 = FactoryGirl.create(:site, :subdomain => 'foo', :memberships => [Membership.new(:account => account)])
|
||||
account.reload.sites.to_a.should == [site_1, site_2]
|
||||
end
|
||||
|
||||
describe 'deleting' do
|
||||
|
||||
before(:each) do
|
||||
@account = Factory.build(:account)
|
||||
@site_1 = Factory.build(:site, :subdomain => 'foo', :memberships => [Factory.build(:membership, :account => @account)])
|
||||
@site_2 = Factory.build(:site, :subdomain => 'bar', :memberships => [Factory.build(:membership, :account => @account)])
|
||||
@account = FactoryGirl.build(:account)
|
||||
@site_1 = FactoryGirl.build(:site, :subdomain => 'foo', :memberships => [FactoryGirl.build(:membership, :account => @account)])
|
||||
@site_2 = FactoryGirl.build(:site, :subdomain => 'bar', :memberships => [FactoryGirl.build(:membership, :account => @account)])
|
||||
@account.stubs(:sites).returns([@site_1, @site_2])
|
||||
Site.any_instance.stubs(:save).returns(true)
|
||||
end
|
||||
@ -65,7 +65,7 @@ describe Account do
|
||||
describe 'cross domain authentication' do
|
||||
|
||||
before(:each) do
|
||||
@account = Factory.build(:account)
|
||||
@account = FactoryGirl.build(:account)
|
||||
@account.stubs(:save).returns(true)
|
||||
end
|
||||
|
||||
|
@ -8,7 +8,7 @@ describe Asset do
|
||||
|
||||
before(:each) do
|
||||
Asset.any_instance.stubs(:site_id).returns('test')
|
||||
@asset = Factory.build(:asset)
|
||||
@asset = FactoryGirl.build(:asset)
|
||||
end
|
||||
|
||||
it 'should process picture' do
|
||||
@ -28,7 +28,7 @@ describe Asset do
|
||||
describe 'vignette' do
|
||||
|
||||
before(:each) do
|
||||
@asset = Factory.build(:asset, :source => FixturedAsset.open('5k.png'))
|
||||
@asset = FactoryGirl.build(:asset, :source => FixturedAsset.open('5k.png'))
|
||||
end
|
||||
|
||||
it 'does not resize image smaller than 50x50' do
|
||||
|
@ -6,7 +6,7 @@ describe ContentInstance do
|
||||
|
||||
before(:each) do
|
||||
Site.any_instance.stubs(:create_default_pages!).returns(true)
|
||||
@content_type = Factory.build(:content_type)
|
||||
@content_type = FactoryGirl.build(:content_type)
|
||||
@content_type.content_custom_fields.build :label => 'Title', :kind => 'String'
|
||||
@content_type.content_custom_fields.build :label => 'Description', :kind => 'Text'
|
||||
@content_type.content_custom_fields.build :label => 'Visible ?', :kind => 'Text', :_alias => 'visible'
|
||||
@ -111,8 +111,8 @@ describe ContentInstance do
|
||||
describe '#api' do
|
||||
|
||||
before(:each) do
|
||||
@account_1 = Factory.build('admin user', :id => fake_bson_id('1'))
|
||||
@account_2 = Factory.build('frenchy user', :id => fake_bson_id('2'))
|
||||
@account_1 = FactoryGirl.build('admin user', :id => fake_bson_id('1'))
|
||||
@account_2 = FactoryGirl.build('frenchy user', :id => fake_bson_id('2'))
|
||||
|
||||
@content_type.api_enabled = true
|
||||
@content_type.api_accounts = ['', @account_1.id, @account_2.id]
|
||||
|
@ -9,7 +9,7 @@ describe ContentType do
|
||||
context 'when validating' do
|
||||
|
||||
it 'should have a valid factory' do
|
||||
content_type = Factory.build(:content_type)
|
||||
content_type = FactoryGirl.build(:content_type)
|
||||
content_type.content_custom_fields.build :label => 'anything', :kind => 'String'
|
||||
content_type.should be_valid
|
||||
end
|
||||
@ -18,35 +18,35 @@ describe ContentType do
|
||||
|
||||
%w{site name}.each do |field|
|
||||
it "requires the presence of #{field}" do
|
||||
content_type = Factory.build(:content_type, field.to_sym => nil)
|
||||
content_type = FactoryGirl.build(:content_type, field.to_sym => nil)
|
||||
content_type.should_not be_valid
|
||||
content_type.errors[field.to_sym].should == ["can't be blank"]
|
||||
end
|
||||
end
|
||||
|
||||
it 'requires the presence of slug' do
|
||||
content_type = Factory.build(:content_type, :name => nil, :slug => nil)
|
||||
content_type = FactoryGirl.build(:content_type, :name => nil, :slug => nil)
|
||||
content_type.should_not be_valid
|
||||
content_type.errors[:slug].should == ["can't be blank"]
|
||||
end
|
||||
|
||||
it 'is not valid if slug is not unique' do
|
||||
content_type = Factory.build(:content_type)
|
||||
content_type = FactoryGirl.build(:content_type)
|
||||
content_type.content_custom_fields.build :label => 'anything', :kind => 'String'
|
||||
content_type.save
|
||||
(content_type = Factory.build(:content_type, :site => content_type.site)).should_not be_valid
|
||||
(content_type = FactoryGirl.build(:content_type, :site => content_type.site)).should_not be_valid
|
||||
content_type.errors[:slug].should == ["is already taken"]
|
||||
end
|
||||
|
||||
it 'is not valid if there is not at least one field' do
|
||||
content_type = Factory.build(:content_type)
|
||||
content_type = FactoryGirl.build(:content_type)
|
||||
content_type.should_not be_valid
|
||||
content_type.errors[:content_custom_fields].should == ["is too small (minimum element number is 1)"]
|
||||
end
|
||||
|
||||
%w(created_at updated_at).each do |_alias|
|
||||
it "does not allow #{_alias} as alias" do
|
||||
content_type = Factory.build(:content_type)
|
||||
content_type = FactoryGirl.build(:content_type)
|
||||
field = content_type.content_custom_fields.build :label => 'anything', :kind => 'String', :_alias => _alias
|
||||
field.valid?.should be_false
|
||||
field.errors[:_alias].should == ['is reserved']
|
||||
@ -58,7 +58,7 @@ describe ContentType do
|
||||
context '#ordered_contents' do
|
||||
|
||||
before(:each) do
|
||||
@content_type = Factory.build(:content_type, :order_by => 'created_at')
|
||||
@content_type = FactoryGirl.build(:content_type, :order_by => 'created_at')
|
||||
@content_1 = stub('content_1', :name => 'Did', :_position_in_list => 2)
|
||||
@content_2 = stub('content_2', :name => 'Sacha', :_position_in_list => 1)
|
||||
@content_type.stubs(:contents).returns([@content_1, @content_2])
|
||||
@ -95,9 +95,9 @@ describe ContentType do
|
||||
describe 'custom fields' do
|
||||
|
||||
before(:each) do
|
||||
site = Factory.build(:site)
|
||||
site = FactoryGirl.build(:site)
|
||||
Site.stubs(:find).returns(site)
|
||||
@content_type = Factory.build(:content_type, :site => site, :highlighted_field_name => 'custom_field_1')
|
||||
@content_type = FactoryGirl.build(:content_type, :site => site, :highlighted_field_name => 'custom_field_1')
|
||||
@content_type.content_custom_fields.build :label => 'My Description', :_alias => 'description', :kind => 'text'
|
||||
@content_type.content_custom_fields.build :label => 'Active', :kind => 'boolean'
|
||||
# ContentType.logger = Logger.new($stdout)
|
||||
|
@ -3,14 +3,14 @@ require 'spec_helper'
|
||||
describe EditableElement do
|
||||
|
||||
before(:each) do
|
||||
@site = Factory(:site)
|
||||
@site = FactoryGirl.create(:site)
|
||||
@home = @site.pages.root.first
|
||||
@home.update_attributes :raw_template => "{% block body %}{% editable_short_text 'body' %}Lorem ipsum{% endeditable_short_text %}{% endblock %}"
|
||||
|
||||
@sub_page_1 = Factory(:page, :slug => 'sub_page_1', :parent => @home, :raw_template => "{% extends 'parent' %}")
|
||||
@sub_page_2 = Factory(:page, :slug => 'sub_page_2', :parent => @home, :raw_template => "{% extends 'parent' %}")
|
||||
@sub_page_1 = FactoryGirl.create(:page, :slug => 'sub_page_1', :parent => @home, :raw_template => "{% extends 'parent' %}")
|
||||
@sub_page_2 = FactoryGirl.create(:page, :slug => 'sub_page_2', :parent => @home, :raw_template => "{% extends 'parent' %}")
|
||||
|
||||
@sub_page_1_1 = Factory(:page, :slug => 'sub_page_1_1', :parent => @sub_page_1, :raw_template => "{% extends 'parent' %}")
|
||||
@sub_page_1_1 = FactoryGirl.create(:page, :slug => 'sub_page_1_1', :parent => @sub_page_1, :raw_template => "{% extends 'parent' %}")
|
||||
end
|
||||
|
||||
context 'in sub pages level #1' do
|
||||
|
@ -3,19 +3,19 @@ require 'spec_helper'
|
||||
describe Membership do
|
||||
|
||||
it 'should have a valid factory' do
|
||||
Factory.build(:membership, :account => Factory.build(:account)).should be_valid
|
||||
FactoryGirl.build(:membership, :account => FactoryGirl.build(:account)).should be_valid
|
||||
end
|
||||
|
||||
it 'should validate presence of account' do
|
||||
membership = Factory.build(:membership, :account => nil)
|
||||
membership = FactoryGirl.build(:membership, :account => nil)
|
||||
membership.should_not be_valid
|
||||
membership.errors[:account].should == ["can't be blank"]
|
||||
end
|
||||
|
||||
it 'should assign account from email' do
|
||||
Account.stubs(:where).returns([Factory.build(:account)])
|
||||
Account.stubs(:find).returns(Factory.build(:account))
|
||||
membership = Factory.build(:membership, :account => nil)
|
||||
Account.stubs(:where).returns([FactoryGirl.build(:account)])
|
||||
Account.stubs(:find).returns(FactoryGirl.build(:account))
|
||||
membership = FactoryGirl.build(:membership, :account => nil)
|
||||
membership.email = 'bart@simpson.net'
|
||||
membership.account.should_not be_nil
|
||||
membership.account.name.should == 'Bart Simpson'
|
||||
@ -24,8 +24,8 @@ describe Membership do
|
||||
describe 'next action to take' do
|
||||
|
||||
before(:each) do
|
||||
@membership = Factory.build(:membership, :site => Factory.build(:site))
|
||||
@account = Factory.build(:account)
|
||||
@membership = FactoryGirl.build(:membership, :site => FactoryGirl.build(:site))
|
||||
@account = FactoryGirl.build(:account)
|
||||
@account.stubs(:save).returns(true)
|
||||
Account.stubs(:where).returns([@account])
|
||||
Account.stubs(:find).returns(@account)
|
||||
@ -53,7 +53,7 @@ describe Membership do
|
||||
end
|
||||
|
||||
def build_membership(account = nil)
|
||||
Factory.build(:membership, :site => Factory.build(:site), :account => account || Factory.build(:account))
|
||||
FactoryGirl.build(:membership, :site => FactoryGirl.build(:site), :account => account || FactoryGirl.build(:account))
|
||||
end
|
||||
|
||||
end
|
||||
|
@ -10,36 +10,36 @@ describe Page do
|
||||
end
|
||||
|
||||
it 'should have a valid factory' do
|
||||
Factory.build(:page).should be_valid
|
||||
FactoryGirl.build(:page).should be_valid
|
||||
end
|
||||
|
||||
# Validations ##
|
||||
|
||||
%w{site title}.each do |field|
|
||||
it "should validate presence of #{field}" do
|
||||
page = Factory.build(:page, field.to_sym => nil)
|
||||
page = FactoryGirl.build(:page, field.to_sym => nil)
|
||||
page.should_not be_valid
|
||||
page.errors[field.to_sym].should == ["can't be blank"]
|
||||
end
|
||||
end
|
||||
|
||||
it 'should validate presence of slug' do
|
||||
page = Factory.build(:page, :title => nil, :slug => nil)
|
||||
page = FactoryGirl.build(:page, :title => nil, :slug => nil)
|
||||
page.should_not be_valid
|
||||
page.errors[:slug].should == ["can't be blank"]
|
||||
end
|
||||
|
||||
it 'should validate uniqueness of slug' do
|
||||
page = Factory(:page)
|
||||
(page = Factory.build(:page, :site => page.site)).should_not be_valid
|
||||
page = FactoryGirl.create(:page)
|
||||
(page = FactoryGirl.build(:page, :site => page.site)).should_not be_valid
|
||||
page.errors[:slug].should == ["is already taken"]
|
||||
end
|
||||
|
||||
it 'should validate uniqueness of slug within a "folder"' do
|
||||
site = Factory(:site)
|
||||
root = Factory(:page, :slug => 'index', :site => site)
|
||||
child_1 = Factory(:page, :slug => 'first_child', :parent => root, :site => site)
|
||||
(page = Factory.build(:page, :slug => 'first_child', :parent => root, :site => site)).should_not be_valid
|
||||
site = FactoryGirl.create(:site)
|
||||
root = FactoryGirl.create(:page, :slug => 'index', :site => site)
|
||||
child_1 = FactoryGirl.create(:page, :slug => 'first_child', :parent => root, :site => site)
|
||||
(page = FactoryGirl.build(:page, :slug => 'first_child', :parent => root, :site => site)).should_not be_valid
|
||||
page.errors[:slug].should == ["is already taken"]
|
||||
|
||||
page.slug = 'index'
|
||||
@ -48,7 +48,7 @@ describe Page do
|
||||
|
||||
%w{admin stylesheets images javascripts}.each do |slug|
|
||||
it "should consider '#{slug}' as invalid" do
|
||||
page = Factory.build(:page, :slug => slug)
|
||||
page = FactoryGirl.build(:page, :slug => slug)
|
||||
page.should_not be_valid
|
||||
page.errors[:slug].should == ["is reserved"]
|
||||
end
|
||||
@ -63,22 +63,22 @@ describe Page do
|
||||
describe 'once created' do
|
||||
|
||||
it 'should tell if the page is the index one' do
|
||||
Factory.build(:page, :slug => 'index', :site => nil).index?.should be_true
|
||||
Factory.build(:page, :slug => 'index', :depth => 1, :site => nil).index?.should be_false
|
||||
FactoryGirl.build(:page, :slug => 'index', :site => nil).index?.should be_true
|
||||
FactoryGirl.build(:page, :slug => 'index', :depth => 1, :site => nil).index?.should be_false
|
||||
end
|
||||
|
||||
it 'should have normalized slug' do
|
||||
page = Factory.build(:page, :slug => ' Valid ité.html ')
|
||||
page = FactoryGirl.build(:page, :slug => ' Valid ité.html ')
|
||||
page.valid?
|
||||
page.slug.should == 'valid-ite-html'
|
||||
|
||||
page = Factory.build(:page, :title => ' Valid ité.html ', :slug => nil, :site => page.site)
|
||||
page = FactoryGirl.build(:page, :title => ' Valid ité.html ', :slug => nil, :site => page.site)
|
||||
page.should be_valid
|
||||
page.slug.should == 'valid-ite-html'
|
||||
end
|
||||
|
||||
it 'has no cache strategy' do
|
||||
page = Factory.build(:page, :site => nil)
|
||||
page = FactoryGirl.build(:page, :site => nil)
|
||||
page.with_cache?.should == false
|
||||
end
|
||||
|
||||
@ -87,7 +87,7 @@ describe Page do
|
||||
describe '#deleting' do
|
||||
|
||||
before(:each) do
|
||||
@page = Factory.build(:page)
|
||||
@page = FactoryGirl.build(:page)
|
||||
end
|
||||
|
||||
it 'does not delete the index page' do
|
||||
@ -111,27 +111,27 @@ describe Page do
|
||||
describe 'acts as tree' do
|
||||
|
||||
before(:each) do
|
||||
@home = Factory(:page)
|
||||
@child_1 = Factory(:page, :title => 'Subpage 1', :slug => 'foo', :parent_id => @home._id, :site => @home.site)
|
||||
@home = FactoryGirl.create(:page)
|
||||
@child_1 = FactoryGirl.create(:page, :title => 'Subpage 1', :slug => 'foo', :parent_id => @home._id, :site => @home.site)
|
||||
end
|
||||
|
||||
it 'should add root elements' do
|
||||
page_404 = Factory(:page, :title => 'Page not found', :slug => '404', :site => @home.site)
|
||||
page_404 = FactoryGirl.create(:page, :title => 'Page not found', :slug => '404', :site => @home.site)
|
||||
Page.roots.count.should == 2
|
||||
Page.roots.should == [@home, page_404]
|
||||
end
|
||||
|
||||
it 'should add sub pages' do
|
||||
child_2 = Factory(:page, :title => 'Subpage 2', :slug => 'bar', :parent => @home, :site => @home.site)
|
||||
child_2 = FactoryGirl.create(:page, :title => 'Subpage 2', :slug => 'bar', :parent => @home, :site => @home.site)
|
||||
@home = Page.find(@home.id)
|
||||
@home.children.count.should == 2
|
||||
@home.children.should == [@child_1, child_2]
|
||||
end
|
||||
|
||||
it 'should move its children accordingly' do
|
||||
sub_child_1 = Factory(:page, :title => 'Sub Subpage 1', :slug => 'bar', :parent => @child_1, :site => @home.site)
|
||||
archives = Factory(:page, :title => 'archives', :slug => 'archives', :parent => @home, :site => @home.site)
|
||||
posts = Factory(:page, :title => 'posts', :slug => 'posts', :parent => archives, :site => @home.site)
|
||||
sub_child_1 = FactoryGirl.create(:page, :title => 'Sub Subpage 1', :slug => 'bar', :parent => @child_1, :site => @home.site)
|
||||
archives = FactoryGirl.create(:page, :title => 'archives', :slug => 'archives', :parent => @home, :site => @home.site)
|
||||
posts = FactoryGirl.create(:page, :title => 'posts', :slug => 'posts', :parent => archives, :site => @home.site)
|
||||
|
||||
@child_1.parent_id = archives._id
|
||||
@child_1.save
|
||||
@ -146,7 +146,7 @@ describe Page do
|
||||
end
|
||||
|
||||
it 'should destroy descendants as well' do
|
||||
Factory(:page, :title => 'Sub Subpage 1', :slug => 'bar', :parent_id => @child_1._id, :site => @home.site)
|
||||
FactoryGirl.create(:page, :title => 'Sub Subpage 1', :slug => 'bar', :parent_id => @child_1._id, :site => @home.site)
|
||||
@child_1.destroy
|
||||
Page.where(:slug => 'bar').first.should be_nil
|
||||
end
|
||||
@ -156,10 +156,10 @@ describe Page do
|
||||
describe 'acts as list' do
|
||||
|
||||
before(:each) do
|
||||
@home = Factory(:page)
|
||||
@child_1 = Factory(:page, :title => 'Subpage 1', :slug => 'foo', :parent => @home, :site => @home.site)
|
||||
@child_2 = Factory(:page, :title => 'Subpage 2', :slug => 'bar', :parent => @home, :site => @home.site)
|
||||
@child_3 = Factory(:page, :title => 'Subpage 3', :slug => 'acme', :parent => @home, :site => @home.site)
|
||||
@home = FactoryGirl.create(:page)
|
||||
@child_1 = FactoryGirl.create(:page, :title => 'Subpage 1', :slug => 'foo', :parent => @home, :site => @home.site)
|
||||
@child_2 = FactoryGirl.create(:page, :title => 'Subpage 2', :slug => 'bar', :parent => @home, :site => @home.site)
|
||||
@child_3 = FactoryGirl.create(:page, :title => 'Subpage 3', :slug => 'acme', :parent => @home, :site => @home.site)
|
||||
end
|
||||
|
||||
it 'should be at the bottom of the folder once created' do
|
||||
@ -176,8 +176,8 @@ describe Page do
|
||||
describe 'templatized extension' do
|
||||
|
||||
before(:each) do
|
||||
@page = Factory.build(:page, :site => nil, :templatized => true, :content_type_id => 42)
|
||||
ContentType.stubs(:find).returns(Factory.build(:content_type, :site => nil))
|
||||
@page = FactoryGirl.build(:page, :site => nil, :templatized => true, :content_type_id => 42)
|
||||
ContentType.stubs(:find).returns(FactoryGirl.build(:content_type, :site => nil))
|
||||
end
|
||||
|
||||
it 'is considered as a templatized page' do
|
||||
@ -198,12 +198,12 @@ describe Page do
|
||||
describe 'listed extension' do
|
||||
|
||||
it 'is considered as a visible page' do
|
||||
@page = Factory.build(:page, :site => nil, :content_type_id => 42)
|
||||
@page = FactoryGirl.build(:page, :site => nil, :content_type_id => 42)
|
||||
@page.listed?.should be_true
|
||||
end
|
||||
|
||||
it 'is not considered as a visible page' do
|
||||
@page = Factory.build(:page, :site => nil, :listed => false, :content_type_id => 42)
|
||||
@page = FactoryGirl.build(:page, :site => nil, :listed => false, :content_type_id => 42)
|
||||
@page.listed?.should be_false
|
||||
end
|
||||
|
||||
@ -212,7 +212,7 @@ describe Page do
|
||||
describe 'redirect extension' do
|
||||
|
||||
before(:each) do
|
||||
@page = Factory.build(:page, :site => nil, :redirect=> true, :redirect_url => 'http://www.google.com/')
|
||||
@page = FactoryGirl.build(:page, :site => nil, :redirect=> true, :redirect_url => 'http://www.google.com/')
|
||||
end
|
||||
|
||||
it 'is considered as a redirect page' do
|
||||
|
@ -3,61 +3,61 @@ require 'spec_helper'
|
||||
describe Site do
|
||||
|
||||
it 'should have a valid factory' do
|
||||
Factory.build(:site).should be_valid
|
||||
FactoryGirl.build(:site).should be_valid
|
||||
end
|
||||
|
||||
## Validations ##
|
||||
|
||||
it 'should validate presence of name' do
|
||||
site = Factory.build(:site, :name => nil)
|
||||
site = FactoryGirl.build(:site, :name => nil)
|
||||
site.should_not be_valid
|
||||
site.errors[:name].should == ["can't be blank"]
|
||||
end
|
||||
|
||||
it 'should validate presence of subdomain' do
|
||||
site = Factory.build(:site, :subdomain => nil)
|
||||
site = FactoryGirl.build(:site, :subdomain => nil)
|
||||
site.should_not be_valid
|
||||
site.errors[:subdomain].should == ["can't be blank"]
|
||||
end
|
||||
|
||||
%w{test test42 foo_bar}.each do |subdomain|
|
||||
it "should accept subdomain like '#{subdomain}'" do
|
||||
Factory.build(:site, :subdomain => subdomain).should be_valid
|
||||
FactoryGirl.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 = FactoryGirl.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 = FactoryGirl.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
|
||||
FactoryGirl.create(:site)
|
||||
(site = FactoryGirl.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})
|
||||
FactoryGirl.create(:site, :domains => %w{www.acme.net www.acme.com})
|
||||
|
||||
(site = Factory.build(:site, :domains => %w{www.acme.com})).should_not be_valid
|
||||
(site = FactoryGirl.build(:site, :domains => %w{www.acme.com})).should_not be_valid
|
||||
site.errors[:domains].should == ["www.acme.com is already taken"]
|
||||
|
||||
(site = Factory.build(:site, :subdomain => 'foo', :domains => %w{acme.example.com})).should_not be_valid
|
||||
(site = FactoryGirl.build(:site, :subdomain => 'foo', :domains => %w{acme.example.com})).should_not be_valid
|
||||
site.errors[:domains].should == ["acme.example.com is already taken"]
|
||||
end
|
||||
|
||||
it 'should validate format of domains' do
|
||||
site = Factory.build(:site, :domains => ['barformat.superlongextension', '-foo.net'])
|
||||
site = FactoryGirl.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
|
||||
@ -65,8 +65,8 @@ describe Site do
|
||||
## 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})
|
||||
site_1 = FactoryGirl.create(:site, :domains => %w{www.acme.net})
|
||||
site_2 = FactoryGirl.create(:site, :subdomain => 'test', :domains => %w{www.example.com})
|
||||
|
||||
sites = Site.match_domain('www.acme.net')
|
||||
sites.size.should == 1
|
||||
@ -87,8 +87,8 @@ describe Site do
|
||||
## Associations ##
|
||||
|
||||
it 'should have many accounts' do
|
||||
site = Factory.build(:site)
|
||||
account_1, account_2 = Factory(:account), Factory(:account, :name => 'homer', :email => 'homer@simpson.net')
|
||||
site = FactoryGirl.build(:site)
|
||||
account_1, account_2 = FactoryGirl.create(:account), FactoryGirl.create(:account, :name => 'homer', :email => 'homer@simpson.net')
|
||||
site.memberships.build(:account => account_1, :admin => true)
|
||||
site.memberships.build(:account => account_2)
|
||||
site.memberships.size.should == 2
|
||||
@ -98,7 +98,7 @@ describe Site do
|
||||
## Methods ##
|
||||
|
||||
it 'should return domains without subdomain' do
|
||||
site = Factory(:site, :domains => %w{www.acme.net www.acme.com})
|
||||
site = FactoryGirl.create(: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
|
||||
@ -106,7 +106,7 @@ describe Site do
|
||||
describe 'once created' do
|
||||
|
||||
before(:each) do
|
||||
@site = Factory(:site)
|
||||
@site = FactoryGirl.create(:site)
|
||||
end
|
||||
|
||||
it 'should create index and 404 pages' do
|
||||
@ -119,7 +119,7 @@ describe Site do
|
||||
describe 'deleting in cascade' do
|
||||
|
||||
before(:each) do
|
||||
@site = Factory(:site)
|
||||
@site = FactoryGirl.create(:site)
|
||||
end
|
||||
|
||||
it 'should also destroy pages' do
|
||||
|
@ -3,14 +3,14 @@ require 'spec_helper'
|
||||
describe Snippet do
|
||||
|
||||
it 'should have a valid factory' do
|
||||
Factory.build(:snippet).should be_valid
|
||||
FactoryGirl.build(:snippet).should be_valid
|
||||
end
|
||||
|
||||
# Validations ##
|
||||
|
||||
%w{site name template}.each do |field|
|
||||
it "should validate presence of #{field}" do
|
||||
template = Factory.build(:snippet, field.to_sym => nil)
|
||||
template = FactoryGirl.build(:snippet, field.to_sym => nil)
|
||||
template.should_not be_valid
|
||||
template.errors[field.to_sym].should == ["can't be blank"]
|
||||
end
|
||||
@ -19,14 +19,14 @@ describe Snippet do
|
||||
describe '#update_templates' do
|
||||
|
||||
before :each do
|
||||
@site = Factory(:site, :subdomain => 'omg')
|
||||
@snippet = Factory(:snippet, :site => @site, :slug => 'my_test_snippet', :template => 'a testing template')
|
||||
@site = FactoryGirl.create(:site, :subdomain => 'omg')
|
||||
@snippet = FactoryGirl.create(:snippet, :site => @site, :slug => 'my_test_snippet', :template => 'a testing template')
|
||||
end
|
||||
|
||||
context 'with a normal top level snippet' do
|
||||
|
||||
before :each do
|
||||
@page = Factory(:page, :site => @site, :slug => 'my_page_here', :raw_template => "{% include 'my_test_snippet' %}")
|
||||
@page = FactoryGirl.create(:page, :site => @site, :slug => 'my_page_here', :raw_template => "{% include 'my_test_snippet' %}")
|
||||
end
|
||||
|
||||
it 'updates templates with the new snippet template' do
|
||||
@ -39,7 +39,7 @@ describe Snippet do
|
||||
context 'for snippets inside of a block' do
|
||||
|
||||
before :each do
|
||||
@page = Factory(:page, :site => @site, :slug => 'my_page_here', :raw_template => "{% block main %}{% include 'my_test_snippet' %}{% endblock %}")
|
||||
@page = FactoryGirl.create(:page, :site => @site, :slug => 'my_page_here', :raw_template => "{% block main %}{% include 'my_test_snippet' %}{% endblock %}")
|
||||
end
|
||||
|
||||
it 'updates templates with the new snippet template' do
|
||||
|
@ -8,7 +8,7 @@ describe ThemeAsset do
|
||||
|
||||
before(:each) do
|
||||
ThemeAsset.any_instance.stubs(:site_id).returns('test')
|
||||
@asset = Factory.build(:theme_asset)
|
||||
@asset = FactoryGirl.build(:theme_asset)
|
||||
end
|
||||
|
||||
describe 'file is a picture' do
|
||||
@ -63,7 +63,7 @@ describe ThemeAsset do
|
||||
@asset.source = FixturedAsset.open('5k.png')
|
||||
@asset.save!
|
||||
|
||||
another_asset = Factory.build(:theme_asset, :site => @asset.site)
|
||||
another_asset = FactoryGirl.build(:theme_asset, :site => @asset.site)
|
||||
another_asset.source = FixturedAsset.open('5k.png')
|
||||
another_asset.valid?.should be_false
|
||||
another_asset.errors[:local_path].should_not be_blank
|
||||
@ -94,8 +94,8 @@ describe ThemeAsset do
|
||||
|
||||
before(:each) do
|
||||
ThemeAsset.any_instance.stubs(:site_id).returns('test')
|
||||
@asset = Factory.build(:theme_asset, {
|
||||
:site => Factory.build(:site),
|
||||
@asset = FactoryGirl.build(:theme_asset, {
|
||||
:site => FactoryGirl.build(:site),
|
||||
:plain_text_name => 'test',
|
||||
:plain_text => 'Lorem ipsum',
|
||||
:performing_plain_text => true
|
||||
|
@ -86,7 +86,6 @@ end
|
||||
|
||||
Spork.each_run do
|
||||
# This code will be run each time you run your specs.
|
||||
Locomotive.configure_for_test(true)
|
||||
Dir[Rails.root.join('spec/support/**/*.rb')].each { |f| require f }
|
||||
|
||||
# loading ruby file directly breaks the tests
|
||||
|
Loading…
Reference in New Issue
Block a user