k3cms_blog 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. data/.gitignore +3 -0
  2. data/.rspec +1 -0
  3. data/Gemfile +1 -0
  4. data/Gemfile.lock +136 -0
  5. data/License.txt +165 -0
  6. data/Rakefile +20 -0
  7. data/Readme.rdoc +13 -0
  8. data/app/cells/k3cms/blog/blog_posts/index.html.haml +46 -0
  9. data/app/cells/k3cms/blog/blog_posts/index.html.haml.haml +0 -0
  10. data/app/cells/k3cms/blog/blog_posts/metadata_drawer.html.haml +38 -0
  11. data/app/cells/k3cms/blog/blog_posts/published_status.html.haml +4 -0
  12. data/app/cells/k3cms/blog/blog_posts_cell.rb +36 -0
  13. data/app/controllers/k3cms/blog/base_controller.rb +29 -0
  14. data/app/controllers/k3cms/blog/blog_posts_controller.rb +82 -0
  15. data/app/models/k3cms/blog/ability.rb +37 -0
  16. data/app/models/k3cms/blog/blog_post.rb +75 -0
  17. data/app/models/user_decorator.rb +3 -0
  18. data/app/views/k3cms/blog/blog_posts/_form.html.erb +28 -0
  19. data/app/views/k3cms/blog/blog_posts/edit.html.erb +3 -0
  20. data/app/views/k3cms/blog/blog_posts/index.html.haml +3 -0
  21. data/app/views/k3cms/blog/blog_posts/new.html.erb +5 -0
  22. data/app/views/k3cms/blog/blog_posts/show.html.haml +41 -0
  23. data/app/views/k3cms/blog/init.html.haml +34 -0
  24. data/config/authorization.rb +37 -0
  25. data/config/locales/validates_timeliness.en.yml +16 -0
  26. data/config/routes.rb +3 -0
  27. data/db/migrate/20110113015852_create_k3_blog_posts.rb +17 -0
  28. data/db/migrate/20110118015034_create_slugs.rb +18 -0
  29. data/db/migrate/20110118023300_add_cached_slug_to_blog_posts.rb +10 -0
  30. data/db/migrate/20110120172202_add_meta_description_to_blog_posts.rb +15 -0
  31. data/db/migrate/20110415180204_rename_to_k3cms_blog_posts.rb +9 -0
  32. data/image_source/famfamfam_silk_icons/information.png +0 -0
  33. data/image_source/famfamfam_silk_icons/page_add.png +0 -0
  34. data/image_source/famfamfam_silk_icons/page_delete.png +0 -0
  35. data/image_source/famfamfam_silk_icons/page_white_add.png +0 -0
  36. data/image_source/famfamfam_silk_icons/text_list_bullets.png +0 -0
  37. data/image_source/icons.xcf +0 -0
  38. data/k3cms_blog.gemspec +37 -0
  39. data/lib/form_tag_helper.rb +3 -0
  40. data/lib/k3cms/blog/railtie.rb +67 -0
  41. data/lib/k3cms/blog/version.rb +5 -0
  42. data/lib/k3cms_blog.rb +8 -0
  43. data/lib/tasks/tasks.rake +17 -0
  44. data/public/images/k3cms/blog/icons.png +0 -0
  45. data/public/images/k3cms/blog/new.png +0 -0
  46. data/public/javascripts/k3cms/blog.js +13 -0
  47. data/public/stylesheets/k3cms/blog.css +53 -0
  48. data/spec/connection_and_schema.rb +12 -0
  49. data/spec/models/blog_post_spec.rb +254 -0
  50. data/spec/spec_helper.rb +49 -0
  51. 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
@@ -0,0 +1,9 @@
1
+ class RenameToK3cmsBlogPosts < ActiveRecord::Migration
2
+ def self.up
3
+ rename_table :k3_blog_blog_posts, :k3cms_blog_blog_posts
4
+ end
5
+
6
+ def self.down
7
+ rename_table :k3cms_blog_blog_posts, :k3_blog_blog_posts
8
+ end
9
+ end
Binary file
@@ -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,3 @@
1
+ def email_field_tag(name, value = nil, options = {})
2
+ text_field_tag(name, value, options.stringify_keys.update("type" => "email"))
3
+ 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
@@ -0,0 +1,5 @@
1
+ module K3cms
2
+ module Blog
3
+ Version = "0.1.0"
4
+ end
5
+ end
@@ -0,0 +1,8 @@
1
+ $:.unshift File.join(File.dirname(__FILE__), '..') # so we can require 'app/models/...'
2
+
3
+ require 'k3cms/blog/railtie' if defined?(Rails)
4
+
5
+ module K3cms
6
+ module Blog
7
+ end
8
+ end
@@ -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
@@ -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,12 @@
1
+ require 'active_record'
2
+
3
+ ActiveRecord::Base.establish_connection({
4
+ :database => ":memory:",
5
+ :adapter => 'sqlite3',
6
+ :timeout => 500
7
+ })
8
+
9
+ ActiveRecord::Schema.define do
10
+ end
11
+
12
+ ActiveRecord::Migrator.migrate('db/migrate')
@@ -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