add rspec tests for the import module + debug the cms to handle correctly the default theme

This commit is contained in:
dinedine 2010-10-29 01:36:45 +02:00
parent 680a42b8f5
commit cc0b50e22e
26 changed files with 383 additions and 112 deletions

View File

@ -10,6 +10,7 @@ gem 'devise', '= 1.1.3'
gem 'mongoid', '2.0.0.beta.19' gem 'mongoid', '2.0.0.beta.19'
gem 'bson_ext', '1.1.1' gem 'bson_ext', '1.1.1'
gem 'locomotive_mongoid_acts_as_tree', '0.1.5.1', :require => 'mongoid_acts_as_tree' gem 'locomotive_mongoid_acts_as_tree', '0.1.5.1', :require => 'mongoid_acts_as_tree'
gem 'will_paginate'
gem 'haml', '= 3.0.18' gem 'haml', '= 3.0.18'
gem 'locomotive_liquid', '2.2.2', :require => 'liquid' gem 'locomotive_liquid', '2.2.2', :require => 'liquid'

View File

@ -266,3 +266,4 @@ DEPENDENCIES
rubyzip rubyzip
spork spork
warden warden
will_paginate

View File

@ -13,8 +13,17 @@ module Admin
respond_to do |format| respond_to do |format|
if @content.save if @content.save
format.json { render :json => { :content => @content } } format.json { render :json => { :content => @content } }
format.html do
flash[@content_type.slug.singularize] = @content.aliased_attributes
redirect_to params[:success_callback]
end
else else
format.json { render :json => { :content => @content, :errors => @content.errors } } format.json { render :json => { :content => @content, :errors => @content.errors } }
format.html do
flash[@content_type.slug.singularize] = @content.aliased_attributes
flash[:errors] = content.errors
redirect_to params[:error_callback]
end
end end
end end
end end

View File

@ -42,11 +42,12 @@ module Admin
@site.save @site.save
if @site.valid? if @site.valid?
# begin begin
job = Locomotive::Import::Job.new(params[:zipfile], @site) job = Locomotive::Import::Job.new(params[:zipfile], @site, { :samples => true })
Delayed::Job.enqueue job, { :site => @site, :job_type => 'import' } Delayed::Job.enqueue job, { :site => @site, :job_type => 'import' }
# rescue; rescue Exception => e
# end # not a big deal if it did not work logger.error "Import failed because of #{e.message}"
end
redirect_to admin_session_url(:host => Site.first.domains.first, :port => request.port) redirect_to admin_session_url(:host => Site.first.domains.first, :port => request.port)
else else

View File

@ -38,6 +38,20 @@ class ContentInstance
self._visible || self._visible.nil? self._visible || self._visible.nil?
end end
def aliased_attributes # TODO: move it to the custom_fields gem
hash = { :created_at => self.created_at, :updated_at => self.updated_at }
self.custom_fields.each do |field|
case field.kind
when 'file' then hash[field._alias] = self.send(field._name.to_sym).url
else
hash[field._alias] = self.send(field._name.to_sym)
end
end
hash
end
def to_liquid def to_liquid
Locomotive::Liquid::Drops::Content.new(self) Locomotive::Liquid::Drops::Content.new(self)
end end

View File

@ -62,7 +62,16 @@ class ContentType
(if conditions.nil? || conditions.empty? (if conditions.nil? || conditions.empty?
self.contents self.contents
else else
self.contents.where(conditions) conditions_with_names = {}
conditions.each do |key, value|
# convert alias (key) to name
field = self.content_custom_fields.detect { |f| f._alias == key }
conditions_with_names[field._name.to_sym] = value
end
self.contents.where(conditions_with_names)
end).sort { |a, b| (a.send(column) || 0) <=> (b.send(column) || 0) } end).sort { |a, b| (a.send(column) || 0) <=> (b.send(column) || 0) }
end end

View File

