alchemy_cms 2.0.pre3 → 2.0.pre4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --color
2
+ --format documentation
3
+ --debug
data/Gemfile CHANGED
@@ -3,9 +3,15 @@ source "http://rubygems.org"
3
3
  # Specify your gem's dependencies in alchemy.gemspec
4
4
  gemspec
5
5
 
6
- group :development do
6
+ group :development, :test do
7
7
  gem 'gettext', '~>2.0', :git => 'git://github.com/cameel/gettext.git', :require => false
8
- gem "capybara", ">= 0.4.0"
9
- gem "rspec-rails", ">= 2.0.0.beta"
10
- gem "sqlite3"
8
+ gem "rspec-rails", ">= 2.0.0.beta"
9
+ end
10
+
11
+ group :test do
12
+ gem 'factory_girl_rails'
13
+ gem "capybara", ">= 0.4.0"
14
+ gem "launchy"
15
+ gem "sqlite3"
16
+ gem "database_cleaner"
11
17
  end
@@ -9,8 +9,8 @@ Gem::Specification.new do |s|
9
9
  s.authors = ["Thomas von Deyen", "Robin Böning", "Carsten Fregin"]
10
10
  s.email = ["alchemy@magiclabs.de"]
11
11
  s.homepage = "http://alchemy-cms.com"
12
- s.summary = %q{A CMS for Rails 3}
13
- s.description = %q{A CMS for Rails 3}
12
+ s.summary = %q{An extremly flexbile CMS for Rails 3.}
13
+ s.description = %q{Alchemy is an awesome Rails CMS with an extremely flexible content storing architecture.}
14
14
  s.requirements << 'ImageMagick (libmagick), v6.6 or greater.'
15
15
  s.license = 'GPL-3'
16
16
 
@@ -33,4 +33,8 @@ Gem::Specification.new do |s|
33
33
  s.add_runtime_dependency(%q<jquery-rails>, ["~> 1.0"])
34
34
  s.add_runtime_dependency(%q<tinymce_hammer>, ["~> 0.2"])
35
35
  s.add_runtime_dependency(%q<attachment_magic>, ["~> 0.1"])
36
+
37
+ s.add_development_dependency(%q<capybara>, [">= 0.4.0"])
38
+ s.add_development_dependency(%q<rspec-rails>, [">= 2.0.0.beta"])
39
+ s.add_development_dependency(%q<sqlite3>)
36
40
  end
@@ -19,7 +19,7 @@ class AlchemyController < ApplicationController
19
19
  before_filter :mailer_set_url_options
20
20
 
21
21
  helper_method :current_server, :configuration, :multi_language?, :current_user, :clipboard_empty?, :trash_empty?, :get_clipboard
22
- helper :errors, :layout
22
+ helper :layout
23
23
 
24
24
  def render_errors_or_redirect(object, redicrect_url, flash_notice, button = nil)
25
25
  if object.errors.empty?
@@ -32,7 +32,7 @@ class AlchemyController < ApplicationController
32
32
 
33
33
  def render_remote_errors(object, button = nil)
34
34
  render :update do |page|
35
- page << "jQuery('#errors').html('<ul>" + object.errors.sum{|a, b| "<li>" + _(b) + "</li>"} + "</ul>')"
35
+ page << "jQuery('#errors').html('<ul>" + object.errors.sum { |a, b| "<li>" + _(b) + "</li>" } + "</ul>')"
36
36
  page << "jQuery('#errors').show()"
37
37
  page << "Alchemy.enableButton('#{button}')" unless button.blank?
38
38
  end
@@ -137,7 +137,6 @@ private
137
137
  end
138
138
 
139
139
  def set_stamper
140
- FastGettext.text_domain = 'alchemy'
141
140
  User.stamper = self.current_user
142
141
  end
143
142
 
@@ -152,7 +151,6 @@ private
152
151
  protected
153
152
 
154
153
  def init_gettext#:nodoc:
155
- FastGettext.text_domain = 'alchemy'
156
154
  FastGettext.available_locales = configuration(:translations).collect { |l| l[:language_code] }
157
155
  end
158
156
 
@@ -160,9 +158,9 @@ protected
160
158
  # You can set the default_translation in your config/alchemy/config.yml file
161
159
  def set_translation
162
160
  if current_user.blank? || current_user.language.blank?
163
- FastGettext.locale = configuration(:default_translation)
161
+ FastGettext.locale = configuration(:default_translation) || I18n.locale
164
162
  else
165
- FastGettext.locale = current_user.language
163
+ FastGettext.locale = current_user.language || I18n.locale
166
164
  end
167
165
  end
168
166
 
@@ -92,23 +92,15 @@ module PagesHelper
92
92
  end
93
93
  page = page_found_by_layout || page
94
94
  page = (options[:link_to_public_child] ? (page.first_public_child.blank? ? nil : page.first_public_child) : nil) if !page.public?
95
-
95
+
96
96
  if !page.blank?
97
97
  active = session[:language_id] == page.language.id
