k3cms_blog 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +3 -0
- data/.rspec +1 -0
- data/Gemfile +1 -0
- data/Gemfile.lock +136 -0
- data/License.txt +165 -0
- data/Rakefile +20 -0
- data/Readme.rdoc +13 -0
- data/app/cells/k3cms/blog/blog_posts/index.html.haml +46 -0
- data/app/cells/k3cms/blog/blog_posts/index.html.haml.haml +0 -0
- data/app/cells/k3cms/blog/blog_posts/metadata_drawer.html.haml +38 -0
- data/app/cells/k3cms/blog/blog_posts/published_status.html.haml +4 -0
- data/app/cells/k3cms/blog/blog_posts_cell.rb +36 -0
- data/app/controllers/k3cms/blog/base_controller.rb +29 -0
- data/app/controllers/k3cms/blog/blog_posts_controller.rb +82 -0
- data/app/models/k3cms/blog/ability.rb +37 -0
- data/app/models/k3cms/blog/blog_post.rb +75 -0
- data/app/models/user_decorator.rb +3 -0
- data/app/views/k3cms/blog/blog_posts/_form.html.erb +28 -0
- data/app/views/k3cms/blog/blog_posts/edit.html.erb +3 -0
- data/app/views/k3cms/blog/blog_posts/index.html.haml +3 -0
- data/app/views/k3cms/blog/blog_posts/new.html.erb +5 -0
- data/app/views/k3cms/blog/blog_posts/show.html.haml +41 -0
- data/app/views/k3cms/blog/init.html.haml +34 -0
- data/config/authorization.rb +37 -0
- data/config/locales/validates_timeliness.en.yml +16 -0
- data/config/routes.rb +3 -0
- data/db/migrate/20110113015852_create_k3_blog_posts.rb +17 -0
- data/db/migrate/20110118015034_create_slugs.rb +18 -0
- data/db/migrate/20110118023300_add_cached_slug_to_blog_posts.rb +10 -0
- data/db/migrate/20110120172202_add_meta_description_to_blog_posts.rb +15 -0
- data/db/migrate/20110415180204_rename_to_k3cms_blog_posts.rb +9 -0
- data/image_source/famfamfam_silk_icons/information.png +0 -0
- data/image_source/famfamfam_silk_icons/page_add.png +0 -0
- data/image_source/famfamfam_silk_icons/page_delete.png +0 -0
- data/image_source/famfamfam_silk_icons/page_white_add.png +0 -0
- data/image_source/famfamfam_silk_icons/text_list_bullets.png +0 -0
- data/image_source/icons.xcf +0 -0
- data/k3cms_blog.gemspec +37 -0
- data/lib/form_tag_helper.rb +3 -0
- data/lib/k3cms/blog/railtie.rb +67 -0
- data/lib/k3cms/blog/version.rb +5 -0
- data/lib/k3cms_blog.rb +8 -0
- data/lib/tasks/tasks.rake +17 -0
- data/public/images/k3cms/blog/icons.png +0 -0
- data/public/images/k3cms/blog/new.png +0 -0
- data/public/javascripts/k3cms/blog.js +13 -0
- data/public/stylesheets/k3cms/blog.css +53 -0
- data/spec/connection_and_schema.rb +12 -0
- data/spec/models/blog_post_spec.rb +254 -0
- data/spec/spec_helper.rb +49 -0
- metadata +340 -0
@@ -0,0 +1,10 @@
|
|
1
|
+
class AddCachedSlugToBlogPosts < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
add_column :k3_blog_blog_posts, :cached_slug, :string
|
4
|
+
add_index :k3_blog_blog_posts, :cached_slug, :unique => true
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.down
|
8
|
+
remove_column :k3_blog_blog_posts, :cached_slug
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
class AddMetaDescriptionToBlogPosts < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
change_table :k3_blog_blog_posts do |t|
|
4
|
+
t.text :meta_description
|
5
|
+
t.text :meta_keywords
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.down
|
10
|
+
change_table :k3_blog_blog_posts do |t|
|
11
|
+
t.remove :meta_description
|
12
|
+
t.remove :meta_keywords
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
data/k3cms_blog.gemspec
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "k3cms/blog/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "k3cms_blog"
|
7
|
+
s.summary = %q{K3cms Blog}
|
8
|
+
s.description = %q{Provides a simple blog}
|
9
|
+
s.homepage = "http://k3cms.org/#{s.name}"
|
10
|
+
|
11
|
+
s.authors = `git shortlog --summary --numbered | awk '{print $2, $3 }'`.split("\n")
|
12
|
+
s.email = `git shortlog --summary --numbered --email | awk '{print $2, $3, $4}'`.split("\n")
|
13
|
+
|
14
|
+
s.add_dependency 'facets'
|
15
|
+
s.add_dependency 'rails', '~> 3.0.0'
|
16
|
+
s.add_dependency 'activerecord', '~> 3.0.0'
|
17
|
+
s.add_dependency 'actionpack', '~> 3.0.0'
|
18
|
+
s.add_dependency 'cancan'
|
19
|
+
s.add_dependency 'cells'
|
20
|
+
s.add_dependency 'attribute_normalizer'
|
21
|
+
s.add_dependency 'friendly_id'
|
22
|
+
s.add_dependency 'stringex'
|
23
|
+
s.add_dependency 'k3cms_core'
|
24
|
+
s.add_dependency 'validates_timeliness'
|
25
|
+
|
26
|
+
s.add_development_dependency 'rspec'
|
27
|
+
s.add_development_dependency 'rspec-rails'
|
28
|
+
s.add_development_dependency 'sqlite3-ruby'
|
29
|
+
s.add_development_dependency 'ruby-debug19'
|
30
|
+
|
31
|
+
s.files = `git ls-files`.split("\n")
|
32
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
33
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
34
|
+
s.require_paths = ["lib"]
|
35
|
+
s.version = K3cms::Blog::Version
|
36
|
+
s.platform = Gem::Platform::RUBY
|
37
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require "rails"
|
2
|
+
require "k3cms_blog"
|
3
|
+
require 'facets/kernel/__dir__'
|
4
|
+
require 'facets/pathname'
|
5
|
+
|
6
|
+
module K3cms
|
7
|
+
module Blog
|
8
|
+
class Railtie < Rails::Engine
|
9
|
+
puts self
|
10
|
+
|
11
|
+
config.before_initialize do
|
12
|
+
# Work around the fact that the line:
|
13
|
+
# Bundler.require(:default, Rails.env) if defined?(Bundler)
|
14
|
+
# in config/application.rb only does a 'require' for the gems explicitly listed in the app's Gemfile -- not for the gems *they* might depend on.
|
15
|
+
require 'haml'
|
16
|
+
#require 'haml-rails'
|
17
|
+
require 'validates_timeliness'
|
18
|
+
require 'cancan'
|
19
|
+
end
|
20
|
+
|
21
|
+
config.before_configuration do |app|
|
22
|
+
# Ensure that friendly_id/railtie is loaded soon enough
|
23
|
+
# The Bundler.require(:default, Rails.env) in application.rb *only* *requires* gems listed in the *app*'s Gemfile, not gems that those gems depend on, even though it *installs* those.
|
24
|
+
# We could simply list these gems in the app's Gemfile, but they are dependencies of *this* gem, not of the app, so we should handle requiring them here.
|
25
|
+
require 'friendly_id'
|
26
|
+
require 'stringex'
|
27
|
+
|
28
|
+
# Ensure that active_record is loaded before attribute_normalizer, since attribute_normalizer only loads its active_record-specific code if active_record is loaded.
|
29
|
+
require 'active_record'
|
30
|
+
require 'attribute_normalizer'
|
31
|
+
end
|
32
|
+
|
33
|
+
# This is to avoid errors like undefined method `can?' for #<K3cms::Blog::BlogPostCell>
|
34
|
+
initializer 'k3cms.authorization.cancan' do
|
35
|
+
ActiveSupport.on_load(:action_controller) do
|
36
|
+
include CanCan::ControllerAdditions
|
37
|
+
Cell::Base.send :include, CanCan::ControllerAdditions
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
config.action_view.javascript_expansions[:k3cms_editing].concat [
|
42
|
+
'k3cms/blog.js',
|
43
|
+
]
|
44
|
+
config.action_view.stylesheet_expansions[:k3cms].concat [
|
45
|
+
'k3cms/blog.css',
|
46
|
+
]
|
47
|
+
|
48
|
+
initializer 'k3cms.blog.cells_paths' do |app|
|
49
|
+
Cell::Base.view_paths += [Pathname[__DIR__] + '../../../app/cells']
|
50
|
+
end
|
51
|
+
|
52
|
+
initializer 'k3cms.pages.hooks', :before => 'k3cms.core.hook_listeners' do |app|
|
53
|
+
class K3cms::Blog::Hooks < K3cms::ThemeSupport::HookListener
|
54
|
+
insert_after :top_of_page, :file => 'k3cms/blog/init.html.haml'
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
initializer 'k3cms.blog.require_decorators', :after => 'k3cms.core.require_decorators' do |app|
|
59
|
+
#puts 'k3cms.blog.require_decorators'
|
60
|
+
Dir.glob(config.root + "app/**/*_decorator*.rb") do |c|
|
61
|
+
Rails.env.production? ? require(c) : load(c)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
data/lib/k3cms_blog.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
namespace :k3cms do
|
2
|
+
namespace :blog do
|
3
|
+
desc "Install K3cms Blog"
|
4
|
+
task :install => [:copy_public, :copy_migrations] do
|
5
|
+
end
|
6
|
+
|
7
|
+
desc "Copy public files"
|
8
|
+
task :copy_public do
|
9
|
+
K3cms::FileUtils.copy_or_symlink_files_from_gem K3cms::Blog, 'public/**/*'
|
10
|
+
end
|
11
|
+
|
12
|
+
desc "Copy migrations"
|
13
|
+
task :copy_migrations do
|
14
|
+
K3cms::FileUtils.copy_from_gem K3cms::Blog, 'db/migrate'
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
Binary file
|
Binary file
|
@@ -0,0 +1,13 @@
|
|
1
|
+
K3cms_Blog = {
|
2
|
+
}
|
3
|
+
|
4
|
+
K3cms_Blog_BlogPost = {
|
5
|
+
updatePage: function(object_name, object_id, object, source_element) {
|
6
|
+
K3cms_InlineEditor.updatePageFromObject(object_name, object_id, object, source_element)
|
7
|
+
|
8
|
+
// TODO: only update title if page title was originally set to @page.title. Perhaps we should set some JS variable to indicate which object/attribute the page title was taken form?
|
9
|
+
$('title').html(object.title)
|
10
|
+
$('meta[name=description]').attr('content', object.meta_description);
|
11
|
+
$('meta[name=keywords]'). attr('content', object.meta_keywords);
|
12
|
+
}
|
13
|
+
}
|
@@ -0,0 +1,53 @@
|
|
1
|
+
.k3cms_blog_blog_posts_index .k3cms_blog_blog_post .title {
|
2
|
+
}
|
3
|
+
.k3cms_blog_blog_post + .k3cms_blog_blog_post {
|
4
|
+
margin-top: 20px;
|
5
|
+
}
|
6
|
+
|
7
|
+
.k3cms_blog_blog_posts_index .unpublished,
|
8
|
+
.k3cms_blog_blog_posts_show .unpublished {
|
9
|
+
border: 1px solid #A33028;
|
10
|
+
background: #E6554B;
|
11
|
+
color: white;
|
12
|
+
}
|
13
|
+
.k3cms_blog_blog_posts_index .unpublished {
|
14
|
+
}
|
15
|
+
.k3cms_blog_blog_posts_show .unpublished {
|
16
|
+
font-size: 110%;
|
17
|
+
}
|
18
|
+
|
19
|
+
.k3cms_blog_blog_posts_index .below_summary {
|
20
|
+
clear: both;
|
21
|
+
}
|
22
|
+
|
23
|
+
/*------------------------------------------------------------------------------------------------*/
|
24
|
+
/* Icons */
|
25
|
+
.k3cms_blog li.icon.button a {
|
26
|
+
background: url(/images/k3cms/blog/icons.png) no-repeat;
|
27
|
+
}
|
28
|
+
|
29
|
+
.k3cms_blog li.icon.button.b1 a { background-position: 0 -24px;}
|
30
|
+
.k3cms_blog li.icon.button.b2 a { background-position: 0 -48px;}
|
31
|
+
.k3cms_blog li.icon.button.list_blog_posts a { background-position: 0 -72px;}
|
32
|
+
.k3cms_blog li.icon.button.blog_post_metadata a { background-position: 0 -96px;}
|
33
|
+
.k3cms_blog li.icon.button.b5 a { background-position: 0 -121px;}
|
34
|
+
.k3cms_blog li.icon.button.b6 a { background-position: 0 -144px;}
|
35
|
+
.k3cms_blog li.icon.button.b7 a { background-position: 0 -168px;}
|
36
|
+
.k3cms_blog li.icon.button.b8 a { background-position: 0 -192px;}
|
37
|
+
.k3cms_blog li.icon.button.b9 a { background-position: 0 -384px;}
|
38
|
+
.k3cms_blog li.icon.button.b10 a { background-position: 0 -408px;}
|
39
|
+
.k3cms_blog li.icon.button.b11 a { background-position: 0 -430px;}
|
40
|
+
.k3cms_blog li.icon.button.b12 a { background-position: 0 -454px;}
|
41
|
+
.k3cms_blog li.icon.button.b13 a { background-position: 0 -502px;}
|
42
|
+
.k3cms_blog li.icon.button.b14 a { background-position: 0 -526px;}
|
43
|
+
.k3cms_blog li.icon.button.b15 a { background-position: 0 -552px;}
|
44
|
+
.k3cms_blog li.icon.button.b16 a { background-position: 0 -574px;}
|
45
|
+
.k3cms_blog li.icon.button.b17 a { background-position: 0 -598px;}
|
46
|
+
.k3cms_blog li.icon.button.b18 a { background-position: 0 -624px;}
|
47
|
+
.k3cms_blog li.icon.button.b19 a { background-position: 0 -648px;}
|
48
|
+
.k3cms_blog li.icon.button.b20 a { background-position: 0 -672px;}
|
49
|
+
.k3cms_blog li.icon.button.b21 a { background-position: 0 -696px;}
|
50
|
+
.k3cms_blog li.icon.button.b22 a { background-position: 0 -720px;}
|
51
|
+
.k3cms_blog li.icon.button.b23 a { background-position: 0 -744px;}
|
52
|
+
|
53
|
+
/*------------------------------------------------------------------------------------------------*/
|
@@ -0,0 +1,254 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'spec_helper'
|
3
|
+
require 'app/models/k3cms/blog/blog_post'
|
4
|
+
|
5
|
+
module K3cms::Blog
|
6
|
+
describe BlogPost do
|
7
|
+
before do
|
8
|
+
Time.stub!(:now).and_return(Time.mktime(2011,1,1, 12,0))
|
9
|
+
end
|
10
|
+
|
11
|
+
describe "when a new record is initialized" do
|
12
|
+
before do
|
13
|
+
|
14
|
+
@blog_post = BlogPost.new
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should have summary set to #{s='<p>Summary description goes here</p>'}" do
|
18
|
+
@blog_post.summary.should == s
|
19
|
+
end
|
20
|
+
it "should have body set to nil" do
|
21
|
+
@blog_post.body.should == nil
|
22
|
+
end
|
23
|
+
it "should have date set to tomorrow" do
|
24
|
+
@blog_post.date.should == Date.new(2011,1,2)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe "when a saved record (with body set to nil) is initialized" do
|
29
|
+
before do
|
30
|
+
@blog_post = BlogPost.create!(:title => 'Something')
|
31
|
+
@blog_post.update_attributes!(:body => nil)
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should not change body" do
|
35
|
+
@blog_post.body.should be_nil
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe "when a new record is initialized with summary 'This talks about the stuff'" do
|
40
|
+
before do
|
41
|
+
@blog_post = BlogPost.new(:summary => 'This talks about the stuff')
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'sets body accordingly' do
|
45
|
+
@blog_post.body.should == @blog_post.summary
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
describe "when a *saved* record is initialized with summary 'This talks about the stuff'" do
|
50
|
+
before do
|
51
|
+
@blog_post = BlogPost.create!(:title => 'Something')
|
52
|
+
@blog_post.update_attributes!(:body => nil, :summary => 'Old summary')
|
53
|
+
@blog_post = BlogPost.new(:summary => 'This talks about the stuff')
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'sets body accordingly' do
|
57
|
+
@blog_post.body.should == @blog_post.summary
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
describe 'friendly_id' do
|
62
|
+
[['my COOL tItLe!', 'my-cool-title'],
|
63
|
+
['你好', 'ni-hao'],
|
64
|
+
['Łódź, Poland', 'lodz-poland'],
|
65
|
+
].each do |title, slug|
|
66
|
+
it "converts title '#{title}' to #{slug}" do
|
67
|
+
@blog_post = BlogPost.create!(:title => title)
|
68
|
+
@blog_post.friendly_id.should == slug
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
it "when I create 2 posts with default title 'New Post', the url for the 2nd post gets a sequence ('new-post--2')" do
|
73
|
+
BlogPost.destroy_all
|
74
|
+
@blog_post_1 = BlogPost.create!()
|
75
|
+
@blog_post_1.cached_slug.should == 'new-post'
|
76
|
+
@blog_post_2 = BlogPost.create!()
|
77
|
+
@blog_post_2.cached_slug.should == 'new-post--2'
|
78
|
+
end
|
79
|
+
|
80
|
+
it "when I change the url/slug, it should still be accessable by the old as well as the new" do
|
81
|
+
BlogPost.destroy_all
|
82
|
+
@blog_post = BlogPost.create!()
|
83
|
+
@blog_post.cached_slug.should == 'new-post'
|
84
|
+
|
85
|
+
@blog_post.update_attributes!(:url => 'a')
|
86
|
+
@blog_post.cached_slug.should == 'a'
|
87
|
+
|
88
|
+
@blog_post.should == BlogPost.find('new-post')
|
89
|
+
@blog_post.should == BlogPost.find('a')
|
90
|
+
end
|
91
|
+
|
92
|
+
# Updates slug automatically because custom url has not been set
|
93
|
+
it "when I set title to 'A', then change title to 'B', url and cached_slug ends up being 'b'" do
|
94
|
+
BlogPost.destroy_all
|
95
|
+
@blog_post = BlogPost.create!(:title => 'A')
|
96
|
+
@blog_post.url .should == 'a'
|
97
|
+
@blog_post.cached_slug.should == 'a'
|
98
|
+
@blog_post.should_not be_custom_url
|
99
|
+
|
100
|
+
@blog_post.update_attributes!(:title => 'B')
|
101
|
+
@blog_post.url .should == 'b'
|
102
|
+
@blog_post.cached_slug.should == 'b'
|
103
|
+
@blog_post.should_not be_custom_url
|
104
|
+
end
|
105
|
+
|
106
|
+
it "when I set title to 'A', causing the url to automatically be 'a', and then try to set manually url to 'a', the url attribute should not get updated because the new value is not different from the existing value" do
|
107
|
+
BlogPost.destroy_all
|
108
|
+
@blog_post = BlogPost.create!(:title => 'A')
|
109
|
+
@blog_post.url .should == 'a'
|
110
|
+
@blog_post.cached_slug.should == 'a'
|
111
|
+
@blog_post.should_not be_custom_url
|
112
|
+
|
113
|
+
@blog_post.update_attributes!(:url => 'a')
|
114
|
+
@blog_post.url .should == 'a'
|
115
|
+
@blog_post.cached_slug.should == 'a'
|
116
|
+
@blog_post.should_not be_custom_url
|
117
|
+
end
|
118
|
+
|
119
|
+
# Setting custom url disables automatic slug generation
|
120
|
+
it "when I set url to 'a', then change title to 'B', cached_slug remains at the custom url, 'a'" do
|
121
|
+
BlogPost.destroy_all
|
122
|
+
@blog_post = BlogPost.create!()
|
123
|
+
@blog_post.url .should == 'new-post'
|
124
|
+
@blog_post.cached_slug.should == 'new-post'
|
125
|
+
@blog_post.should_not be_custom_url
|
126
|
+
|
127
|
+
@blog_post.update_attributes!(:url => 'a')
|
128
|
+
@blog_post.url .should == 'a'
|
129
|
+
@blog_post.cached_slug.should == 'a'
|
130
|
+
@blog_post.should be_custom_url
|
131
|
+
|
132
|
+
@blog_post.update_attributes!(:title => 'B')
|
133
|
+
@blog_post.url .should == 'a'
|
134
|
+
@blog_post.cached_slug.should == 'a'
|
135
|
+
end
|
136
|
+
|
137
|
+
1.times do
|
138
|
+
it "when I set url to invalid url value '#{s='Invalid as URL'}', it converts it to something valid" do
|
139
|
+
BlogPost.destroy_all
|
140
|
+
@blog_post = BlogPost.create!()
|
141
|
+
@blog_post.url .should == 'new-post'
|
142
|
+
@blog_post.cached_slug.should == 'new-post'
|
143
|
+
@blog_post.should == BlogPost.find('new-post')
|
144
|
+
|
145
|
+
@blog_post.update_attributes!(:url => s)
|
146
|
+
@blog_post.read_attribute(:url).should == 'invalid-as-url'
|
147
|
+
@blog_post.url. should == 'invalid-as-url'
|
148
|
+
@blog_post.cached_slug. should == 'invalid-as-url'
|
149
|
+
@blog_post.should == BlogPost.find('invalid-as-url')
|
150
|
+
|
151
|
+
@blog_post.update_attributes!(:title => 'B')
|
152
|
+
@blog_post.url .should == 'invalid-as-url'
|
153
|
+
@blog_post.cached_slug.should == 'invalid-as-url'
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
1.times do
|
158
|
+
it "when I set url to invalid url value '#{s='<blink>cool</blink>'}', it strips out the tags" do
|
159
|
+
BlogPost.destroy_all
|
160
|
+
@blog_post = BlogPost.create!()
|
161
|
+
@blog_post.url .should == 'new-post'
|
162
|
+
@blog_post.cached_slug.should == 'new-post'
|
163
|
+
@blog_post.should == BlogPost.find('new-post')
|
164
|
+
|
165
|
+
@blog_post.update_attributes!(:url => s)
|
166
|
+
@blog_post.read_attribute(:url).should == 'cool'
|
167
|
+
@blog_post.url. should == 'cool'
|
168
|
+
@blog_post.cached_slug. should == 'cool'
|
169
|
+
@blog_post.should == BlogPost.find('cool')
|
170
|
+
|
171
|
+
@blog_post.update_attributes!(:title => 'B')
|
172
|
+
@blog_post.url .should == 'cool'
|
173
|
+
@blog_post.cached_slug.should == 'cool'
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
[
|
178
|
+
[nil]*2,
|
179
|
+
['']*2,
|
180
|
+
['<br>', '']
|
181
|
+
].each do |s, normalized_s|
|
182
|
+
it "when I set url to #{s.inspect}, it goes back to creating the slug based on title" do
|
183
|
+
BlogPost.destroy_all
|
184
|
+
@blog_post = BlogPost.create!(:title => 'My title', :url => 'my-url')
|
185
|
+
@blog_post.url .should == 'my-url'
|
186
|
+
@blog_post.cached_slug.should == 'my-url'
|
187
|
+
@blog_post.should be_custom_url
|
188
|
+
|
189
|
+
@blog_post.update_attributes!(:url => s)
|
190
|
+
@blog_post.read_attribute(:url).should == normalized_s
|
191
|
+
@blog_post.url .should == 'my-title'
|
192
|
+
@blog_post.cached_slug.should == 'my-title'
|
193
|
+
@blog_post.should_not be_custom_url
|
194
|
+
end
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
describe "published?" do
|
199
|
+
it 'when date is yesterday, it will report itself as being unpublished' do
|
200
|
+
@blog_post = BlogPost.create!(:date => Date.new(2011,12,31))
|
201
|
+
@blog_post.should_not be_published
|
202
|
+
end
|
203
|
+
|
204
|
+
it 'when date is today, it will report itself as being published' do
|
205
|
+
@blog_post = BlogPost.create!(:date => Date.new(2011,1,1))
|
206
|
+
@blog_post.should be_published
|
207
|
+
end
|
208
|
+
|
209
|
+
end
|
210
|
+
|
211
|
+
describe "normalization" do
|
212
|
+
[:title, :summary, :body].each do |attr_name|
|
213
|
+
it { should normalize_attribute(attr_name).from(' Something ').to('Something') }
|
214
|
+
it { should normalize_attribute(attr_name).from('').to(nil) }
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
describe "validation" do
|
219
|
+
#describe "when it has the same url as another page" do
|
220
|
+
# it "should fail validation" do
|
221
|
+
# page1 = BlogPost.create(url: '/page1')
|
222
|
+
# page2 = BlogPost.create(url: '/page1')
|
223
|
+
# page2.should_not be_valid
|
224
|
+
# page2.errors[:url].should be_present
|
225
|
+
# end
|
226
|
+
#end
|
227
|
+
|
228
|
+
describe 'date' do
|
229
|
+
it "accepts valid dates" do
|
230
|
+
BlogPost.destroy_all
|
231
|
+
page = BlogPost.new(url: '/page1', :date => '2011-02-10')
|
232
|
+
page.should be_valid
|
233
|
+
end
|
234
|
+
|
235
|
+
it "doesn't accept valid date" do
|
236
|
+
BlogPost.destroy_all
|
237
|
+
page = BlogPost.new(url: '/page1')
|
238
|
+
page.date = '2011-02-99'
|
239
|
+
page.valid?
|
240
|
+
page.should_not be_valid
|
241
|
+
page.errors['date'].first.should match(/not a valid date/)
|
242
|
+
end
|
243
|
+
end
|
244
|
+
|
245
|
+
end
|
246
|
+
|
247
|
+
describe 'to_s' do
|
248
|
+
it 'should return the title' do
|
249
|
+
blog_post = BlogPost.new(:title => 'Home')
|
250
|
+
blog_post.to_s.should match(/Home/)
|
251
|
+
end
|
252
|
+
end
|
253
|
+
end
|
254
|
+
end
|