@ -5,22 +5,24 @@ BOARD:
- editable elements should wrap a tag: div, h1, ...etc (default span) - editable elements should wrap a tag: div, h1, ...etc (default span)
- edit images (upload new ones, ...etc) => wait for aloha or send them an email ? - edit images (upload new ones, ...etc) => wait for aloha or send them an email ?
- import tool: x import tool:
- add samples option x asset whitelist
- remove existing pages / contents option x do not override existing site name
- do not override existing site name x add samples option
- page templatized (tied to content type) x content types
- samples x asset collections
x page templatized (tied to content type)
x remove existing pages / contents option => reset
- cosmetic / ui bugs / bugs: - cosmetic / ui bugs / bugs:
x segmentation with with_scope
x paginate is not working
- assets within custom contents are not deleted when the whole content type gets destroyed (after_destroy callback ?)
- increase the input field for domain names - increase the input field for domain names
- drag&drop for assets ('last' class issue) - drag&drop for assets ('last' class issue)
- paginate is not working
- segmentation with with_scope
- asset whitelist
- api x api
- handle html request (for now, it's just json) x handle html request (for now, it's just json)
- refactor slugify method (use parameterize + create a module) - refactor slugify method (use parameterize + create a module)
- [content types] the "display column" selector should not include file types - [content types] the "display column" selector should not include file types
@ -28,14 +30,13 @@ BOARD:
- global regions: keyword in editable element (http://www.mongodb.org/display/DOCS/Updating) - global regions: keyword in editable element (http://www.mongodb.org/display/DOCS/Updating)
- write my first tutorial about locomotive - write my first tutorial about locomotive
- installation guide x installation guide
- detect if new installation x detect if new installation
- no-site error redirects to the first step x no-site error redirects to the first step
- steps: x steps:
0/ welcome: domains, ...etc x welcome: domains, ...etc
1/ Create account x Create account
2/ Create new site (name, subdomain) x Create new site (name, subdomain) / Import theme (worker or list of sites from fs)
3/ Import theme (worker or list of sites from fs)
! add dom_id and css_class fields in page (body structure ?) ! add dom_id and css_class fields in page (body structure ?)

View File

@ -5,7 +5,6 @@ module CustomFields
class FileUploader < ::CarrierWave::Uploader::Base class FileUploader < ::CarrierWave::Uploader::Base
def store_dir def store_dir
puts
"sites/#{model.site_id}/contents/#{model.class.model_name.underscore}/#{model.id}/files" "sites/#{model.site_id}/contents/#{model.class.model_name.underscore}/#{model.id}/files"
end end

View File

@ -16,6 +16,7 @@ require 'actionmailer_with_request'
require 'zip/zipfilesystem' require 'zip/zipfilesystem'
require 'custom_fields' require 'custom_fields'
require 'delayed_job_mongoid' require 'delayed_job_mongoid'
require 'will_paginate'
$:.unshift File.dirname(__FILE__) $:.unshift File.dirname(__FILE__)

View File

@ -1,3 +1,5 @@
require 'locomotive/import/logger'
require 'locomotive/import/base'
require 'locomotive/import/job' require 'locomotive/import/job'
require 'locomotive/import/site' require 'locomotive/import/site'
require 'locomotive/import/assets' require 'locomotive/import/assets'

View File

@ -1,30 +1,34 @@
module Locomotive module Locomotive
module Import module Import
module AssetCollections class AssetCollections < Base
def self.process(context)
site, database = context[:site], context[:database]
def process
asset_collections = database['site']['asset_collections'] asset_collections = database['site']['asset_collections']
return if asset_collections.nil? return if asset_collections.nil?
asset_collections.each do |name, attributes| asset_collections.each do |name, attributes|
puts "....asset_collection = #{attributes['slug']}" self.log "slug = #{attributes['slug']}"
asset_collection = site.asset_collections.where(:slug => attributes['slug']).first asset_collection = site.asset_collections.where(:slug => attributes['slug']).first
asset_collection ||= self.build_asset_collection(site, attributes.merge(:name => name)) asset_collection ||= self.build_asset_collection(attributes.merge(:name => name))
self.add_or_update_fields(asset_collection, attributes['fields']) self.add_or_update_fields(asset_collection, attributes['fields'])
if options[:samples] && attributes['assets']
self.insert_samples(asset_collection, attributes['assets'].symbolize_keys)
end
asset_collection.save! asset_collection.save!
site.reload site.reload
end end
end end
def self.build_asset_collection(site, data) protected
def build_asset_collection(data)
attributes = { :internal => false }.merge(data) attributes = { :internal => false }.merge(data)
attributes.delete_if { |name, value| %w{fields assets}.include?(name) } attributes.delete_if { |name, value| %w{fields assets}.include?(name) }
@ -32,7 +36,7 @@ module Locomotive
site.asset_collections.build(attributes) site.asset_collections.build(attributes)
end end
def self.add_or_update_fields(asset_collection, fields) def add_or_update_fields(asset_collection, fields)
fields.each_with_index do |data, position| fields.each_with_index do |data, position|
name, data = data.keys.first, data.values.first name, data = data.keys.first, data.values.first
@ -48,6 +52,34 @@ module Locomotive
end end
end end
def insert_samples(asset_collection, assets)
assets.each_with_index do |data, position|
value, attributes = data.is_a?(Array) ? [data.first, data.last] : [data.keys.first, data.values.first]
url = attributes.delete('url')
# build with default attributes
asset = asset_collection.assets.build(:name => value, :position => position, :url => self.open_sample_asset(url))
attributes.each do |name, value|
field = asset_collection.asset_custom_fields.detect { |f| f._alias == name }
value = (case field.kind.downcase
when 'file' then self.open_sample_asset(value)
when 'boolean' then Boolean.set(value)
else
value
end)
asset.send("#{name}=", value)
end
asset.save
self.log "insert asset '#{name}'"
end
end
end end
end end
end end

View File

@ -1,24 +1,26 @@
module Locomotive module Locomotive
module Import module Import
module Assets class Assets < Base
def self.process(context) def process
site, theme_path = context[:site], context[:theme_path] whitelist = self.build_regexps_in_withlist(database['site']['assets']['whitelist']) rescue nil
whitelist = self.build_regexps_in_withlist(context[:database]['site']['assets']['whitelist']) rescue nil self.log "white list = #{whitelist.inspect}"
self.add_theme_assets(site, theme_path, whitelist) self.add_theme_assets(whitelist)
self.add_other_assets(site, theme_path) self.add_other_assets
end end
def self.add_theme_assets(site, theme_path, whitelist) protected
def add_theme_assets(whitelist)
%w(images media fonts javascripts stylesheets).each do |kind| %w(images media fonts javascripts stylesheets).each do |kind|
Dir[File.join(theme_path, 'public', kind, '**/*')].each do |asset_path| Dir[File.join(theme_path, 'public', kind, '**/*')].each do |asset_path|
next if File.directory?(asset_path) next if File.directory?(asset_path)
visible = self.check_against_whitelist(whitelist, asset_path.gsub(File.join(theme_path, 'public'), '')) visible = self.check_against_whitelist(whitelist, asset_path.gsub(File.join(theme_path, 'public'), '').gsub(/^\//, ''))
folder = asset_path.gsub(File.join(theme_path, 'public'), '').gsub(File.basename(asset_path), '').gsub(/^\//, '').gsub(/\/$/, '') folder = asset_path.gsub(File.join(theme_path, 'public'), '').gsub(File.basename(asset_path), '').gsub(/^\//, '').gsub(/\/$/, '')
@ -31,7 +33,7 @@ module Locomotive
begin begin
asset.save! asset.save!
rescue Exception => e rescue Exception => e
puts "\t\t !!! asset_path = #{asset_path}, folder = #{folder}, error = #{e.message}" self.log "!ERROR! = #{e.message}, #{asset_path}"
end end
site.reload site.reload
@ -39,7 +41,7 @@ module Locomotive
end end
end end
def self.add_other_assets(site, theme_path) def add_other_assets
collection = AssetCollection.find_or_create_internal(site) collection = AssetCollection.find_or_create_internal(site)
Dir[File.join(theme_path, 'public', 'samples', '*')].each do |asset_path| Dir[File.join(theme_path, 'public', 'samples', '*')].each do |asset_path|
@ -52,7 +54,7 @@ module Locomotive
end end
end end
def self.build_regexps_in_withlist(rules) def build_regexps_in_withlist(rules)
rules.collect do |rule| rules.collect do |rule|
if rule.start_with?('^') if rule.start_with?('^')
Regexp.new(rule.gsub('/', '\/')) Regexp.new(rule.gsub('/', '\/'))
@ -62,7 +64,7 @@ module Locomotive
end end
end end
def self.check_against_whitelist(whitelist, path) def check_against_whitelist(whitelist, path)
(whitelist || []).each do |rule| (whitelist || []).each do |rule|
case rule case rule
when Regexp when Regexp

View File

@ -0,0 +1,46 @@
module Locomotive
module Import
class Base
include Logger
attr_reader :context, :options
def initialize(context, options)
@context = context
@options = options
self.log "*** starting to process ***"
end
def self.process(context, options)
self.new(context, options).process
end
def process
raise 'this method has to be overidden'
end
def log(message)
super(message, self.class.name.demodulize.underscore)
end
protected
def site
@context[:site]
end
def database
@context[:database]
end
def theme_path
@context[:theme_path]
end
def open_sample_asset(url)
File.open(File.join(self.theme_path, 'public', url))
end
end
end
end

View File

@ -1,20 +1,16 @@
module Locomotive module Locomotive
module Import module Import
module ContentTypes class ContentTypes < Base
def self.process(context)
site, database = context[:site], context[:database]
content_types = database['site']['content_types']
def process
return if content_types.nil? return if content_types.nil?
content_types.each do |name, attributes| content_types.each do |name, attributes|
puts "\t\t....content_type = #{attributes['slug']}" self.log "[content_types] slug = #{attributes['slug']}"
content_type = site.content_types.where(:slug => attributes['slug']).first content_type = site.content_types.where(:slug => attributes['slug']).first
content_type ||= self.build_content_type(site, attributes.merge(:name => name)) content_type ||= self.build_content_type(attributes.merge(:name => name))
self.add_or_update_fields(content_type, attributes['fields']) self.add_or_update_fields(content_type, attributes['fields'])
@ -24,13 +20,23 @@ module Locomotive
self.set_group_by_value(content_type) self.set_group_by_value(content_type)
if options[:samples] && attributes['contents']
self.insert_samples(content_type, attributes['contents'])
end
content_type.save! content_type.save!
site.reload site.reload
end end
end end
def self.build_content_type(site, data) protected
def content_types
database['site']['content_types']
end
def build_content_type(data)
attributes = { :order_by => '_position_in_list', :group_by_field_name => data.delete('group_by') }.merge(data) attributes = { :order_by => '_position_in_list', :group_by_field_name => data.delete('group_by') }.merge(data)
attributes.delete_if { |name, value| %w{fields contents}.include?(name) } attributes.delete_if { |name, value| %w{fields contents}.include?(name) }
@ -38,7 +44,7 @@ module Locomotive
site.content_types.build(attributes) site.content_types.build(attributes)
end end
def self.add_or_update_fields(content_type, fields) def add_or_update_fields(content_type, fields)
fields.each_with_index do |data, position| fields.each_with_index do |data, position|
name, data = data.keys.first, data.values.first name, data = data.keys.first, data.values.first
@ -54,13 +60,39 @@ module Locomotive
end end
end end
def self.set_highlighted_field_name(content_type) def insert_samples(content_type, contents)
contents.each_with_index do |data, position|
value, attributes = data.is_a?(Array) ? [data.first, data.last] : [data.keys.first, data.values.first]
# build with default attributes
content = content_type.contents.build(content_type.highlighted_field_name.to_sym => value, :_position_in_list => position)
attributes.each do |name, value|
field = content_type.content_custom_fields.detect { |f| f._alias == name }
value = (case field.kind.downcase
when 'file' then self.open_sample_asset(value)
when 'boolean' then Boolean.set(value)
else
value
end)
content.send("#{name}=", value)
end
content.save
self.log "insert content '#{value}'"
end
end
def set_highlighted_field_name(content_type)
field = content_type.content_custom_fields.detect { |f| f._alias == content_type.highlighted_field_name } field = content_type.content_custom_fields.detect { |f| f._alias == content_type.highlighted_field_name }
content_type.highlighted_field_name = field._name if field content_type.highlighted_field_name = field._name if field
end end
def self.set_order_by_value(content_type) def set_order_by_value(content_type)
order_by = (case content_type.order_by order_by = (case content_type.order_by
when 'manually', '_position_in_list' then '_position_in_list' when 'manually', '_position_in_list' then '_position_in_list'
when 'date', 'updated_at' then 'updated_at' when 'date', 'updated_at' then 'updated_at'
@ -71,7 +103,7 @@ module Locomotive
content_type.order_by = order_by || '_position_in_list' content_type.order_by = order_by || '_position_in_list'
end end
def self.set_group_by_value(content_type) def set_group_by_value(content_type)
return if content_type.group_by_field_name.blank? return if content_type.group_by_field_name.blank?
field = content_type.content_custom_fields.detect { |f| f._alias == content_type.group_by_field_name } field = content_type.content_custom_fields.detect { |f| f._alias == content_type.group_by_field_name }

View File

@ -4,9 +4,15 @@ module Locomotive
module Import module Import
class Job class Job
def initialize(zipfile, site, enabled = {}) include Logger
def initialize(zipfile, site, options = {})
@site = site @site = site
@enabled = enabled @options = {
:reset => false,
:samples => false,
:enabled => {}
}.merge(options)
@identifier = self.store_zipfile(zipfile) @identifier = self.store_zipfile(zipfile)
@ -18,7 +24,7 @@ module Locomotive
end end
def perform def perform
self.log "theme identifier #{@identifier} / enabled steps = #{@enabled.inspect}" self.log "theme identifier #{@identifier}"
self.unzip! self.unzip!
@ -32,10 +38,11 @@ module Locomotive
:worker => @worker :worker => @worker
} }
self.reset! if @options[:reset]
%w(site content_types assets asset_collections snippets pages).each do |step| %w(site content_types assets asset_collections snippets pages).each do |step|
if @enabled[step] != false if @options[:enabled][step] != false
self.log "performing '#{step}' step" "Locomotive::Import::#{step.camelize}".constantize.process(context, @options)
"Locomotive::Import::#{step.camelize}".constantize.process(context)
@worker.update_attributes :step => step if @worker @worker.update_attributes :step => step if @worker
else else
self.log "skipping #{step}" self.log "skipping #{step}"
@ -59,10 +66,6 @@ module Locomotive
protected protected
def log(message)
puts "\t[import_theme] #{message}"
end
def themes_folder def themes_folder
File.join(Rails.root, 'tmp', 'themes', @site.id.to_s) File.join(Rails.root, 'tmp', 'themes', @site.id.to_s)
end end
@ -136,6 +139,13 @@ module Locomotive
end end
def reset!
@site.pages.destroy_all
@site.theme_assets.destroy_all
@site.content_types.destroy_all
@site.asset_collections.destroy_all
end
end end
end end
end end

View File

@ -0,0 +1,13 @@
module Locomotive
module Import
module Logger
def log(message, domain = '')
head = "[import_theme]"
head += "[#{domain}]" unless domain.blank?
::Locomotive::Logger.info "\t#{head} #{message}"
end
end
end
end

View File

@ -1,13 +1,11 @@
module Locomotive module Locomotive
module Import module Import
module Pages class Pages < Base
def self.process(context)
site, pages, theme_path = context[:site], context[:database]['pages'], context[:theme_path]
def process
context[:done] = {} # initialize the hash storing pages already processed context[:done] = {} # initialize the hash storing pages already processed
self.add_index_and_404(context) self.add_index_and_404
Dir[File.join(theme_path, 'templates', '**/*')].each do |template_path| Dir[File.join(theme_path, 'templates', '**/*')].each do |template_path|
@ -15,43 +13,47 @@ module Locomotive
next if %w(index 404).include?(fullpath) next if %w(index 404).include?(fullpath)
self.add_page(fullpath, context) self.add_page(fullpath)
end end
end end
def self.add_page(fullpath, context) protected
puts "\t\t....adding #{fullpath}"
def add_page(fullpath)
page = context[:done][fullpath] page = context[:done][fullpath]
return page if page # already added, so skip it return page if page # already added, so skip it
site, pages, theme_path = context[:site], context[:database]['site']['pages'], context[:theme_path]
template = File.read(File.join(theme_path, 'templates', "#{fullpath}.liquid")) rescue "Unable to find #{fullpath}.liquid" template = File.read(File.join(theme_path, 'templates', "#{fullpath}.liquid")) rescue "Unable to find #{fullpath}.liquid"
self.build_parent_template(template, context) self.build_parent_template(template)
parent = self.find_parent(fullpath, context) parent = self.find_parent(fullpath)
page = site.pages.where(:fullpath => fullpath).first || site.pages.build
attributes = { attributes = {
:title => fullpath.split('/').last.humanize, :title => fullpath.split('/').last.humanize,
:slug => fullpath.split('/').last, :slug => fullpath.split('/').last,
:parent => parent, :parent => parent,
:raw_template => template :raw_template => template
}.merge(pages[fullpath] || {}).symbolize_keys }.merge(self.pages[fullpath] || {}).symbolize_keys
# templatized ? # templatized ?
if content_type_slug = attributes.delete(:content_type) if content_type_slug = attributes.delete(:content_type)
attributes[:content_type] = site.content_types.where(:slug => content_type_slug).first fullpath.gsub!(/\/template$/, '/content_type_template')
attributes.merge!({
:templatized => true,
:content_type => site.content_types.where(:slug => content_type_slug).first
})
end end
page = site.pages.where(:fullpath => fullpath).first || site.pages.build
page.attributes = attributes page.attributes = attributes
page.save! page.save!
self.log "adding #{page.fullpath}"
site.reload site.reload
context[:done][fullpath] = page context[:done][fullpath] = page
@ -59,7 +61,7 @@ module Locomotive
page page
end end
def self.build_parent_template(template, context) def build_parent_template(template)
# just check if the template contains the extends keyword # just check if the template contains the extends keyword
fullpath = template.scan(/\{% extends (\w+) %\}/).flatten.first fullpath = template.scan(/\{% extends (\w+) %\}/).flatten.first
@ -68,13 +70,11 @@ module Locomotive
return if fullpath == 'parent' return if fullpath == 'parent'
self.add_page(fullpath, context) self.add_page(fullpath)
end end
end end
def self.find_parent(fullpath, context) def find_parent(fullpath)
site = context[:site]
segments = fullpath.split('/') segments = fullpath.split('/')
return site.pages.index.first if segments.size == 1 return site.pages.index.first if segments.size == 1
@ -86,12 +86,10 @@ module Locomotive
# look for a local index page in db # look for a local index page in db
parent = site.pages.where(:fullpath => parent_fullpath).first parent = site.pages.where(:fullpath => parent_fullpath).first
parent || self.add_page(parent_fullpath, context) parent || self.add_page(parent_fullpath)
end end
def self.add_index_and_404(context) def add_index_and_404
site, pages, theme_path = context[:site], context[:database]['site']['pages'], context[:theme_path]
%w(index 404).each_with_index do |slug, position| %w(index 404).each_with_index do |slug, position|
page = site.pages.where({ :slug => slug, :depth => 0 }).first page = site.pages.where({ :slug => slug, :depth => 0 }).first
@ -99,7 +97,7 @@ module Locomotive
template = File.read(File.join(theme_path, 'templates', "#{slug}.liquid")) template = File.read(File.join(theme_path, 'templates', "#{slug}.liquid"))
page.attributes = { :raw_template => template, :position => position }.merge(pages[slug] || {}) page.attributes = { :raw_template => template, :position => position }.merge(self.pages[slug] || {})
page.save! rescue nil # TODO better error handling page.save! rescue nil # TODO better error handling
@ -109,6 +107,10 @@ module Locomotive
end end
end end
def pages
context[:database]['site']['pages']
end
end end
end end
end end

View File

@ -1,11 +1,9 @@
module Locomotive module Locomotive
module Import module Import
module Site class Site < Base
def self.process(context) def process
site, database = context[:site], context[:database] attributes = database['site'].clone.delete_if { |name, value| %w{name pages assets content_types asset_collections}.include?(name) }
attributes = database['site'].clone.delete_if { |name, value| %w{pages assets content_types asset_collections}.include?(name) }
site.attributes = attributes site.attributes = attributes

View File

@ -1,11 +1,10 @@
module Locomotive module Locomotive
module Import module Import
module Snippets class Snippets < Base
def self.process(context)
site, theme_path = context[:site], context[:theme_path]
def process
Dir[File.join(theme_path, 'snippets', '*')].each do |snippet_path| Dir[File.join(theme_path, 'snippets', '*')].each do |snippet_path|
self.log "path = #{snippet_path}"
name = File.basename(snippet_path, File.extname(snippet_path)).parameterize('_') name = File.basename(snippet_path, File.extname(snippet_path)).parameterize('_')
@ -14,7 +13,6 @@ module Locomotive
snippet.template = File.read(snippet_path) # = site.snippets.create! :name => name, :template => snippet.template = File.read(snippet_path) # = site.snippets.create! :name => name, :template =>
snippet.save! snippet.save!
# puts "snippet = #{snippet.inspect}"
end end
end end

View File

@ -45,7 +45,7 @@ module Locomotive
protected protected
def paginate(options = {}) def paginate(options = {})
@collection ||= self.collection.paginate(options) @collection = self.collection.paginate(options)
{ {
:collection => @collection, :collection => @collection,
:current_page => @collection.current_page, :current_page => @collection.current_page,
@ -58,7 +58,7 @@ module Locomotive
end end
def collection def collection
@collection ||= @content_type.ordered_contents(@context['with_scope']) # remove per_page, page keys @collection ||= @content_type.ordered_contents(@context['with_scope'])
end end
end end
end end

View File

@ -60,7 +60,7 @@ module Locomotive
'asset_collections' => Locomotive::Liquid::Drops::AssetCollections.new, 'asset_collections' => Locomotive::Liquid::Drops::AssetCollections.new,
'contents' => Locomotive::Liquid::Drops::Contents.new, 'contents' => Locomotive::Liquid::Drops::Contents.new,
'current_page' => self.params[:page] 'current_page' => self.params[:page]
} }.merge(flash.stringify_keys) # data from api
if @page.templatized? # add instance from content type if @page.templatized? # add instance from content type
assigns['content_instance'] = @content_instance assigns['content_instance'] = @content_instance
@ -79,6 +79,8 @@ module Locomotive
end end
def prepare_and_set_response(output) def prepare_and_set_response(output)
flash.discard
response.headers['Content-Type'] = 'text/html; charset=utf-8' response.headers['Content-Type'] = 'text/html; charset=utf-8'
if @page.with_cache? if @page.with_cache?

View File

@ -39,6 +39,7 @@ Gem::Specification.new do |s|
s.add_dependency "delayed_job_mongoid", "1.0.0.rc" s.add_dependency "delayed_job_mongoid", "1.0.0.rc"
s.add_dependency "custom_fields", "1.0.0.beta2" s.add_dependency "custom_fields", "1.0.0.beta2"
s.add_dependency "rubyzip" s.add_dependency "rubyzip"
s.add_dependency "will_paginate"
s.files = Dir[ "Gemfile", s.files = Dir[ "Gemfile",
"{app}/**/*", "{app}/**/*",

BIN
spec/fixtures/themes/default.zip vendored Normal file

Binary file not shown.

View File

@ -0,0 +1,76 @@
require 'spec_helper'
describe Locomotive::Import::Job do
context 'when successful' do
before(:all) do
@site = Factory(:site)
job = Locomotive::Import::Job.new(FixturedTheme.duplicate_and_open('default.zip'), @site, { :samples => true, :reset => true })
job.perform
job.success nil
end
it 'updates the site information' do
@site.name.should_not == "HTML5 portfolio"
@site.meta_keywords.should == "html5 portfolio theme locomotive cms"
@site.meta_description.should == "portfolio powered by html5"
end
it 'adds content types' do
@site.content_types.count.should == 2
content_type = @site.content_types.where(:slug => 'projects').first
content_type.content_custom_fields.size.should == 6
end
it 'converts correctly the order_by option for content types' do
content_type = @site.content_types.where(:slug => 'messages').first
content_type.order_by.should == 'updated_at'
end
it 'adds samples coming with content types' do
content_type = @site.content_types.where(:slug => 'projects').first
content_type.contents.size.should == 5
content = content_type.contents.first
content.name.should == 'Locomotive App'
content.thumbnail.url.should_not be_nil
content.featured.should == true
end
it 'inserts theme assets' do
@site.theme_assets.count.should == 10
end
it 'hides some theme assets' do
asset = @site.theme_assets.where(:local_path => 'stylesheets/style.css').first
asset.hidden.should == false
asset = @site.theme_assets.where(:local_path => 'stylesheets/ie7.css').first
asset.hidden.should == true
end
it 'inserts all the pages' do
@site.pages.count.should == 8
end
it 'inserts the index and 404 pages' do
@site.pages.index.first.should_not be_nil
@site.pages.not_found.first.should_not be_nil
end
it 'inserts templatized page' do
page = @site.pages.where(:templatized => true).first
page.should_not be_nil
page.fullpath.should == 'portfolio/content_type_template'
end
after(:all) do
Site.destroy_all
end
end
end

View File

@ -21,6 +21,8 @@ Rspec.configure do |config|
DatabaseCleaner.orm = "mongoid" DatabaseCleaner.orm = "mongoid"
end end
config.before(:each) do config.before(:each) do
if self.described_class != Locomotive::Import::Job
DatabaseCleaner.clean DatabaseCleaner.clean
end end
end
end end

View File

@ -5,7 +5,6 @@ CarrierWave.configure do |config|
config.store_dir = "spec/tmp/uploads" config.store_dir = "spec/tmp/uploads"
config.cache_dir = "spec/tmp/cache" config.cache_dir = "spec/tmp/cache"
config.root = File.join(Rails.root, 'spec', 'tmp') config.root = File.join(Rails.root, 'spec', 'tmp')
# config.enable_processing = false
end end
module FixturedAsset module FixturedAsset
@ -29,4 +28,24 @@ module FixturedAsset
end end
end end
module FixturedTheme
def self.open(filename)
File.new(self.path(filename))
end
def self.path(filename)
File.join(File.dirname(__FILE__), '..', 'fixtures', 'themes', filename)
end
def self.duplicate(filename)
dst = File.join(File.dirname(__FILE__), '..', 'tmp', filename)
FileUtils.cp self.path(filename), dst
dst
end
def self.duplicate_and_open(filename)
File.open(self.duplicate(filename))
end
end
FixturedAsset.reset! FixturedAsset.reset!