98
- if options[:linkname]
99
- if options[:linkname].to_sym == :code
100
- linkname = page.language.code
101
- else
102
- linkname = I18n.t("alchemy.languages.#{page.language.code}.name", :default => page.language.name)
103
- end
104
- else
105
- linkname = ""
106
- end
98
+ linkname = page.language.label(options[:linkname])
107
99
  if options[:as_select_box]
108
100
  languages << [linkname, show_page_with_language_url(:urlname => page.urlname, :lang => page.language.code)]
109
101
  else
110
102
  languages << link_to(
111
- "#{content_tag(:span, '', :class => "flag")}#{ content_tag(:span, linkname)}",
103
+ "#{content_tag(:span, '', :class => "flag")}#{ content_tag(:span, linkname)}".html_safe,
112
104
  show_page_with_language_path(:urlname => page.urlname, :lang => page.language.code),
113
105
  :class => "#{(active ? 'active ' : nil)}#{page.language.code} #{(i == 0) ? 'first' : (i==pages.length-1) ? 'last' : nil}",
114
106
  :title => options[:show_title] ? I18n.t("alchemy.languages.#{page.language.code}.title", :default => page.language.name) : nil
@@ -128,13 +120,11 @@ module PagesHelper
128
120
  )
129
121
  else
130
122
  if options[:spacer].blank?
131
- return languages
123
+ return languages.html_safe
132
124
  else
133
- return languages.join(options[:spacer])
125
+ return languages.join(options[:spacer]).html_safe
134
126
  end
135
127
  end
136
- else
137
- ""
138
128
  end
139
129
  end
140
130
 
@@ -30,11 +30,19 @@ class Language < ActiveRecord::Base
30
30
  self.find_by_default(true)
31
31
  end
32
32
 
33
+ def label(attrib)
34
+ if attrib.to_sym == :code
35
+ self.code
36
+ else
37
+ I18n.t("name", :scope => "alchemy.languages.#{self.code}", :default => self.name)
38
+ end
39
+ end
40
+
33
41
  private
34
42
 
35
43
  def publicity_of_default_language
36
44
  if self.default? && !self.public?
37
- errors.add_to_base(N_("Defaut language has to be public"))
45
+ errors.add(:base, N_("Defaut language has to be public"))
38
46
  return false
39
47
  else
40
48
  return true
@@ -43,7 +51,7 @@ private
43
51
 
44
52
  def presence_of_default_language
45
53
  if Language.get_default == self && self.default_changed?
46
- errors.add_to_base(N_("we_need_at_least_one_default"))
54
+ errors.add(:base, N_("we_need_at_least_one_default"))
47
55
  return false
48
56
  else
49
57
  return true
@@ -128,7 +128,7 @@ class Page < ActiveRecord::Base
128
128
  end
129
129
 
130
130
  def set_url_name
131
- self.urlname = generate_url_name((self.urlname.blank? ? self.name : self.urlname))
131
+ self.urlname = convert_url_name((self.urlname.blank? ? self.name : self.urlname))
132
132
  end
133
133
 
134
134
  def set_title
@@ -201,6 +201,7 @@ class Page < ActiveRecord::Base
201
201
  end
202
202
 
203
203
  # Returns the translated explanation of seven the page stati.
204
+ # TODO: Let I18n do this!
204
205
  def humanized_status
205
206
  case self.status
206
207
  when 0
@@ -319,7 +320,7 @@ class Page < ActiveRecord::Base
319
320
  end
320
321
 
321
322
  def first_public_child
322
- self.children.where(:public => true).limit(1)
323
+ self.children.where(:public => true).limit(1).first
323
324
  end
324
325
 
325
326
  def self.language_root_for(language_id)
@@ -455,24 +456,15 @@ private
455
456
  end
456
457
  return Page.where(conditions).order(order_direction).limit(1)
457
458
  end
458
-
459
- def generate_url_name(url_name)
460
- new_url_name = url_name.to_s.downcase
461
- new_url_name = new_url_name.gsub(/[ä]/, 'ae')
462
- new_url_name = new_url_name.gsub(/[ü]/, 'ue')
463
- new_url_name = new_url_name.gsub(/[ö]/, 'oe')
464
- new_url_name = new_url_name.gsub(/[Ä]/, 'AE')
465
- new_url_name = new_url_name.gsub(/[Ü]/, 'UE')
466
- new_url_name = new_url_name.gsub(/[Ö]/, 'OE')
467
- new_url_name = new_url_name.gsub(/[ß]/, 'ss')
468
- new_url_name = new_url_name.gsub(/[^a-zA-Z0-9_]+/, '-')
469
- if(new_url_name.length < 3)
470
- new_url_name = "-#{new_url_name}-"
471
- else
472
- new_url_name.gsub(/-+$/, '')
473
- end
474
- end
475
-
459
+
460
+ # Converts the given nbame into an url friendly string
461
+ # Names shorter than 3 will be filled with dashes, so it does not collidate with the language code.
462
+ def convert_url_name(name)
463
+ url_name = name.gsub(/[äÄ]/, 'ae').gsub(/[üÜ]/, 'ue').gsub(/[öÖ]/, 'oe').parameterize
464
+ url_name = ('-' * (3 - url_name.length)) + url_name if url_name.length < 3
465
+ return url_name
466
+ end
467
+
476
468
  # Looks in the layout_descripion, if there are elements to autogenerate.
