rails_blog_engine 0.0.1 → 0.0.2
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/.gitignore +12 -0
- data/.rspec +1 -0
- data/Gemfile +24 -0
- data/Guardfile +21 -0
- data/Procfile +1 -0
- data/TODO.txt +31 -0
- data/app/assets/images/rails_blog_engine/.gitkeep +0 -0
- data/app/controllers/rails_blog_engine/comments_controller.rb +1 -1
- data/app/controllers/rails_blog_engine/posts_controller.rb +1 -1
- data/lib/rails_blog_engine.rb +2 -0
- data/lib/rails_blog_engine/version.rb +1 -1
- data/rails_blog_engine.gemspec +64 -0
- data/script/rails +6 -0
- data/spec/acceptance/acceptance_helper.rb +4 -0
- data/spec/acceptance/rails_blog_engine/posts_admin_spec.rb +33 -0
- data/spec/acceptance/rails_blog_engine/posts_spec.rb +74 -0
- data/spec/acceptance/rails_blog_engine/spam_filtering_spec.rb +110 -0
- data/spec/acceptance/support/helpers.rb +18 -0
- data/spec/acceptance/support/paths.rb +5 -0
- data/spec/controllers/rails_blog_engine/comments_controller_spec.rb +22 -0
- data/spec/controllers/rails_blog_engine/posts_controller_spec.rb +81 -0
- data/spec/dummy/Rakefile +7 -0
- data/spec/dummy/app/assets/javascripts/application.js +10 -0
- data/spec/dummy/app/assets/stylesheets/application.css +8 -0
- data/spec/dummy/app/controllers/application_controller.rb +3 -0
- data/spec/dummy/app/controllers/home_controller.rb +4 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/mailers/.gitkeep +0 -0
- data/spec/dummy/app/models/.gitkeep +0 -0
- data/spec/dummy/app/models/ability.rb +11 -0
- data/spec/dummy/app/models/user.rb +9 -0
- data/spec/dummy/app/views/home/index.html.haml +2 -0
- data/spec/dummy/app/views/layouts/application.html.erb +15 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/config/application.rb +54 -0
- data/spec/dummy/config/boot.rb +10 -0
- data/spec/dummy/config/database.yml +25 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +30 -0
- data/spec/dummy/config/environments/production.rb +60 -0
- data/spec/dummy/config/environments/test.rb +42 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/devise.rb +211 -0
- data/spec/dummy/config/initializers/inflections.rb +10 -0
- data/spec/dummy/config/initializers/mime_types.rb +5 -0
- data/spec/dummy/config/initializers/rails_blog_engine.rb +13 -0
- data/spec/dummy/config/initializers/secret_token.rb +7 -0
- data/spec/dummy/config/initializers/session_store.rb +8 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/devise.en.yml +58 -0
- data/spec/dummy/config/locales/en.yml +5 -0
- data/spec/dummy/config/routes.rb +6 -0
- data/spec/dummy/db/migrate/20110913113004_devise_create_users.rb +28 -0
- data/spec/dummy/db/schema.rb +67 -0
- data/spec/dummy/lib/assets/.gitkeep +0 -0
- data/spec/dummy/log/.gitkeep +0 -0
- data/spec/dummy/public/404.html +26 -0
- data/spec/dummy/public/422.html +26 -0
- data/spec/dummy/public/500.html +26 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/script/rails +6 -0
- data/spec/helpers/rails_blog_engine/application_helper_spec.rb +56 -0
- data/spec/helpers/rails_blog_engine/comments_helper_spec.rb +14 -0
- data/spec/helpers/rails_blog_engine/posts_helper_spec.rb +14 -0
- data/spec/lib/generators/rails_blog_engine/install_generator_spec.rb +78 -0
- data/spec/lib/rails_blog_engine/filters/base_spec.rb +13 -0
- data/spec/lib/rails_blog_engine/filters/code_spec.rb +16 -0
- data/spec/lib/rails_blog_engine/filters_spec.rb +58 -0
- data/spec/models/rails_blog_engine/comment_spec.rb +84 -0
- data/spec/models/rails_blog_engine/post_spec.rb +121 -0
- data/spec/spec_helper.rb +36 -0
- data/spec/support/blueprints.rb +25 -0
- data/spec/support/javascript.rb +27 -0
- data/spec/support/vcr.rb +8 -0
- data/spec/vcr_cassettes/rakismet-ham.yml +30 -0
- data/spec/vcr_cassettes/rakismet-spam.yml +30 -0
- data/spec/vcr_cassettes/rakismet-train-as-ham.yml +32 -0
- data/spec/vcr_cassettes/rakismet-train-as-spam.yml +32 -0
- metadata +175 -101
File without changes
|
File without changes
|
@@ -0,0 +1,26 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>The page you were looking for doesn't exist (404)</title>
|
5
|
+
<style type="text/css">
|
6
|
+
body { background-color: #fff; color: #666; text-align: center; font-family: arial, sans-serif; }
|
7
|
+
div.dialog {
|
8
|
+
width: 25em;
|
9
|
+
padding: 0 4em;
|
10
|
+
margin: 4em auto 0 auto;
|
11
|
+
border: 1px solid #ccc;
|
12
|
+
border-right-color: #999;
|
13
|
+
border-bottom-color: #999;
|
14
|
+
}
|
15
|
+
h1 { font-size: 100%; color: #f00; line-height: 1.5em; }
|
16
|
+
</style>
|
17
|
+
</head>
|
18
|
+
|
19
|
+
<body>
|
20
|
+
<!-- This file lives in public/404.html -->
|
21
|
+
<div class="dialog">
|
22
|
+
<h1>The page you were looking for doesn't exist.</h1>
|
23
|
+
<p>You may have mistyped the address or the page may have moved.</p>
|
24
|
+
</div>
|
25
|
+
</body>
|
26
|
+
</html>
|
@@ -0,0 +1,26 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>The change you wanted was rejected (422)</title>
|
5
|
+
<style type="text/css">
|
6
|
+
body { background-color: #fff; color: #666; text-align: center; font-family: arial, sans-serif; }
|
7
|
+
div.dialog {
|
8
|
+
width: 25em;
|
9
|
+
padding: 0 4em;
|
10
|
+
margin: 4em auto 0 auto;
|
11
|
+
border: 1px solid #ccc;
|
12
|
+
border-right-color: #999;
|
13
|
+
border-bottom-color: #999;
|
14
|
+
}
|
15
|
+
h1 { font-size: 100%; color: #f00; line-height: 1.5em; }
|
16
|
+
</style>
|
17
|
+
</head>
|
18
|
+
|
19
|
+
<body>
|
20
|
+
<!-- This file lives in public/422.html -->
|
21
|
+
<div class="dialog">
|
22
|
+
<h1>The change you wanted was rejected.</h1>
|
23
|
+
<p>Maybe you tried to change something you didn't have access to.</p>
|
24
|
+
</div>
|
25
|
+
</body>
|
26
|
+
</html>
|
@@ -0,0 +1,26 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>We're sorry, but something went wrong (500)</title>
|
5
|
+
<style type="text/css">
|
6
|
+
body { background-color: #fff; color: #666; text-align: center; font-family: arial, sans-serif; }
|
7
|
+
div.dialog {
|
8
|
+
width: 25em;
|
9
|
+
padding: 0 4em;
|
10
|
+
margin: 4em auto 0 auto;
|
11
|
+
border: 1px solid #ccc;
|
12
|
+
border-right-color: #999;
|
13
|
+
border-bottom-color: #999;
|
14
|
+
}
|
15
|
+
h1 { font-size: 100%; color: #f00; line-height: 1.5em; }
|
16
|
+
</style>
|
17
|
+
</head>
|
18
|
+
|
19
|
+
<body>
|
20
|
+
<!-- This file lives in public/500.html -->
|
21
|
+
<div class="dialog">
|
22
|
+
<h1>We're sorry, but something went wrong.</h1>
|
23
|
+
<p>We've been notified about this issue and we'll take a look at it shortly.</p>
|
24
|
+
</div>
|
25
|
+
</body>
|
26
|
+
</html>
|
File without changes
|
@@ -0,0 +1,6 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
|
3
|
+
|
4
|
+
APP_PATH = File.expand_path('../../config/application', __FILE__)
|
5
|
+
require File.expand_path('../../config/boot', __FILE__)
|
6
|
+
require 'rails/commands'
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe RailsBlogEngine::ApplicationHelper do
|
4
|
+
class SillyFilter < RailsBlogEngine::Filters::Base
|
5
|
+
register_filter :silly
|
6
|
+
|
7
|
+
def process(text, options)
|
8
|
+
"Whee"
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
describe ".markdown" do
|
13
|
+
it "converts markdown text to HTML" do
|
14
|
+
helper.markdown("_foo_ bar").should match(/<em>foo<\/em> bar/)
|
15
|
+
end
|
16
|
+
|
17
|
+
it "does not pass scripts" do
|
18
|
+
helper.markdown("<script>foo</script>").
|
19
|
+
should_not match(/script/)
|
20
|
+
end
|
21
|
+
|
22
|
+
it "applies filters" do
|
23
|
+
helper.markdown("<filter:silly/>").should match(/Whee/)
|
24
|
+
end
|
25
|
+
|
26
|
+
context "for trusted users" do
|
27
|
+
it "allows images" do
|
28
|
+
helper.markdown("<img src='foo.png'>", :trusted? => true).
|
29
|
+
should match(/<img/)
|
30
|
+
end
|
31
|
+
|
32
|
+
it "does not add nofollow to links" do
|
33
|
+
helper.markdown("<a href='foo.html'>", :trusted? => true).
|
34
|
+
should_not match(/nofollow/)
|
35
|
+
end
|
36
|
+
|
37
|
+
it "allows code highlighting" do
|
38
|
+
formatted = helper.markdown(<<EOD, :trusted? => true)
|
39
|
+
<div class='foo'><span class='bar'></span></div>
|
40
|
+
EOD
|
41
|
+
formatted.should match(/foo/)
|
42
|
+
formatted.should match(/bar/)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
context "for untrusted users" do
|
47
|
+
it "does not allow images" do
|
48
|
+
helper.markdown("<img src='foo.png'>").should_not match(/<img/)
|
49
|
+
end
|
50
|
+
|
51
|
+
it "adds nofollow to links" do
|
52
|
+
helper.markdown("<a href='foo.html'>").should match(/nofollow/)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
# Specs in this file have access to a helper object that includes
|
4
|
+
# the CommentsHelper. For example:
|
5
|
+
#
|
6
|
+
# describe CommentsHelper do
|
7
|
+
# describe "string concat" do
|
8
|
+
# it "concats two strings with spaces" do
|
9
|
+
# helper.concat_strings("this","that").should == "this that"
|
10
|
+
# end
|
11
|
+
# end
|
12
|
+
# end
|
13
|
+
describe RailsBlogEngine::CommentsHelper do
|
14
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
# Specs in this file have access to a helper object that includes
|
4
|
+
# the PostsHelper. For example:
|
5
|
+
#
|
6
|
+
# describe PostsHelper do
|
7
|
+
# describe "string concat" do
|
8
|
+
# it "concats two strings with spaces" do
|
9
|
+
# helper.concat_strings("this","that").should == "this that"
|
10
|
+
# end
|
11
|
+
# end
|
12
|
+
# end
|
13
|
+
describe RailsBlogEngine::PostsHelper do
|
14
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
require "spec_helper.rb"
|
2
|
+
require "generator_spec/test_case"
|
3
|
+
require "generators/rails_blog_engine/install/install_generator"
|
4
|
+
|
5
|
+
describe RailsBlogEngine::InstallGenerator do
|
6
|
+
include GeneratorSpec::TestCase
|
7
|
+
destination File.expand_path("../../../../tmp", __FILE__)
|
8
|
+
|
9
|
+
# Create a file with the specified contents in our fake application tree.
|
10
|
+
# This is faster than generating a real application every time we test.
|
11
|
+
def create_file(path, contents)
|
12
|
+
full_path = ::File.join(destination_root, path)
|
13
|
+
mkdir_p(::File.dirname(full_path))
|
14
|
+
::File.open(full_path, 'w') {|f| f.write(contents) }
|
15
|
+
end
|
16
|
+
|
17
|
+
def prepare_destination
|
18
|
+
super
|
19
|
+
create_file('config/routes.rb', <<EOD)
|
20
|
+
Dummy::Application.routes.draw do
|
21
|
+
end
|
22
|
+
EOD
|
23
|
+
create_file('app/assets/stylesheets/application.css', <<EOD)
|
24
|
+
/*
|
25
|
+
*= require_self
|
26
|
+
*= require_tree .
|
27
|
+
*/
|
28
|
+
EOD
|
29
|
+
create_file('app/assets/javascripts/application.js', <<EOD)
|
30
|
+
//= require jquery
|
31
|
+
//= require jquery_ujs
|
32
|
+
//= require_tree .
|
33
|
+
EOD
|
34
|
+
end
|
35
|
+
|
36
|
+
before do
|
37
|
+
prepare_destination
|
38
|
+
run_generator
|
39
|
+
end
|
40
|
+
|
41
|
+
it "generates the expected files" do
|
42
|
+
destination_root.should have_structure {
|
43
|
+
directory "app" do
|
44
|
+
directory "assets" do
|
45
|
+
directory "javascripts" do
|
46
|
+
file "application.js" do
|
47
|
+
contains "//= require rails_blog_engine"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
directory "stylesheets" do
|
51
|
+
file "application.css" do
|
52
|
+
contains " *= require rails_blog_engine"
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
directory "config" do
|
58
|
+
file "routes.rb" do
|
59
|
+
contains 'mount RailsBlogEngine::Engine => "/blog"'
|
60
|
+
end
|
61
|
+
directory "initializers" do
|
62
|
+
file "rails_blog_engine.rb"
|
63
|
+
end
|
64
|
+
directory "locales" do
|
65
|
+
file "rails_blog_engine.en.yml"
|
66
|
+
end
|
67
|
+
end
|
68
|
+
directory "db" do
|
69
|
+
directory "migrate" do
|
70
|
+
# We don't need to test every single one of these--just make sure
|
71
|
+
# a couple are copied over, and the rest should be OK.
|
72
|
+
file "20110912153527_create_rails_blog_engine_posts.rb"
|
73
|
+
file "20110913190319_add_fields_to_rails_blog_engine_post.rb"
|
74
|
+
end
|
75
|
+
end
|
76
|
+
}
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe RailsBlogEngine::Filters::Base do
|
4
|
+
let(:filter) { RailsBlogEngine::Filters::Base.new }
|
5
|
+
|
6
|
+
describe "#process" do
|
7
|
+
it "raises an error if not overridden" do
|
8
|
+
lambda do
|
9
|
+
filter.process("text", {})
|
10
|
+
end.should raise_error(/override/)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe RailsBlogEngine::Filters::Code do
|
4
|
+
let(:filter) { RailsBlogEngine::Filters::Code.new }
|
5
|
+
|
6
|
+
describe ".process" do
|
7
|
+
it "applies syntax highlighting to code blocks" do
|
8
|
+
output = filter.process(<<END_OF_CODE, :lang => 'ruby')
|
9
|
+
def foo
|
10
|
+
42
|
11
|
+
end
|
12
|
+
END_OF_CODE
|
13
|
+
output.should match(/foo/)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe RailsBlogEngine::Filters do
|
4
|
+
|
5
|
+
# A sample filter.
|
6
|
+
class HelloFilter < RailsBlogEngine::Filters::Base
|
7
|
+
register_filter :hello
|
8
|
+
|
9
|
+
def process(text, options)
|
10
|
+
attrs =
|
11
|
+
if options[:class] then " class=\"#{options[:class]}\"" else "" end
|
12
|
+
name = if text then ", #{text}" else "" end
|
13
|
+
"<p#{attrs}>Hello#{name}!</p>"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe ".find" do
|
18
|
+
it "returns the filter registered for a name" do
|
19
|
+
RailsBlogEngine::Filters.find(:hello).should be_kind_of(HelloFilter)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe ".apply_all_to" do
|
24
|
+
%w(filter macro typo).each do |tag|
|
25
|
+
it "applies registered filters to empty '#{tag}' tags" do
|
26
|
+
RailsBlogEngine::Filters.apply_all_to(<<"END_OF_INPUT").should == <<END_OF_OUTPUT
|
27
|
+
<#{tag}:hello/>
|
28
|
+
<#{tag}:hello class="example" />
|
29
|
+
END_OF_INPUT
|
30
|
+
<p>Hello!</p>
|
31
|
+
<p class="example">Hello!</p>
|
32
|
+
END_OF_OUTPUT
|
33
|
+
end
|
34
|
+
|
35
|
+
it "applies registered filters to '#{tag}' tags with content" do
|
36
|
+
RailsBlogEngine::Filters.apply_all_to(<<"END_OF_INPUT").should == <<END_OF_OUTPUT
|
37
|
+
<#{tag}:hello>Judy</#{tag}:hello>
|
38
|
+
<#{tag}:hello class='example' extra="" >Mike
|
39
|
+
Smith</#{tag}:hello>
|
40
|
+
END_OF_INPUT
|
41
|
+
<p>Hello, Judy!</p>
|
42
|
+
<p class="example">Hello, Mike
|
43
|
+
Smith!</p>
|
44
|
+
END_OF_OUTPUT
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
it "reports errors inline" do
|
49
|
+
RailsBlogEngine::Filters.apply_all_to(<<END_OF_INPUT).should == <<END_OF_OUTPUT
|
50
|
+
<filter:invalid/>
|
51
|
+
<filter:hello class= >Mike</filter:hello>
|
52
|
+
END_OF_INPUT
|
53
|
+
<p><strong>Text filter not installed: invalid</strong></p>
|
54
|
+
<p><strong>Can't parse filter arguments: {{ class= }}</strong></p>
|
55
|
+
END_OF_OUTPUT
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe RailsBlogEngine::Comment do
|
4
|
+
it { should belong_to(:post) }
|
5
|
+
|
6
|
+
it { should_not allow_value('').for(:author_byline) }
|
7
|
+
it { should_not allow_value('').for(:body) }
|
8
|
+
|
9
|
+
describe ".visible" do
|
10
|
+
it "includes unfiltered and ham messages, but not spam" do
|
11
|
+
@unfiltered = RailsBlogEngine::Comment.make!
|
12
|
+
@ham = RailsBlogEngine::Comment.make!(:state => 'filtered_as_ham')
|
13
|
+
@ham2 = RailsBlogEngine::Comment.make!(:state => 'marked_as_ham')
|
14
|
+
@spam = RailsBlogEngine::Comment.make!(:state => 'filtered_as_spam')
|
15
|
+
@spam2 = RailsBlogEngine::Comment.make!(:state => 'marked_as_spam')
|
16
|
+
RailsBlogEngine::Comment.visible.should include(@unfiltered)
|
17
|
+
RailsBlogEngine::Comment.visible.should include(@ham)
|
18
|
+
RailsBlogEngine::Comment.visible.should include(@ham2)
|
19
|
+
RailsBlogEngine::Comment.visible.should_not include(@spam)
|
20
|
+
RailsBlogEngine::Comment.visible.should_not include(@spam2)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe "#state" do
|
25
|
+
subject { RailsBlogEngine::Comment.make! }
|
26
|
+
|
27
|
+
def enable_spam_filter
|
28
|
+
Rakismet.key = "fakekey"
|
29
|
+
end
|
30
|
+
|
31
|
+
def disable_spam_filter
|
32
|
+
Rakismet.key = nil
|
33
|
+
end
|
34
|
+
|
35
|
+
it "begins in state unfiltered" do
|
36
|
+
subject.should be_unfiltered
|
37
|
+
end
|
38
|
+
|
39
|
+
it "transitions to filtered_as_ham if rakismet likes it" do
|
40
|
+
enable_spam_filter
|
41
|
+
subject.stub(:spam?) { false }
|
42
|
+
subject.run_spam_filter
|
43
|
+
subject.should be_filtered_as_ham
|
44
|
+
end
|
45
|
+
|
46
|
+
it "transitions to filtered_as_spam if rakismet doesn't like it" do
|
47
|
+
enable_spam_filter
|
48
|
+
subject.stub(:spam?) { true }
|
49
|
+
subject.run_spam_filter
|
50
|
+
subject.should be_filtered_as_spam
|
51
|
+
end
|
52
|
+
|
53
|
+
it "remains unfiltered if the rakismet is not configured" do
|
54
|
+
disable_spam_filter
|
55
|
+
subject.run_spam_filter
|
56
|
+
subject.should be_unfiltered
|
57
|
+
end
|
58
|
+
|
59
|
+
it "supports manually marking a filtered post as ham" do
|
60
|
+
enable_spam_filter
|
61
|
+
subject.filter_as_spam
|
62
|
+
subject.can_mark_as_ham?.should == true
|
63
|
+
subject.should_receive(:ham!)
|
64
|
+
subject.mark_as_ham
|
65
|
+
subject.should be_marked_as_ham
|
66
|
+
end
|
67
|
+
|
68
|
+
it "supports manually marking a filtered post as spam" do
|
69
|
+
enable_spam_filter
|
70
|
+
subject.filter_as_ham
|
71
|
+
subject.can_mark_as_spam?.should == true
|
72
|
+
subject.should_receive(:spam!)
|
73
|
+
subject.mark_as_spam
|
74
|
+
subject.should be_marked_as_spam
|
75
|
+
end
|
76
|
+
|
77
|
+
it "supports manually marking an unfiltered post as spam" do
|
78
|
+
disable_spam_filter
|
79
|
+
subject.can_mark_as_spam?.should == true
|
80
|
+
subject.mark_as_spam
|
81
|
+
subject.should be_marked_as_spam
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,121 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe RailsBlogEngine::Post do
|
4
|
+
Post = RailsBlogEngine::Post
|
5
|
+
|
6
|
+
it { should have_many(:comments) }
|
7
|
+
|
8
|
+
describe "validations" do
|
9
|
+
before { Post.make! }
|
10
|
+
|
11
|
+
it { should allow_value("Title").for(:title) }
|
12
|
+
it { should_not allow_value("").for(:title) }
|
13
|
+
|
14
|
+
it { should allow_value("Body").for(:body) }
|
15
|
+
it { should_not allow_value("").for(:body) }
|
16
|
+
|
17
|
+
%w(unpublished published).each do |state|
|
18
|
+
it { should allow_value(state).for(:state) }
|
19
|
+
end
|
20
|
+
it { should_not allow_value("invalid").for(:state) }
|
21
|
+
it { should validate_presence_of(:state) }
|
22
|
+
|
23
|
+
it { should allow_value("abc-def").for(:permalink) }
|
24
|
+
it { should validate_presence_of(:permalink) }
|
25
|
+
it { should validate_uniqueness_of(:permalink) }
|
26
|
+
|
27
|
+
it { should validate_presence_of(:author) }
|
28
|
+
end
|
29
|
+
|
30
|
+
describe ".recently_published" do
|
31
|
+
before do
|
32
|
+
base = Time.now
|
33
|
+
@posts = (0...3).map do |i|
|
34
|
+
Post.make!(:published, :published_at => base + i.seconds)
|
35
|
+
end
|
36
|
+
@posts[1].published_at = base + 10.seconds
|
37
|
+
@posts[1].save!
|
38
|
+
@unpublished = Post.make!
|
39
|
+
end
|
40
|
+
|
41
|
+
it "does not include unpublished posts" do
|
42
|
+
Post.recently_published.should_not include(@unpublished)
|
43
|
+
end
|
44
|
+
|
45
|
+
it "returns in order of descending published_at" do
|
46
|
+
Post.recently_published.should == [@posts[1], @posts[2], @posts[0]]
|
47
|
+
end
|
48
|
+
|
49
|
+
it "excludes posts which have been explicitly unpublished" do
|
50
|
+
@posts[1].unpublish!
|
51
|
+
Post.recently_published.should == [@posts[2], @posts[0]]
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe "state machine" do
|
56
|
+
let(:post) { Post.make }
|
57
|
+
|
58
|
+
it "begins as unpublished" do
|
59
|
+
post.should be_unpublished
|
60
|
+
end
|
61
|
+
|
62
|
+
it "can be published and unpublished" do
|
63
|
+
post.publish!
|
64
|
+
post.should be_published
|
65
|
+
|
66
|
+
lambda do
|
67
|
+
post.publish!
|
68
|
+
end.should raise_error(StateMachine::InvalidTransition)
|
69
|
+
|
70
|
+
post.unpublish!
|
71
|
+
post.should be_unpublished
|
72
|
+
|
73
|
+
lambda do
|
74
|
+
post.unpublish!
|
75
|
+
end.should raise_error(StateMachine::InvalidTransition)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
describe "published_at" do
|
80
|
+
it "is set automatically when post is first published" do
|
81
|
+
first_publication = Time.utc(1980, 1, 1)
|
82
|
+
second_publication = Time.utc(1980, 1, 2)
|
83
|
+
|
84
|
+
post = Post.make
|
85
|
+
post.published_at.should be_nil
|
86
|
+
|
87
|
+
Time.stub(:now) { first_publication }
|
88
|
+
post.publish
|
89
|
+
post.published_at.should == first_publication
|
90
|
+
|
91
|
+
Time.stub(:now) { second_publication }
|
92
|
+
post.publish
|
93
|
+
post.published_at.should == first_publication
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
describe "#author_byline" do
|
98
|
+
it "is set from the #author method before save" do
|
99
|
+
author = User.make(:email => 'jane@example.com')
|
100
|
+
Post.make!(:author => author).author_byline.
|
101
|
+
should == 'jane'
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
describe ".author_byline" do
|
106
|
+
it "returns .byline if present" do
|
107
|
+
author = mock('author', :byline => 'Jane Smith')
|
108
|
+
Post.author_byline(author).should == 'Jane Smith'
|
109
|
+
end
|
110
|
+
|
111
|
+
it "returns .email without domain if present" do
|
112
|
+
author = mock('author', :email => 'jane@example.com')
|
113
|
+
Post.author_byline(author).should == 'jane'
|
114
|
+
end
|
115
|
+
|
116
|
+
it "returns 'unknown' otherwise" do
|
117
|
+
author = mock('author')
|
118
|
+
Post.author_byline(author).should == 'unknown'
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|