alchemy_cms 2.0.pre3 → 2.0.pre4

Sign up to get free protection for your applications and to get access to all the features.
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