477
469
  # If so, it generates them.
478
470
  def autogenerate_elements
@@ -93,6 +93,7 @@ default_language:
93
93
  :page_layout_name: contact
94
94
  :forward_to_page: false
95
95
  :mail_success_page: thanks
96
+ :mail_from: your.mail@your-domain.com
96
97
  :fields: [salutation, firstname, lastname, address, zip, city, phone, email, message]
97
98
  :validate_fields:
98
99
  :lastname:
@@ -1,2 +1,3 @@
1
1
  require 'fast_gettext'
2
- FastGettext.add_text_domain 'alchemy', :path => File.join(File.dirname(__FILE__), '..', '..', 'locale')
2
+ FastGettext.add_text_domain 'alchemy', :path => File.join(File.dirname(__FILE__), '..', '..', 'locale')
3
+ FastGettext.default_text_domain = 'alchemy'
@@ -2,31 +2,31 @@ if defined?(Tinymce::Hammer)
2
2
  Tinymce::Hammer.install_path = '/javascripts/alchemy/tiny_mce'
3
3
  Tinymce::Hammer.plugins = %w(safari paste fullscreen inlinepopups alchemy_link)
4
4
  Tinymce::Hammer.languages = ['de', 'en']
5
- Tinymce::Hammer.init = [
6
- [:paste_convert_headers_to_strong, true],
7
- [:paste_convert_middot_lists, true],
8
- [:paste_remove_spans, true],
9
- [:paste_remove_styles, true],
10
- [:paste_strip_class_attributes, true],
11
- [:theme, 'advanced'],
12
- [:skin, 'o2k7'],
13
- [:skin_variant, 'silver'],
14
- [:inlinepopups_skin, 'alchemy'],
15
- [:popup_css, "/stylesheets/alchemy/alchemy_tinymce_dialog.css"],
16
- [:content_css, "/stylesheets/alchemy/alchemy_tinymce_content.css"],
17
- [:dialog_type, "modal"],
18
- [:width, "100%"],
19
- [:height, '185'],
20
- [:theme_advanced_toolbar_align, 'left'],
21
- [:theme_advanced_toolbar_location, 'top'],
22
- [:theme_advanced_statusbar_location, 'bottom'],
23
- [:theme_advanced_buttons1, 'bold,italic,underline,strikethrough,sub,sup,|,numlist,bullist,indent,outdent,|,alchemy_link,unlink,|,removeformat,cleanup,|,fullscreen'],
24
- [:theme_advanced_buttons2, 'pastetext,pasteword,charmap,code,help'],
25
- [:theme_advanced_buttons3, ''],
26
- [:theme_advanced_resizing, 'true'],
27
- [:theme_advanced_resize_horizontal, false],
28
- [:theme_advanced_resizing_min_height, '185'],
29
- [:fix_list_elements, true],
30
- [:convert_urls, false]
31
- ]
5
+ Tinymce::Hammer.init = {
6
+ :paste_convert_headers_to_strong => true,
7
+ :paste_convert_middot_lists => true,
8
+ :paste_remove_spans => true,
9
+ :paste_remove_styles => true,
10
+ :paste_strip_class_attributes => true,
11
+ :theme => 'advanced',
12
+ :skin => 'o2k7',
13
+ :skin_variant => 'silver',
14
+ :inlinepopups_skin => 'alchemy',
15
+ :popup_css => "/stylesheets/alchemy/alchemy_tinymce_dialog.css",
16
+ :content_css => "/stylesheets/alchemy/alchemy_tinymce_content.css",
17
+ :dialog_type => "modal",
18
+ :width => "100%",
19
+ :height => '185',
20
+ :theme_advanced_toolbar_align => 'left',
21
+ :theme_advanced_toolbar_location => 'top',
22
+ :theme_advanced_statusbar_location => 'bottom',
23
+ :theme_advanced_buttons1 => 'bold,italic,underline,strikethrough,sub,sup,|,numlist,bullist,indent,outdent,|,alchemy_link,unlink,|,removeformat,cleanup,|,fullscreen',
24
+ :theme_advanced_buttons2 => 'pastetext,pasteword,charmap,code,help',
25
+ :theme_advanced_buttons3 => '',
26
+ :theme_advanced_resizing => 'true',
27
+ :theme_advanced_resize_horizontal => false,
28
+ :theme_advanced_resizing_min_height => '185',
29
+ :fix_list_elements => true,
30
+ :convert_urls => false
31
+ }
32
32
  end
