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.
Files changed (79) hide show
  1. data/.gitignore +12 -0
  2. data/.rspec +1 -0
  3. data/Gemfile +24 -0
  4. data/Guardfile +21 -0
  5. data/Procfile +1 -0
  6. data/TODO.txt +31 -0
  7. data/app/assets/images/rails_blog_engine/.gitkeep +0 -0
  8. data/app/controllers/rails_blog_engine/comments_controller.rb +1 -1
  9. data/app/controllers/rails_blog_engine/posts_controller.rb +1 -1
  10. data/lib/rails_blog_engine.rb +2 -0
  11. data/lib/rails_blog_engine/version.rb +1 -1
  12. data/rails_blog_engine.gemspec +64 -0
  13. data/script/rails +6 -0
  14. data/spec/acceptance/acceptance_helper.rb +4 -0
  15. data/spec/acceptance/rails_blog_engine/posts_admin_spec.rb +33 -0
  16. data/spec/acceptance/rails_blog_engine/posts_spec.rb +74 -0
  17. data/spec/acceptance/rails_blog_engine/spam_filtering_spec.rb +110 -0
  18. data/spec/acceptance/support/helpers.rb +18 -0
  19. data/spec/acceptance/support/paths.rb +5 -0
  20. data/spec/controllers/rails_blog_engine/comments_controller_spec.rb +22 -0
  21. data/spec/controllers/rails_blog_engine/posts_controller_spec.rb +81 -0
  22. data/spec/dummy/Rakefile +7 -0
  23. data/spec/dummy/app/assets/javascripts/application.js +10 -0
  24. data/spec/dummy/app/assets/stylesheets/application.css +8 -0
  25. data/spec/dummy/app/controllers/application_controller.rb +3 -0
  26. data/spec/dummy/app/controllers/home_controller.rb +4 -0
  27. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  28. data/spec/dummy/app/mailers/.gitkeep +0 -0
  29. data/spec/dummy/app/models/.gitkeep +0 -0
  30. data/spec/dummy/app/models/ability.rb +11 -0
  31. data/spec/dummy/app/models/user.rb +9 -0
  32. data/spec/dummy/app/views/home/index.html.haml +2 -0
  33. data/spec/dummy/app/views/layouts/application.html.erb +15 -0
  34. data/spec/dummy/config.ru +4 -0
  35. data/spec/dummy/config/application.rb +54 -0
  36. data/spec/dummy/config/boot.rb +10 -0
  37. data/spec/dummy/config/database.yml +25 -0
  38. data/spec/dummy/config/environment.rb +5 -0
  39. data/spec/dummy/config/environments/development.rb +30 -0
  40. data/spec/dummy/config/environments/production.rb +60 -0
  41. data/spec/dummy/config/environments/test.rb +42 -0
  42. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  43. data/spec/dummy/config/initializers/devise.rb +211 -0
  44. data/spec/dummy/config/initializers/inflections.rb +10 -0
  45. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  46. data/spec/dummy/config/initializers/rails_blog_engine.rb +13 -0
  47. data/spec/dummy/config/initializers/secret_token.rb +7 -0
  48. data/spec/dummy/config/initializers/session_store.rb +8 -0
  49. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  50. data/spec/dummy/config/locales/devise.en.yml +58 -0
  51. data/spec/dummy/config/locales/en.yml +5 -0
  52. data/spec/dummy/config/routes.rb +6 -0
  53. data/spec/dummy/db/migrate/20110913113004_devise_create_users.rb +28 -0
  54. data/spec/dummy/db/schema.rb +67 -0
  55. data/spec/dummy/lib/assets/.gitkeep +0 -0
  56. data/spec/dummy/log/.gitkeep +0 -0
  57. data/spec/dummy/public/404.html +26 -0
  58. data/spec/dummy/public/422.html +26 -0
  59. data/spec/dummy/public/500.html +26 -0
  60. data/spec/dummy/public/favicon.ico +0 -0
  61. data/spec/dummy/script/rails +6 -0
  62. data/spec/helpers/rails_blog_engine/application_helper_spec.rb +56 -0
  63. data/spec/helpers/rails_blog_engine/comments_helper_spec.rb +14 -0
  64. data/spec/helpers/rails_blog_engine/posts_helper_spec.rb +14 -0
  65. data/spec/lib/generators/rails_blog_engine/install_generator_spec.rb +78 -0
  66. data/spec/lib/rails_blog_engine/filters/base_spec.rb +13 -0
  67. data/spec/lib/rails_blog_engine/filters/code_spec.rb +16 -0
  68. data/spec/lib/rails_blog_engine/filters_spec.rb +58 -0
  69. data/spec/models/rails_blog_engine/comment_spec.rb +84 -0
  70. data/spec/models/rails_blog_engine/post_spec.rb +121 -0
  71. data/spec/spec_helper.rb +36 -0
  72. data/spec/support/blueprints.rb +25 -0
  73. data/spec/support/javascript.rb +27 -0
  74. data/spec/support/vcr.rb +8 -0
  75. data/spec/vcr_cassettes/rakismet-ham.yml +30 -0
  76. data/spec/vcr_cassettes/rakismet-spam.yml +30 -0
  77. data/spec/vcr_cassettes/rakismet-train-as-ham.yml +32 -0
  78. data/spec/vcr_cassettes/rakismet-train-as-spam.yml +32 -0
  79. metadata +175 -101