@@ -0,0 +1,9 @@
1
+ class AddDefaultRoleToUsers < ActiveRecord::Migration
2
+ def self.up
3
+ change_column_default :users, :role, "registered"
4
+ end
5
+
6
+ def self.down
7
+ change_column_default :users, :role, nil
8
+ end
9
+ end
@@ -0,0 +1,93 @@
1
+ # This recipe contains Capistrano recipes for handling the uploads, ferret index and picture cache files while deploying your application.
2
+ # It also contains a ferret:rebuild_index task to rebuild the index after deploying your application.
3
+
4
+ Capistrano::Configuration.instance(:must_exist).load do
5
+
6
+ after "deploy:setup", "alchemy:shared_folders:create"
7
+ after "deploy:symlink", "alchemy:shared_folders:symlink"
8
+
9
+ before "deploy:restart", "alchemy:files:copy"
10
+
11
+ namespace :alchemy do
12
+
13
+ namespace :shared_folders do
14
+
15
+ # This task creates the shared folders for uploads, picture cache and ferret index while setting up your server.
16
+ # Call after deploy:setup like +after "deploy:setup", "alchemy:create_shared_folders"+ in your +deploy.rb+.
17
+ desc "Creates the uploads and picture cache directory in the shared folder. Call after deploy:setup"
18
+ task :create, :roles => :app do
19
+ run "mkdir -p #{shared_path}/uploads"
20
+ run "mkdir -p #{shared_path}/index"
21
+ run "mkdir -p #{shared_path}/uploads/pictures"
22
+ run "mkdir -p #{shared_path}/uploads/attachments"
23
+ run "mkdir -p #{shared_path}/cache"
24
+ run "mkdir -p #{shared_path}/cache/pictures"
25
+ end
26
+
27
+ # This task sets the symlinks for uploads, picture cache and ferret index folder.
28
+ # Call after deploy:symlink like +after "deploy:symlink", "alchemy:symlink_folders"+ in your +deploy.rb+.
29
+ desc "Sets the symlinks for uploads, picture cache and ferret index folder. Call after deploy:symlink"
30
+ task :symlink, :roles => :app do
31
+ run "rm -rf #{current_path}/public/uploads/*"
32
+ run "ln -nfs #{shared_path}/uploads/pictures/ #{current_path}/uploads/pictures"
33
+ run "ln -nfs #{shared_path}/uploads/attachments/ #{current_path}/uploads/attachments"
34
+ run "rm -rf #{current_path}/public/pictures"
35
+ run "ln -nfs #{shared_path}/cache/pictures/ #{current_path}/public/pictures"
36
+ run "rm -rf #{current_path}/index"
37
+ run "ln -nfs #{shared_path}/index/ #{current_path}/index"
38
+ end
39
+
40
+ end
41
+
42
+ namespace :files do
43
+
44
+ desc "Copies all assets and migration files from Alchemy to project"
45
+ task :copy do
46
+ run "cd #{current_path} && RAILS_ENV=production #{rake} alchemy:assets:copy:all"
47
+ run "cd #{current_path} && RAILS_ENV=production #{rake} alchemy:migrations:sync"
48
+ end
49
+
50
+ end
51
+
52
+ namespace :database_yml do
53
+
54
+ desc "Creates the database.yml file"
55
+ task :create do
56
+ db_config = ERB.new <<-EOF
57
+ production:
58
+ adapter: mysql
59
+ encoding: utf8
60
+ reconnect: false
61
+ pool: 5
62
+ database: #{ Capistrano::CLI.ui.ask("Database name: ") }
63
+ username: #{ Capistrano::CLI.ui.ask("Database username: ") }
64
+ password: #{ Capistrano::CLI.ui.ask("Database password: ") }
65
+ socket: #{ Capistrano::CLI.ui.ask("Database socket: ") }
66
+ host: #{ Capistrano::CLI.ui.ask("Database host: ") }
67
+ EOF
68
+ run "mkdir -p #{shared_path}/config"
69
+ put db_config.result, "#{shared_path}/config/database.yml"
70
+ end
71
+
72
+ desc "Symlinks the database.yml file from shared folder into config folder"
73
+ task :symlink, :except => { :no_release => true } do
74
+ run "ln -nfs #{shared_path}/config/database.yml #{release_path}/config/database.yml"
75
+ end
76
+
77
+ end
78
+
79
+ end
80
+
81
+ namespace :ferret do
82
+
83
+ # This task rebuilds the ferret index for the EssenceText and EssenceRichtext Models.
84
+ # Call it before deploy:restart like +before "deploy:restart", "alchemy:rebuild_index"+ in your +deploy.rb+.
85
+ # It uses the +alchemy:rebuild_index+ rake task found in +vendor/plugins/alchemy/lib/tasks+.
86
+ desc "Rebuild the ferret index. Call before deploy:restart"
87
+ task :rebuild_index, :roles => :app do
88
+ run "cd #{current_path} && RAILS_ENV=production #{rake} ferret:rebuild_index"
89
+ end
90
+
91
+ end
92
+
93
+ end
@@ -1,5 +1,5 @@
1
1
  module Alchemy
2
2
 
3
- VERSION = "2.0.pre3"
3
+ VERSION = "2.0.pre4"
4
4
 
5
5
  end
@@ -10,7 +10,7 @@
10
10
  #
11
11
  # It's strongly recommended to check this file into your version control system.
12
12
 
13
- ActiveRecord::Schema.define(:version => 20110711142057) do
13
+ ActiveRecord::Schema.define(:version => 20110919110451) do
14
14
 
15
15
  create_table "attachments", :force => true do |t|
16
16
  t.string "name"
@@ -242,20 +242,20 @@ ActiveRecord::Schema.define(:version => 20110711142057) do
242
242
  t.string "login"
243
243
  t.string "email"
244
244
  t.string "gender"
245
- t.string "role"
245
+ t.string "role", :default => "registered"
246
246
  t.string "language"
247
- t.string "crypted_password", :limit => 128, :default => "", :null => false
248
- t.string "password_salt", :limit => 128, :default => "", :null => false
249
- t.integer "login_count", :default => 0, :null => false
250
- t.integer "failed_login_count", :default => 0, :null => false
247
+ t.string "crypted_password", :limit => 128, :default => "", :null => false
248
+ t.string "password_salt", :limit => 128, :default => "", :null => false
249
+ t.integer "login_count", :default => 0, :null => false
250
+ t.integer "failed_login_count", :default => 0, :null => false
251
251
  t.datetime "last_request_at"
252
252
  t.datetime "current_login_at"
253
253
  t.datetime "last_login_at"
254
254
  t.string "current_login_ip"
255
255
  t.string "last_login_ip"
256
- t.string "persistence_token", :null => false
257
- t.string "single_access_token", :null => false
258
- t.string "perishable_token", :null => false
256
+ t.string "persistence_token", :null => false
257
+ t.string "single_access_token", :null => false
258
+ t.string "perishable_token", :null => false
259
259
  t.datetime "created_at"
260
260
  t.datetime "updated_at"
261
261
  t.integer "creator_id"
@@ -0,0 +1,43 @@
1
+ FactoryGirl.define do
2
+
3
+ factory :user do
4
+ email 'john@doe.com'
5
+ login "jdoe"
6
+ password 's3cr3t'
7
+ password_confirmation 's3cr3t'
8
+
9
+ factory :admin_user do
10
+ role "admin"
11
+ end
12
+
13
+ factory :registered_user do
14
+ role "registered"
15
+ end
16
+
17
+ factory :author_user do
18
+ role "author"
19
+ end
20
+
21
+ factory :editor_user do
22
+ role "editor"
23
+ end
24
+
25
+ end
26
+
27
+ factory :language do
28
+ code "kl"
29
+ name 'Klingonian'
30
+ default false
31
+ frontpage_name 'tuq'
32
+ page_layout 'intro'
33
+ public true
34
+ end
35
+
36
+ factory :page do
37
+ name "tuq"
38
+ page_layout "intro"
39
+ association :language
40
+ public false
41
+ end
42
+
43
+ end
@@ -14,8 +14,8 @@ describe "Security: " do
14
14
  end
15
15
  end
16
16
 
17
- context "If users are present" do
18
- it "one should not to be able to signup" do
17
+ context "If on or more users are present" do
18
+ it "a visitor should not be able to signup" do
19
19
  @user = User.create({:login => 'foo', :email => 'foo@bar.com', :password => 's3cr3t', :password_confirmation => 's3cr3t'})
20
20
  visit '/admin/signup'
21
21
  within('#alchemy_greeting') { page.should_not have_content('have to signup') }
@@ -0,0 +1,29 @@
1
+ require 'spec_helper'
2
+
3
+ describe Language do
4
+
5
+ before(:all) do
6
+ @language = Factory(:language)
7
+ end
8
+
9
+ after(:all) do
10
+ @language.destroy if @language
11
+ end
12
+
13
+ it "should return a label for code" do
14
+ @language.label(:code).should == 'kl'
15
+ end
16
+
17
+ it "should return a label for name" do
18
+ @language.label(:name).should == 'Klingonian'
19
+ end
20
+
21
+ it "should not be deletable if it is the default language" do
22
+ @default_language = Language.find_by_default(true)
23
+ if !@default_language
24
+ @default_language = Factory(:language, :name => "default", :code => "aa", :frontpage_name => "intro", :default => true)
25
+ end
26
+ expect { @default_language.destroy }.should raise_error
27
+ end
28
+
29
+ end
@@ -0,0 +1,50 @@
1
+ require 'spec_helper'
2
+
3
+ describe Page do
4
+
5
+ it "should get a webfriendly urlname on create" do
6
+ page = Factory(:page, :name => 'klingon$&stößel ')
7
+ page.urlname.should == 'klingon-stoessel'
8
+ end
9
+
10
+ it "should generate a three letter urlname from two letter name" do
11
+ page = Factory(:page, :name => 'Au')
12
+ page.urlname.should == '-au'
13
+ end
14
+
15
+ it "should generate a three letter urlname from two letter name with umlaut" do
16
+ page = Factory(:page, :name => 'Aü')
17
+ page.urlname.should == 'aue'
18
+ end
19
+
20
+ it "should generate a three letter urlname from one letter name" do
21
+ page = Factory(:page, :name => 'A')
22
+ page.urlname.should == '--a'
23
+ end
24
+
25
+ context "Root pages" do
26
+ it "should contain one ore more rootpages" do
27
+ Page.where(:parent_id => nil).any?
28
+ end
29
+ end
30
+
31
+ context "with children" do
32
+ before(:each) do
33
+ @page = Factory(:page)
34
+ @first_child = Factory(:page, :name => "First child", :language => @page.language, :public => false)
35
+ @first_child.move_to_child_of(@page)
36
+
37
+ @first_public_child = Factory(:page, :name => "First public child", :language => @page.language, :public => true)
38
+ @first_public_child.move_to_child_of(@page)
39
+ end
40
+
41
+ it "should return a page object (or nil if no public children exists) for first_public_child" do
42
+ if @page.children.any?
43
+ @page.first_public_child.should == @first_public_child
44
+ else
45
+ @page.first_public_child.should == nil
46
+ end
47
+ end
48
+ end
49
+
50
+ end
@@ -8,6 +8,12 @@ FastGettext.text_domain = 'alchemy'
8
8
  require File.expand_path("../dummy/config/environment.rb", __FILE__)