data/.gitignore ADDED
@@ -0,0 +1,12 @@
1
+ /Gemfile.lock
2
+ /.bundle/
3
+ /.sass-cache/
4
+ /log/*.log
5
+ /pkg/
6
+ /spec/dummy/db/*.sqlite3
7
+ /spec/dummy/log/*.log
8
+ /spec/dummy/tmp/
9
+ /spec/dummy/.sass-cache/
10
+ /spec/tmp/
11
+ /.env
12
+ /*.gem
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --colour
data/Gemfile ADDED
@@ -0,0 +1,24 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Declare your gem's dependencies in rails_blog_engine.gemspec.
4
+ # Bundler will treat runtime dependencies like base dependencies, and
5
+ # development dependencies will be added by default to the :development group.
6
+ gemspec
7
+
8
+ # Declare any dependencies that are still in development here instead of in
9
+ # your gemspec. These might include edge Rails or gems from your path or
10
+ # Git. Remember to move these dependencies to your gemspec before releasing
11
+ # your gem to rubygems.org.
12
+
13
+ # To use debugger
14
+ # gem 'ruby-debug19', :require => 'ruby-debug'
15
+
16
+ group :development do
17
+ # We need a version which doesn't create objects in separate threads,
18
+ # cache them, or do anything else that breaks database-cleaning
19
+ # transactions in Steak.
20
+ gem 'machinist', :git => 'https://github.com/notahat/machinist.git'
21
+
22
+ # This is an optional runtime depedency.
23
+ gem 'pygments', :git => 'https://github.com/nathany/pygments-gem.git'
24
+ end
data/Guardfile ADDED
@@ -0,0 +1,21 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ guard 'rspec', :version => 2 do
5
+ watch(%r{^spec/.+_spec\.rb$})
6
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
7
+ watch('spec/spec_helper.rb') { "spec" }
8
+
9
+ # Rails example
10
+ watch(%r{^spec/.+_spec\.rb$})
11
+ watch(%r{^app/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
12
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
13
+ watch(%r{^app/controllers/(.+)_(controller)\.rb$}) { |m| ["spec/routing/#{m[1]}_routing_spec.rb", "spec/#{m[2]}s/#{m[1]}_#{m[2]}_spec.rb", "spec/acceptance/#{m[1]}_spec.rb"] }
14
+ watch(%r{^spec/support/(.+)\.rb$}) { "spec" }
15
+ watch('spec/spec_helper.rb') { "spec" }
16
+ watch('config/routes.rb') { "spec/routing" }
17
+ watch('app/controllers/application_controller.rb') { "spec/controllers" }
18
+ # Capybara request specs
19
+ watch(%r{^app/views/(.+)/.*\.(erb|haml|builder)$}) { |m| ["spec/controllers/#{m[1]}_controller_spec.rb", "spec/requests/#{m[1]}_spec.rb"] }
20
+ end
21
+
data/Procfile ADDED
@@ -0,0 +1 @@
1
+ web: bundle exec rails server -p $PORT
data/TODO.txt ADDED
@@ -0,0 +1,31 @@
1
+ Before public release
2
+
3
+ / Spam filtering for comments: rakismet
4
+ / Moderation by administrators
5
+ / Secure comment fields using attr_accessible
6
+ / Secure HTML in comments
7
+ X Table changes - Not going to collapse migrations, so there's no rush.
8
+ X Comment author_id polymorphic
9
+ X Comment state index
10
+ X Collapse migrations into 1 giant migration
11
+ / Quick refactoring pass
12
+ , Integrate into Kidd Software site
13
+
14
+ Needed for 3rd-party use
15
+
16
+ Generators
17
+ rails_blog_engine:templates
18
+ rails_blog_engine:filter
19
+ Config class? Either implement or remove initializer
20
+
21
+ Needed for use as a product or company blog
22
+
23
+ Caching
24
+ Editor polish
25
+ Auto-save
26
+ Publish / Unpublish button
27
+ , SEO best practices
28
+
29
+ Needed for 1.0
30
+
31
+ Recent articles list
File without changes
@@ -1,5 +1,5 @@
1
1
  module RailsBlogEngine
2
- class CommentsController < ApplicationController
2
+ class CommentsController < RailsBlogEngine::ApplicationController
3
3
  before_filter :load_post
4
4
 
5
5
  load_and_authorize_resource :class => "RailsBlogEngine::Comment"
@@ -1,5 +1,5 @@
1
1
  module RailsBlogEngine
2
- class PostsController < ApplicationController
2
+ class PostsController < RailsBlogEngine::ApplicationController
3
3
  before_filter :load_recently_published, :only => :index
4
4
  before_filter :load_by_permalink, :only => :show
5
5
 
@@ -15,4 +15,6 @@ require "rails_blog_engine/ability"
15
15
  require "rails_blog_engine/filters"
16
16
 
17
17
  module RailsBlogEngine
18
+ class Railtie < ::Rails::Railtie
19
+ end
18
20
  end
@@ -1,3 +1,3 @@
1
1
  module RailsBlogEngine
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
@@ -0,0 +1,64 @@
1
+ $:.push File.expand_path("../lib", __FILE__)
2
+
3
+ # Maintain your gem's version:
4
+ require "rails_blog_engine/version"
5
+
6
+ # Describe your gem and declare its dependencies:
7
+ Gem::Specification.new do |s|
8
+ s.name = "rails_blog_engine"
9
+ s.version = RailsBlogEngine::VERSION
10
+ s.authors = ["Eric Kidd"]
11
+ s.email = ["eric@kiddsoftware.com"]
12
+ s.homepage = "http://github.com/kiddsoftware/rails_blog_engine"
13
+ s.summary = "Rails 3.1 drop-in blog engine"
14
+ s.description = "Rails 3.1 drop-in blog engine for existing Rails applications"
15
+
16
+ s.files = `git ls-files`.split("\n").sort
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ # Rails 3.1.
22
+ s.add_dependency "rails", "~> 3.1.0"
23
+
24
+ # Asset pipeline. We use all the standard gems plus HAML.
25
+ s.add_dependency "jquery-rails", "~> 1.0"
26
+ s.add_dependency "sass-rails", "~> 3.1"
27
+ s.add_dependency "coffee-script", "~> 2.2"
28
+ s.add_dependency "haml", "~> 3.1"
29
+
30
+ # Pagination.
31
+ s.add_dependency "kaminari", "~> 0.12.4"
32
+
33
+ # User accounts and authentication.
34
+ s.add_dependency "cancan", "~> 1.6"
35
+
36
+ # Spam filtering.
37
+ s.add_dependency "rakismet", "~> 1.1"
38
+
39
+ # Other useful libraries.
40
+ s.add_dependency "simple_form", "~> 1.4"
41
+ s.add_dependency "state_machine", "~> 1.0.0"
42
+ s.add_dependency "rdiscount", "~> 1.6"
43
+ s.add_dependency "sanitize", "~> 2.0"
44
+
45
+ # Development-only gems.
46
+ s.add_development_dependency "sqlite3"
47
+ s.add_development_dependency "devise"
48
+ s.add_development_dependency "steak"
49
+ s.add_development_dependency "foreman"
50
+ s.add_development_dependency "capybara-webkit", "~> 0.6.1"
51
+ s.add_development_dependency "database_cleaner"
52
+ s.add_development_dependency "shoulda-matchers"
53
+ s.add_development_dependency "generator_spec"
54
+ s.add_development_dependency "vcr", ">= 2.0.0.beta2"
55
+ s.add_development_dependency "fakeweb"
56
+ #s.add_development_dependency "machinist" (see Gemfile)
57
+ #s.add_development_dependency "pygments" (see Gemfile)
58
+
59
+ # Auto-running our unit tests when things change.
60
+ s.add_development_dependency "guard-rspec"
61
+ s.add_development_dependency "rb-inotify"
62
+ s.add_development_dependency "libnotify"
63
+ s.add_development_dependency "launchy"
64
+ end
data/script/rails ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+ #!/usr/bin/env ruby
3
+ # This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
4
+
5
+ ENGINE_PATH = File.expand_path('../..', __FILE__)
6
+ load File.expand_path('../../spec/dummy/script/rails', __FILE__)
@@ -0,0 +1,4 @@
1
+ require 'spec_helper'
2
+
3
+ # Put your acceptance spec helpers inside spec/acceptance/support
4
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
@@ -0,0 +1,33 @@
1
+ require 'acceptance/acceptance_helper'
2
+
3
+ feature 'Posts admin', %q{
4
+ In order to publish information to the world
5
+ As a manager of the blog
6
+ I want to publish and manage posts
7
+ } do
8
+
9
+ background do
10
+ sign_in_as_admin
11
+ end
12
+
13
+ scenario 'Adding and editing new post', :js => true do
14
+ visit '/blog'
15
+
16
+ click_link "New Post"
17
+ fill_in 'Title', :with => 'Test Post'
18
+ fill_in 'Permalink', :with => 'test-post'
19
+ fill_in 'Body', :with => 'My post <img src="a.png">'
20
+ click_button 'Create Post'
21
+ page.should have_content("Test Post")
22
+ page.should have_content("by sue")
23
+ page.should have_content("My post")
24
+ page.should have_selector(:xpath, '//img[@src="a.png"]')
25
+
26
+ click_link "Edit"
27
+ fill_in 'Title', :with => 'New Title'
28
+ fill_in 'Body', :with => 'New Body'
29
+ click_button "Update Post"
30
+ page.should have_content('New Title')
31
+ page.should have_content('New Body')
32
+ end
33
+ end
@@ -0,0 +1,74 @@
1
+ require 'acceptance/acceptance_helper'
2
+
3
+ feature 'Posts', %q{
4
+ In order to learn intesting new things
5
+ As a site visitor
6
+ I want to read blog articles
7
+ } do
8
+
9
+ background do
10
+ published_at = Time.utc(2011, 01, 02, 03)
11
+ RailsBlogEngine::Post.make!(:title => "Test Post", :body => "_Body_ ",
12
+ :state => 'published',
13
+ :published_at => published_at,
14
+ :permalink => 'test')
15
+ end
16
+
17
+ scenario 'Viewing the index' do
18
+ visit '/blog'
19
+ page.should have_content("Test Post")
20
+ within('em') { page.should have_content("Body") }
21
+ page.should_not have_content("New Post")
22
+ end
23
+
24
+ scenario 'Navigating to a post' do
25
+ visit '/blog'
26
+ click_on "Test Post"
27
+ page.should have_content("Test Post")
28
+ page.should_not have_content("New Post")
29
+ within('em') { page.should have_content("Body") }
30
+ page.should_not have_content("Edit Post")
31
+ end
32
+
33
+ scenario 'Linking to a post directly' do
34
+ visit '/blog/2011/01/02/test'
35
+ page.should have_content("Test Post")
36
+ end
37
+
38
+ scenario 'Looking for posts on page 2' do
39
+ # Force our original post off the front page.
40
+ 5.times { RailsBlogEngine::Post.make!(:published) }
41
+
42
+ visit '/blog'
43
+ page.should_not have_content("Test Post")
44
+ click_on "Next"
45
+ page.should have_content("Test Post")
46
+ current_path.should == '/blog/page/2'
47
+ end
48
+
49
+ scenario 'Adding a comment' do
50
+ visit '/blog'
51
+ click_on 'Comment'
52
+ fill_in "Your name", :with => "Jane Doe"
53
+ fill_in "Comment", :with => "Test comment"
54
+ click_on "Post Comment"
55
+ page.should have_content("Jane Doe")
56
+ page.should have_content("Test comment")
57
+
58
+ # Change comment link text.
59
+ visit '/blog'
60
+ click_on "1 comment"
61
+ page.should have_content("Jane Doe")
62
+ end
63
+
64
+ scenario 'Validating a comment' do
65
+ visit '/blog'
66
+ click_on 'Comment'
67
+ click_on 'Post Comment'
68
+ page.should have_content("can't be blank")
69
+ fill_in "Your name", :with => "Jane Doe"
70
+ fill_in "Comment", :with => "Test comment"
71
+ click_on "Post Comment"
72
+ page.should have_content("Jane Doe")
73
+ end
74
+ end
@@ -0,0 +1,110 @@
1
+ require 'acceptance/acceptance_helper'
2
+
3
+ feature 'Spam filtering', %q{
4
+ In order to keep my site free of spam
5
+ As a manager of the blog
6
+ I want to identify spam posts and hide them automatically
7
+ } do
8
+
9
+ background do
10
+ @post = RailsBlogEngine::Post.make!(:published, :title => "Example post")
11
+ visit '/blog'
12
+ click_on "Example post"
13
+ end
14
+
15
+ def enable_spam_filter
16
+ Rakismet.key = "fakekey"
17
+ Rakismet.url = "http://www.example.com/"
18
+ end
19
+
20
+ def disable_spam_filter
21
+ Rakismet.key = nil
22
+ Rakismet.url = nil
23
+ end
24
+
25
+ def post_ham_comment
26
+ fill_in "Your name", :with => "Jane Doe"
27
+ fill_in "Comment", :with => "An interesting and legitimate post."
28
+ click_on "Post Comment"
29
+ end
30
+
31
+ def post_spam_comment
32
+ fill_in "Your name", :with => "viagra-test-123"
33
+ fill_in "Comment", :with => "Buy toner cartridges today!"
34
+ click_on "Post Comment"
35
+ end
36
+
37
+ def last_comment
38
+ @last_comment ||= RailsBlogEngine::Comment.last
39
+ end
40
+
41
+ scenario 'Posting a real comment' do
42
+ enable_spam_filter
43
+ VCR.use_cassette('rakismet-ham') { post_ham_comment }
44
+ last_comment.should be_filtered_as_ham
45
+ page.should have_content(last_comment.body)
46
+ page.should_not have_content("moderation")
47
+ end
48
+
49
+ scenario 'Posting a spam comment' do
50
+ enable_spam_filter
51
+ VCR.use_cassette('rakismet-spam') { post_spam_comment }
52
+ last_comment.should be_filtered_as_spam
53
+ page.should_not have_content(last_comment.body)
54
+ page.should have_content("moderation")
55
+ end
56
+
57
+ scenario 'Posting a comment without configuring the spam filter' do
58
+ disable_spam_filter
59
+ post_spam_comment
60
+ last_comment.should be_unfiltered
61
+ end
62
+
63
+ # Wait for the comment to have the specified state. This forces us to
64
+ # synchronize the current thread with the background thread the runs the
65
+ # webserver, which is helpful for ensuring that VCR cassettes will be
66
+ # left "in the VCR" until they've actually been used by the other thread.
67
+ def wait_for_comment_in_state(state)
68
+ Timeout.timeout(3) do
69
+ sleep 0.1 until RailsBlogEngine::Comment.where(:state => state.to_s).first
70
+ end
71
+ end
72
+
73
+ scenario 'Filtered as ham, mark as spam', :js => true do
74
+ enable_spam_filter
75
+ VCR.use_cassette('rakismet-ham', :match_requests_on => [:method]) do
76
+ post_spam_comment
77
+ wait_for_comment_in_state(:filtered_as_ham)
78
+ end
79
+ page.should have_content('viagra-test-123')
80
+ page.should have_selector('.ham')
81
+
82
+ sign_in_as_admin
83
+ VCR.use_cassette('rakismet-train-as-spam') do
84
+ click_on 'Spam'
85
+ wait_for_comment_in_state(:marked_as_spam)
86
+ end
87
+ page.should have_content('viagra-test-123')
88
+ page.should have_selector('.spam')
89
+ end
90
+
91
+ scenario 'Filtered as spam, mark as ham', :js => true do
92
+ enable_spam_filter
93
+ VCR.use_cassette('rakismet-spam', :match_requests_on => [:method]) do
94
+ post_ham_comment
95
+ wait_for_comment_in_state(:filtered_as_spam)
96
+ end
97
+ page.should_not have_content('Jane Doe')
98
+
99
+ sign_in_as_admin
100
+ page.should have_content('Jane Doe')
101
+ page.should have_selector('.spam')
102
+
103
+ VCR.use_cassette('rakismet-train-as-ham') do
104
+ click_on 'Not Spam'
105
+ wait_for_comment_in_state(:marked_as_ham)
106
+ end
107
+ page.should have_content('Jane Doe')
108
+ page.should have_selector('.ham')
109
+ end
110
+ end
@@ -0,0 +1,18 @@
1
+ module RailsBlogEngine::AcceptanceHelperMethods
2
+ # Put helper methods you need to be available in all acceptance specs here.
3
+
4
+ # In our test application, any user counts as an administrator.
5
+ def sign_in_as_admin
6
+ saved_path = current_path
7
+ visit '/users/sign_up'
8
+ fill_in 'Email', :with => "sue@example.com"
9
+ fill_in 'Password', :with => "password"
10
+ fill_in 'Password confirmation', :with => "password"
11
+ click_button 'Sign up'
12
+ visit saved_path
13
+ end
14
+ end
15
+
16
+ RSpec.configuration.include(RailsBlogEngine::AcceptanceHelperMethods,
17
+ :example_group =>
18
+ { :file_path => /spec\/acceptance/ })