9
9
  require "rails/test_help"
10
10
  require "rspec/rails"
11
+ require 'factory_girl'
12
+ require 'database_cleaner'
13
+ require 'factories.rb'
14
+
15
+ DatabaseCleaner.strategy = :truncation
16
+ DatabaseCleaner.clean
11
17
 
12
18
  ActionMailer::Base.delivery_method = :test
13
19
  ActionMailer::Base.perform_deliveries = true
@@ -27,14 +33,11 @@ ActiveRecord::Migrator.migrate File.expand_path("../dummy/db/migrate/", __FILE__
27
33
  Alchemy::Seeder.seed!
28
34
 
29
35
  # Load support files
30
- Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
36
+ Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
31
37
 
32
38
  RSpec.configure do |config|
33
- # Remove this line if you don't want RSpec's should and should_not
34
- # methods or matchers
35
39
  require 'rspec/expectations'
36
40
  config.include RSpec::Matchers
37
-
38
- # == Mock Framework
39
41
  config.mock_with :rspec
42
+ config.use_transactional_fixtures = true
40
43
  end
@@ -0,0 +1,10 @@
1
+ require 'spec_helper'
2
+
3
+ describe User do
4
+
5
+ it "should have a role" do
6
+ @user = Factory.create(:user)
7
+ @user.role.should_not be_nil
8
+ end
9
+
10
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: alchemy_cms
3
3
  version: !ruby/object:Gem::Version
4
- hash: 1923831935
4
+ hash: 1923831921
5
5
  prerelease: 4
6
6
  segments:
7
7
  - 2
8
8
  - 0
9
9
  - pre
10
- - 3
11
- version: 2.0.pre3
10
+ - 4
11
+ version: 2.0.pre4
12
12
  platform: ruby
13
13
  authors:
14
14
  - Thomas von Deyen
@@ -18,7 +18,7 @@ autorequire:
18
18
  bindir: bin
19
19
  cert_chain: []
20
20
 
21
- date: 2011-09-15 00:00:00 Z
21
+ date: 2011-09-28 00:00:00 Z
22
22
  dependencies:
23
23
  - !ruby/object:Gem::Dependency
24
24
  name: rails
@@ -232,7 +232,54 @@ dependencies:
232
232
  version: "0.1"
233
233
  type: :runtime
234
234
  version_requirements: *id014
235
- description: A CMS for Rails 3
235
+ - !ruby/object:Gem::Dependency
236
+ name: capybara
237
+ prerelease: false
238
+ requirement: &id015 !ruby/object:Gem::Requirement
239
+ none: false
240
+ requirements:
241
+ - - ">="
242
+ - !ruby/object:Gem::Version
243
+ hash: 15
244
+ segments:
245
+ - 0
246
+ - 4
247
+ - 0
248
+ version: 0.4.0
249
+ type: :development
250
+ version_requirements: *id015
251
+ - !ruby/object:Gem::Dependency
252
+ name: rspec-rails
253
+ prerelease: false
254
+ requirement: &id016 !ruby/object:Gem::Requirement
255
+ none: false
256
+ requirements:
257
+ - - ">="
258
+ - !ruby/object:Gem::Version
259
+ hash: 31098209
260
+ segments:
261
+ - 2
262
+ - 0
263
+ - 0
264
+ - beta
265
+ version: 2.0.0.beta
266
+ type: :development
267
+ version_requirements: *id016
268
+ - !ruby/object:Gem::Dependency
269
+ name: sqlite3
270
+ prerelease: false
271
+ requirement: &id017 !ruby/object:Gem::Requirement
272
+ none: false
273
+ requirements:
274
+ - - ">="
275
+ - !ruby/object:Gem::Version
276
+ hash: 3
277
+ segments:
278
+ - 0
279
+ version: "0"
280
+ type: :development
281
+ version_requirements: *id017
282
+ description: Alchemy is an awesome Rails CMS with an extremely flexible content storing architecture.
236
283
  email:
237
284
  - alchemy@magiclabs.de
238
285
  executables:
@@ -243,6 +290,7 @@ extra_rdoc_files: []
243
290
 
244
291
  files:
245
292
  - .gitignore
293
+ - .rspec
246
294
  - .yardopts
247
295
  - Gemfile
248
296
  - LICENSE
@@ -278,7 +326,6 @@ files:
278
326
  - app/helpers/admin/pictures_helper.rb
279
327
  - app/helpers/alchemy_helper.rb
280
328
  - app/helpers/elements_helper.rb
281
- - app/helpers/errors_helper.rb
282
329
  - app/helpers/layout_helper.rb
283
330
  - app/helpers/pages_helper.rb
284
331
  - app/mailers/messages.rb
@@ -688,6 +735,8 @@ files:
688
735
  - db/migrate/20110530102804_change_pages_page_layout_column.rb
689
736
  - db/migrate/20110707190728_add_render_size_to_essence_pictures.rb
690
737
  - db/migrate/20110711142057_change_open_link_in_new_window_to_link_target.rb
738
+ - db/migrate/20110919110451_add_default_role_to_users.rb
739
+ - lib/alchemy/capistrano.rb
691
740
  - lib/alchemy/config.rb
692
741
  - lib/alchemy/controller.rb
693
742
  - lib/alchemy/engine.rb
@@ -721,7 +770,6 @@ files:
721
770
  - lib/tasks/install.rake
722
771
  - lib/tasks/upgrade.rake
723
772
  - lib/translation_extras/alchemy_core_modules.rb
724
- - lib/vendor/i18n_label.rb
725
773
  - locale/alchemy.pot
726
774
  - locale/de/LC_MESSAGES/alchemy.mo
727
775
  - locale/de/alchemy.po
@@ -729,7 +777,6 @@ files:
729
777
  - locale/en/alchemy.po
730
778
  - locale/missing_translations.rb
731
779
  - locale/model_attributes.rb
732
- - recipes/alchemy_capistrano_tasks.rb
733
780
  - spec/alchemy_spec.rb
734
781
  - spec/config_spec.rb
735
782
  - spec/dummy/Rakefile
@@ -909,9 +956,13 @@ files:
909
956
  - spec/dummy/public/stylesheets/alchemy/jquery.sb.css
910
957
  - spec/dummy/public/stylesheets/alchemy/standard_set.css
911
958
  - spec/dummy/script/rails
959
+ - spec/factories.rb
912
960
  - spec/integration/navigation_spec.rb
913
961
  - spec/integration/security_spec.rb
962
+ - spec/language_spec.rb
963
+ - spec/page_spec.rb
914
964
  - spec/spec_helper.rb
965
+ - spec/user_spec.rb
915
966
  homepage: http://alchemy-cms.com
916
967
  licenses:
917
968
  - GPL-3
@@ -946,7 +997,7 @@ rubyforge_project:
946
997
  rubygems_version: 1.8.10
947
998
  signing_key:
948
999
  specification_version: 3
949
- summary: A CMS for Rails 3
1000
+ summary: An extremly flexbile CMS for Rails 3.
950
1001
  test_files:
951
1002
  - spec/alchemy_spec.rb
952
1003
  - spec/config_spec.rb
@@ -1127,6 +1178,10 @@ test_files:
1127
1178
  - spec/dummy/public/stylesheets/alchemy/jquery.sb.css
1128
1179
  - spec/dummy/public/stylesheets/alchemy/standard_set.css
1129
1180
  - spec/dummy/script/rails
1181
+ - spec/factories.rb
1130
1182
  - spec/integration/navigation_spec.rb
1131
1183
  - spec/integration/security_spec.rb
1184
+ - spec/language_spec.rb
1185
+ - spec/page_spec.rb
1132
1186
  - spec/spec_helper.rb
1187
+ - spec/user_spec.rb
@@ -1,37 +0,0 @@
1
- module ErrorsHelper
2
-
3
- def error_messages_for(*params)
4
- options = params.extract_options!.symbolize_keys
5
- if object = options.delete(:object)
6
- objects = [object].flatten
7
- else
8
- objects = params.collect {|object_name| instance_variable_get("@#{object_name}") }.compact
9
- end
10
- count = objects.inject(0) {|sum, object| sum + object.errors.length }
11
- unless count.zero?
12
- html = {}
13
- [:id, :class].each do |key|
14
- if options.include?(key)
15
- value = options[key]
16
- html[key] = value unless value.blank?
17
- else
18
- html[key] = 'errorExplanation'
19
- end
20
- end
21
- options[:object_name] ||= params.first
22
- options[:header_message] = I18n.t("activerecord.errors.template.header", {:count => count, :model => object.class.to_s.humanize}) unless options.include?(:header_message)
23
- options[:message] ||= I18n.t('activerecord.errors.template.body') unless options.include?(:message)
24
- error_messages = objects.map {|object| object.errors.collect{ |column,error| content_tag( :li, error ) } }
25
-
26
- contents = ''
27
- contents << content_tag(options[:header_tag] || :h2, options[:header_message]) unless options[:header_message].blank?
28
- contents << content_tag(:p, options[:message]) unless options[:message].blank?
29
- contents << content_tag(:ul, error_messages)
30
-
31
- content_tag(:div, contents, html)
32
- else
33
- ''
34
- end
35
- end
36
-
37
- end
@@ -1,23 +0,0 @@
1
- # Took from https://github.com/iain/i18n_label
2
- module ActionView
3
- module Helpers
4
- class InstanceTag
5
- def to_label_tag(text = nil, options = {})
6
- options = options.stringify_keys
7
- name_and_id = options.dup
8
- add_default_name_and_id(name_and_id)
9
- options.delete("index")
10
- options["for"] ||= name_and_id["id"]
11
- if text.blank?
12
- content = method_name.humanize
13
- if object.class.respond_to?(:human_attribute_name)
14
- content = object.class.human_attribute_name(method_name)
15
- end
16
- else
17
- content = text.to_s
18
- end
19
- label_tag(name_and_id["id"], content, options)
20
- end
21
- end
22
- end
23
- end
@@ -1,83 +0,0 @@
1
- # This recipe contains Capistrano recipes for handling the uploads, ferret index and picture cache files while deploying your application.
2
- # It also contains a ferret:rebuild_index task to rebuild the index after deploying your application.
3
-
4
- namespace :alchemy do
5
-
6
- namespace :shared_folders do
7
-
8
- # This task creates the shared folders for uploads, picture cache and ferret index while setting up your server.
9
- # Call after deploy:setup like +after "deploy:setup", "alchemy:create_shared_folders"+ in your +deploy.rb+.
10
- desc "Creates the uploads and picture cache directory in the shared folder. Call after deploy:setup"
11
- task :create, :roles => :app do
12
- run "mkdir -p #{shared_path}/uploads"
13
- run "mkdir -p #{shared_path}/index"
14
- run "mkdir -p #{shared_path}/uploads/pictures"
15
- run "mkdir -p #{shared_path}/uploads/attachments"
16
- run "mkdir -p #{shared_path}/cache"
17
- run "mkdir -p #{shared_path}/cache/pictures"
18
- end
19
-
20
- # This task sets the symlinks for uploads, picture cache and ferret index folder.
21
- # Call after deploy:symlink like +after "deploy:symlink", "alchemy:symlink_folders"+ in your +deploy.rb+.
22
- desc "Sets the symlinks for uploads, picture cache and ferret index folder. Call after deploy:symlink"
23
- task :symlink, :roles => :app do
24
- run "rm -rf #{current_path}/public/uploads/*"
25
- run "ln -nfs #{shared_path}/uploads/pictures/ #{current_path}/uploads/pictures"
26
- run "ln -nfs #{shared_path}/uploads/attachments/ #{current_path}/uploads/attachments"
27
- run "rm -rf #{current_path}/public/pictures"
28
- run "ln -nfs #{shared_path}/cache/pictures/ #{current_path}/public/pictures"
29
- run "rm -rf #{current_path}/index"
30
- run "ln -nfs #{shared_path}/index/ #{current_path}/index"
31
- end
32
-
33
- end
34
-
35
- namespace :assets do
36
-
37
- desc "Copies all assets from Alchemy plugin folder to public folder"
38
- task :copy do
39
- run "cd #{current_path} && RAILS_ENV=production rake alchemy:assets:copy:all"
40
- end
41
-
42
- end
43
-
44
- namespace :database_yml do
45
-
46
- desc "Creates the database.yml file"
47
- task :create do
48
- db_config = ERB.new <<-EOF
49
- production:
50
- adapter: mysql
51
- encoding: utf8
52
- reconnect: false
53
- pool: 5
54
- database: #{ Capistrano::CLI.ui.ask("Database name: ") }
55
- username: #{ Capistrano::CLI.ui.ask("Database username: ") }
56
- password: #{ Capistrano::CLI.ui.ask("Database password: ") }
57
- socket: #{ Capistrano::CLI.ui.ask("Database socket: ") }
58
- host: #{ Capistrano::CLI.ui.ask("Database host: ") }
59
- EOF
60
- run "mkdir -p #{shared_path}/config"
61
- put db_config.result, "#{shared_path}/config/database.yml"
62
- end
63
-
64
- desc "Symlinks the database.yml file from shared folder into config folder"
65
- task :symlink, :except => { :no_release => true } do
66
- run "ln -nfs #{shared_path}/config/database.yml #{release_path}/config/database.yml"
67
- end
68
-
69
- end
70
-
71
- end
72
-
73
- namespace :ferret do
74
-
75
- # This task rebuilds the ferret index for the EssenceText and EssenceRichtext Models.
76
- # Call it before deploy:restart like +before "deploy:restart", "alchemy:rebuild_index"+ in your +deploy.rb+.
77
- # It uses the +alchemy:rebuild_index+ rake task found in +vendor/plugins/alchemy/lib/tasks+.
78
- desc "Rebuild the ferret index. Call before deploy:restart"
79
- task :rebuild_index, :roles => :app do
80
- run "cd #{current_path} && RAILS_ENV=production rake ferret:rebuild_index"
81
- end
82
-
83
- end