enki-engine 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +13 -0
- data/.rspec +1 -0
- data/.travis.yml +3 -0
- data/Gemfile +4 -0
- data/LICENSE +284 -0
- data/README.textile +112 -0
- data/Rakefile +13 -0
- data/TODO.textile +8 -0
- data/app/assets/images/admin/flash_bg.gif +0 -0
- data/app/assets/images/admin/future_bg.png +0 -0
- data/app/assets/images/admin/gray_bg.gif +0 -0
- data/app/assets/images/admin/new_button.png +0 -0
- data/app/assets/images/admin/silver_bg.gif +0 -0
- data/app/assets/images/admin/submit_bg.gif +0 -0
- data/app/assets/images/admin/subnav_bg.gif +0 -0
- data/app/assets/images/openid_icon.png +0 -0
- data/app/assets/images/rails.png +0 -0
- data/app/assets/images/silk/arrow_undo.png +0 -0
- data/app/assets/images/silk/delete.png +0 -0
- data/app/assets/images/silk/pencil.png +0 -0
- data/app/assets/javascripts/admin/actions.js +18 -0
- data/app/assets/javascripts/admin/comments.js +3 -0
- data/app/assets/javascripts/admin/common.js +109 -0
- data/app/assets/javascripts/admin/dashboard.js +33 -0
- data/app/assets/javascripts/admin/edit-preview.js +40 -0
- data/app/assets/javascripts/admin/pages.js +1 -0
- data/app/assets/javascripts/admin/posts.js +1 -0
- data/app/assets/javascripts/admin/shortcut.js +223 -0
- data/app/assets/javascripts/admin.js +17 -0
- data/app/assets/javascripts/application.js +15 -0
- data/app/assets/javascripts/common.js +22 -0
- data/app/assets/javascripts/enki.js +13 -0
- data/app/assets/javascripts/live-comment-preview.js +36 -0
- data/app/assets/stylesheets/admin.css +304 -0
- data/app/assets/stylesheets/application.css.scss +486 -0
- data/app/assets/stylesheets/humanmsg.css +112 -0
- data/app/assets/stylesheets/login.css +65 -0
- data/app/controllers/enki/admin/base_controller.rb +15 -0
- data/app/controllers/enki/admin/comments_controller.rb +52 -0
- data/app/controllers/enki/admin/dashboard_controller.rb +12 -0
- data/app/controllers/enki/admin/health_controller.rb +20 -0
- data/app/controllers/enki/admin/pages_controller.rb +97 -0
- data/app/controllers/enki/admin/posts_controller.rb +104 -0
- data/app/controllers/enki/admin/undo_items_controller.rb +43 -0
- data/app/controllers/enki/application_controller.rb +21 -0
- data/app/controllers/enki/archives_controller.rb +7 -0
- data/app/controllers/enki/base_controller.rb +5 -0
- data/app/controllers/enki/comments_controller.rb +43 -0
- data/app/controllers/enki/pages_controller.rb +7 -0
- data/app/controllers/enki/posts_controller.rb +27 -0
- data/app/helpers/enki/admin/navigation_helper.rb +10 -0
- data/app/helpers/enki/application_helper.rb +35 -0
- data/app/helpers/enki/date_helper.rb +15 -0
- data/app/helpers/enki/form_helper.rb +7 -0
- data/app/helpers/enki/host_helper.rb +19 -0
- data/app/helpers/enki/navigation_helper.rb +23 -0
- data/app/helpers/enki/page_title_helper.rb +33 -0
- data/app/helpers/enki/posts_helper.rb +9 -0
- data/app/helpers/enki/tag_helper.rb +7 -0
- data/app/helpers/enki/url_helper.rb +25 -0
- data/app/models/enki/base/post.rb +153 -0
- data/app/models/enki/comment.rb +75 -0
- data/app/models/enki/comment_activity.rb +33 -0
- data/app/models/enki/delete_comment_undo.rb +33 -0
- data/app/models/enki/delete_page_undo.rb +32 -0
- data/app/models/enki/delete_post_undo.rb +36 -0
- data/app/models/enki/page.rb +42 -0
- data/app/models/enki/post.rb +4 -0
- data/app/models/enki/stats.rb +19 -0
- data/app/models/enki/tag.rb +19 -0
- data/app/models/enki/tagging.rb +7 -0
- data/app/models/enki/undo_item.rb +10 -0
- data/app/views/enki/admin/comments/_comment.html.erb +12 -0
- data/app/views/enki/admin/comments/index.html.erb +30 -0
- data/app/views/enki/admin/comments/show.html.erb +9 -0
- data/app/views/enki/admin/dashboard/show.html.erb +61 -0
- data/app/views/enki/admin/health/index.html.erb +3 -0
- data/app/views/enki/admin/pages/_form.html.erb +3 -0
- data/app/views/enki/admin/pages/_page.html.erb +12 -0
- data/app/views/enki/admin/pages/index.html.erb +25 -0
- data/app/views/enki/admin/pages/new.html.erb +8 -0
- data/app/views/enki/admin/pages/show.html.erb +8 -0
- data/app/views/enki/admin/posts/_form.html.erb +11 -0
- data/app/views/enki/admin/posts/_post.html.erb +12 -0
- data/app/views/enki/admin/posts/_taggings_form.html.erb +4 -0
- data/app/views/enki/admin/posts/_upload_form.html.erb +0 -0
- data/app/views/enki/admin/posts/index.html.erb +25 -0
- data/app/views/enki/admin/posts/new.html.erb +8 -0
- data/app/views/enki/admin/posts/show.html.erb +8 -0
- data/app/views/enki/admin/undo_items/index.html.erb +24 -0
- data/app/views/enki/archives/index.html.erb +17 -0
- data/app/views/enki/comments/_comment.html.erb +4 -0
- data/app/views/enki/pages/_page.html.erb +3 -0
- data/app/views/enki/pages/show.html.erb +5 -0
- data/app/views/enki/posts/_post.html.erb +13 -0
- data/app/views/enki/posts/index.atom.builder +27 -0
- data/app/views/enki/posts/index.html.erb +15 -0
- data/app/views/enki/posts/show.html.erb +37 -0
- data/autotest/discover.rb +2 -0
- data/config/cucumber.yml +8 -0
- data/config/enki.yml.sample +16 -0
- data/config/initializers/enki_ext.rb +3 -0
- data/config/initializers/set_chronic_timezone.rb +1 -0
- data/config/initializers/verification.rb +135 -0
- data/config/routes.rb +34 -0
- data/db/migrate/20110709024316_initialize_db.rb +97 -0
- data/db/seeds.rb +8 -0
- data/enki-engine.gemspec +47 -0
- data/features/admin_dashboard.feature +10 -0
- data/features/admin_health.feature +10 -0
- data/features/admin_undo.feature +20 -0
- data/features/browsing.feature +16 -0
- data/features/step_definitions/admin.rb +27 -0
- data/features/step_definitions/browsing.rb +3 -0
- data/features/step_definitions/posts.rb +11 -0
- data/features/step_definitions/web_steps.rb +1 -0
- data/features/support/env.rb +59 -0
- data/features/support/paths.rb +35 -0
- data/features/support/selectors.rb +39 -0
- data/lib/core_extensions/object.rb +9 -0
- data/lib/core_extensions/string.rb +22 -0
- data/lib/enki/config.rb +44 -0
- data/lib/enki/engine.rb +19 -0
- data/lib/enki/html5_tags.rb +8 -0
- data/lib/enki/pagination_shim.rb +25 -0
- data/lib/enki/version.rb +3 -0
- data/lib/enki.rb +14 -0
- data/lib/enki_formatter.rb +11 -0
- data/lib/tag_list.rb +2 -0
- data/lib/tags_helper.rb +13 -0
- data/lib/tasks/cucumber.rake +65 -0
- data/lib/tasks/enki.rake +29 -0
- data/lib/undo_failed.rb +2 -0
- data/script/cucumber +10 -0
- data/spec/controllers/admin/comments_controller_spec.rb +140 -0
- data/spec/controllers/admin/dashboard_controller_spec.rb +47 -0
- data/spec/controllers/admin/health_controller_spec.rb +49 -0
- data/spec/controllers/admin/pages_controller_spec.rb +136 -0
- data/spec/controllers/admin/posts_controller_spec.rb +183 -0
- data/spec/controllers/admin/undo_items_controller_spec.rb +93 -0
- data/spec/controllers/archives_controller_spec.rb +37 -0
- data/spec/controllers/comments_controller_spec.rb +126 -0
- data/spec/controllers/pages_controller_spec.rb +46 -0
- data/spec/controllers/posts_controller_spec.rb +168 -0
- data/spec/dummy/Gemfile +5 -0
- data/spec/dummy/Rakefile +7 -0
- data/spec/dummy/app/controllers/application_controller.rb +3 -0
- data/spec/dummy/config/application.rb +34 -0
- data/spec/dummy/config/boot.rb +10 -0
- data/spec/dummy/config/database.yml +6 -0
- data/spec/dummy/config/enki.yml +20 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +34 -0
- data/spec/dummy/config/environments/test.rb +32 -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/en.yml +5 -0
- data/spec/dummy/config/routes.rb +14 -0
- data/spec/dummy/config.ru +6 -0
- data/spec/dummy/script/rails +6 -0
- data/spec/factories/factories.rb +36 -0
- data/spec/helpers/page_title_helper_spec.rb +54 -0
- data/spec/helpers/url_helper_spec.rb +23 -0
- data/spec/lib/slugorize_spec.rb +44 -0
- data/spec/models/comment_activity_spec.rb +60 -0
- data/spec/models/comment_spec.rb +125 -0
- data/spec/models/delete_comment_undo_spec.rb +52 -0
- data/spec/models/delete_post_undo_spec.rb +18 -0
- data/spec/models/page_spec.rb +75 -0
- data/spec/models/post_spec.rb +257 -0
- data/spec/models/stats_spec.rb +28 -0
- data/spec/models/tag_spec.rb +13 -0
- data/spec/models/tagging_spec.rb +30 -0
- data/spec/rcov.opts +2 -0
- data/spec/routing/admin/pages_routing_spec.rb +29 -0
- data/spec/routing/archives_routing_spec.rb +9 -0
- data/spec/routing/comments_routing_spec.rb +17 -0
- data/spec/routing/pages_routing_spec.rb +9 -0
- data/spec/routing/posts_routing_spec.rb +26 -0
- data/spec/spec.opts +4 -0
- data/spec/spec_helper.rb +60 -0
- data/spec/support/be_valid_html5.rb +150 -0
- data/spec/support/be_valid_xhtml.rb +148 -0
- data/spec/support/routes_override_helper.rb +12 -0
- data/spec/views/admin/comments/index.html_spec.rb +26 -0
- data/spec/views/admin/comments/show.html_spec.rb +28 -0
- data/spec/views/admin/dashboard/show.html_spec.rb +37 -0
- data/spec/views/admin/pages/index.html_spec.rb +23 -0
- data/spec/views/admin/pages/new.html_spec.rb +16 -0
- data/spec/views/admin/pages/show.html_spec.rb +16 -0
- data/spec/views/admin/posts/index.html_spec.rb +24 -0
- data/spec/views/admin/posts/new.html_spec.rb +16 -0
- data/spec/views/admin/posts/show.html_spec.rb +16 -0
- data/spec/views/admin/undo_items/index.html_spec.rb +19 -0
- data/spec/views/archives/index.html_spec.rb +34 -0
- data/spec/views/pages/show.html_spec.rb +23 -0
- data/spec/views/posts/index.atom.builder_spec.rb +36 -0
- data/spec/views/posts/index.html_spec.rb +39 -0
- data/spec/views/posts/show.html_spec.rb +49 -0
- data/vendor/assets/javascripts/humanmsg.js +86 -0
- data/vendor/assets/javascripts/jquery.easing.1.3.js +205 -0
- data/vendor/assets/javascripts/jquery.form.js +869 -0
- data/vendor/assets/javascripts/jquery.jfeed.js +143 -0
- data/vendor/assets/javascripts/jquery.livequery.js +250 -0
- metadata +464 -0
@@ -0,0 +1,168 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
|
3
|
+
shared_examples_for 'successful posts list' do
|
4
|
+
it "should be successful" do
|
5
|
+
do_get
|
6
|
+
response.should be_success
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should render index template" do
|
10
|
+
do_get
|
11
|
+
response.should render_template('index')
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should assign the found posts for the view" do
|
15
|
+
do_get
|
16
|
+
assigns[:posts].should == @posts
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
shared_examples_for "ATOM feed" do
|
21
|
+
it "renders with no layout" do
|
22
|
+
response.should render_template(nil)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
module Enki
|
27
|
+
|
28
|
+
describe PostsController do
|
29
|
+
describe 'handling GET to index'do
|
30
|
+
before(:each) do
|
31
|
+
@posts = [create(:post)]
|
32
|
+
Post.stub!(:find_recent).and_return(@posts)
|
33
|
+
end
|
34
|
+
|
35
|
+
def do_get
|
36
|
+
get :index
|
37
|
+
end
|
38
|
+
|
39
|
+
it_should_behave_like('successful posts list')
|
40
|
+
|
41
|
+
it "should find recent posts" do
|
42
|
+
Post.should_receive(:find_recent).with(:tag => nil, :include => :tags).and_return(@posts)
|
43
|
+
do_get
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe 'handling GET to index with tag'do
|
48
|
+
before(:each) do
|
49
|
+
@posts = [create(:post)]
|
50
|
+
Post.stub!(:find_recent).and_return(@posts)
|
51
|
+
end
|
52
|
+
|
53
|
+
def do_get
|
54
|
+
get :index, :tag => 'code'
|
55
|
+
end
|
56
|
+
|
57
|
+
it_should_behave_like('successful posts list')
|
58
|
+
|
59
|
+
it "should find recent tagged posts" do
|
60
|
+
Post.should_receive(:find_recent).with(:tag => 'code', :include => :tags).and_return(@posts)
|
61
|
+
do_get
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
describe 'handling GET to index with no posts' do
|
66
|
+
before(:each) do
|
67
|
+
@posts = []
|
68
|
+
end
|
69
|
+
|
70
|
+
def do_get
|
71
|
+
get :index
|
72
|
+
end
|
73
|
+
|
74
|
+
it_should_behave_like('successful posts list')
|
75
|
+
end
|
76
|
+
|
77
|
+
describe 'handling GET to index with invalid tag'do
|
78
|
+
it "shows post not found" do
|
79
|
+
# This would normally 404, except the way future dated posts are handled
|
80
|
+
# means it is possible for a tag to exist (and show up in the navigation)
|
81
|
+
# without having any public posts. If that issue is ever fixed, this
|
82
|
+
# behaviour should revert to 404ing.
|
83
|
+
Post.stub!(:find_recent).and_return([])
|
84
|
+
get :index, :tag => 'bogus'
|
85
|
+
assigns(:posts).should be_empty
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
describe 'handling GET to /posts.atom'do
|
90
|
+
before(:each) do
|
91
|
+
@posts = [create(:post)]
|
92
|
+
Post.stub!(:find_recent).and_return(@posts)
|
93
|
+
end
|
94
|
+
|
95
|
+
def do_get
|
96
|
+
@request.env["HTTP_ACCEPT"] = "application/atom+xml"
|
97
|
+
get :index
|
98
|
+
end
|
99
|
+
|
100
|
+
it_should_behave_like('successful posts list')
|
101
|
+
it_should_behave_like('ATOM feed')
|
102
|
+
|
103
|
+
it "should find recent posts" do
|
104
|
+
Post.should_receive(:find_recent).with(:tag => nil, :include => :tags).and_return(@posts)
|
105
|
+
do_get
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
describe 'handling GET to /posts.atom with tag'do
|
110
|
+
before(:each) do
|
111
|
+
@posts = [create(:post)]
|
112
|
+
Post.stub!(:find_recent).and_return(@posts)
|
113
|
+
end
|
114
|
+
|
115
|
+
def do_get
|
116
|
+
@request.env["HTTP_ACCEPT"] = "application/atom+xml"
|
117
|
+
get :index, :tag => 'code'
|
118
|
+
end
|
119
|
+
|
120
|
+
it_should_behave_like('successful posts list')
|
121
|
+
it_should_behave_like('ATOM feed')
|
122
|
+
|
123
|
+
it "should find recent posts" do
|
124
|
+
Post.should_receive(:find_recent).with(:tag => 'code', :include => :tags).and_return(@posts)
|
125
|
+
do_get
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
describe "handling GET for a single post" do
|
130
|
+
before(:each) do
|
131
|
+
@post = create(:post)
|
132
|
+
@comment = build(:comment, :post => @post)
|
133
|
+
Post.stub!(:find_by_permalink).and_return(@post)
|
134
|
+
Comment.stub!(:new).and_return(@comment)
|
135
|
+
end
|
136
|
+
|
137
|
+
def do_get
|
138
|
+
get :show, :year => '2008', :month => '01', :day => '01', :slug => 'a-post'
|
139
|
+
end
|
140
|
+
|
141
|
+
it "should be successful" do
|
142
|
+
do_get
|
143
|
+
response.should be_success
|
144
|
+
end
|
145
|
+
|
146
|
+
it "should render show template" do
|
147
|
+
do_get
|
148
|
+
response.should render_template('show')
|
149
|
+
end
|
150
|
+
|
151
|
+
it "should find the post requested" do
|
152
|
+
Post.should_receive(:find_by_permalink).with('2008', '01', '01', 'a-post', :include => [:approved_comments, :tags]).and_return(@post)
|
153
|
+
do_get
|
154
|
+
end
|
155
|
+
|
156
|
+
it "should assign the found post for the view" do
|
157
|
+
do_get
|
158
|
+
assigns[:post].should equal(@post)
|
159
|
+
end
|
160
|
+
|
161
|
+
it "should assign a new comment for the view" do
|
162
|
+
do_get
|
163
|
+
assigns[:comment].should equal(@comment)
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
end
|
data/spec/dummy/Gemfile
ADDED
data/spec/dummy/Rakefile
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
#!/usr/bin/env rake
|
2
|
+
# Add your own tasks in files placed in lib/tasks ending in .rake,
|
3
|
+
# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
|
4
|
+
|
5
|
+
require File.expand_path('../config/application', __FILE__)
|
6
|
+
|
7
|
+
Dummy::Application.load_tasks
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require File.expand_path('../boot', __FILE__)
|
2
|
+
|
3
|
+
# Pick the frameworks you want:
|
4
|
+
require "active_record/railtie"
|
5
|
+
require "action_controller/railtie"
|
6
|
+
|
7
|
+
Bundler.require if defined?(Bundler)
|
8
|
+
|
9
|
+
module Dummy
|
10
|
+
class Application < Rails::Application
|
11
|
+
# Configure the default encoding used in templates for Ruby 1.9.
|
12
|
+
config.encoding = "utf-8"
|
13
|
+
|
14
|
+
# Configure sensitive parameters which will be filtered from the log file.
|
15
|
+
config.filter_parameters += [:password]
|
16
|
+
|
17
|
+
# Use SQL instead of Active Record's schema dumper when creating the database.
|
18
|
+
# This is necessary if your schema can't be completely dumped by the schema dumper,
|
19
|
+
# like if you have constraints or database-specific column types
|
20
|
+
# config.active_record.schema_format = :sql
|
21
|
+
|
22
|
+
# Enforce whitelist mode for mass assignment.
|
23
|
+
# This will create an empty whitelist of attributes available for mass-assignment for all models
|
24
|
+
# in your app. As such, your models will need to explicitly whitelist or blacklist accessible
|
25
|
+
# parameters by using an attr_accessible or attr_protected declaration.
|
26
|
+
config.active_record.whitelist_attributes = true
|
27
|
+
|
28
|
+
config.generators do |generate|
|
29
|
+
generate.fixture_replacement :factory_girl, :dir => "spec/factories"
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# Configuration options for your blog - customise to taste and copy to the host app's config folder.
|
2
|
+
# This file contains no secret information, so can be stored in source control (unlike database.yml)
|
3
|
+
title: My Enki Blog
|
4
|
+
url: http://enkiblog.com
|
5
|
+
author:
|
6
|
+
name: Don Alias # For copyright notice and ATOM feeds
|
7
|
+
email: don@enkiblog.com # Exception emails will go here, and it is used in ATOM feeds
|
8
|
+
open_id: # These are used to login to the admin area
|
9
|
+
- http://enkiblog.com
|
10
|
+
- http://secondaryopenid.com
|
11
|
+
|
12
|
+
engine:
|
13
|
+
mount_at: /blog
|
14
|
+
pages_at: /
|
15
|
+
|
16
|
+
features:
|
17
|
+
comments: true
|
18
|
+
tags: true
|
19
|
+
|
20
|
+
|
@@ -0,0 +1,34 @@
|
|
1
|
+
Dummy::Application.configure do
|
2
|
+
# Settings specified here will take precedence over those in config/application.rb
|
3
|
+
|
4
|
+
# In the development environment your application's code is reloaded on
|
5
|
+
# every request. This slows down response time but is perfect for development
|
6
|
+
# since you don't have to restart the web server when you make code changes.
|
7
|
+
config.cache_classes = false
|
8
|
+
|
9
|
+
# Log error messages when you accidentally call methods on nil.
|
10
|
+
config.whiny_nils = true
|
11
|
+
|
12
|
+
# Show full error reports and disable caching
|
13
|
+
config.consider_all_requests_local = true
|
14
|
+
config.action_controller.perform_caching = false
|
15
|
+
|
16
|
+
# Print deprecation notices to the Rails logger
|
17
|
+
config.active_support.deprecation = :log
|
18
|
+
|
19
|
+
# Only use best-standards-support built into browsers
|
20
|
+
config.action_dispatch.best_standards_support = :builtin
|
21
|
+
|
22
|
+
# Raise exception on mass assignment protection for Active Record models
|
23
|
+
config.active_record.mass_assignment_sanitizer = :strict
|
24
|
+
|
25
|
+
# Log the query plan for queries taking more than this (works
|
26
|
+
# with SQLite, MySQL, and PostgreSQL)
|
27
|
+
config.active_record.auto_explain_threshold_in_seconds = 0.5
|
28
|
+
|
29
|
+
# Do not compress assets
|
30
|
+
config.assets.compress = false
|
31
|
+
|
32
|
+
# Expands the lines which load the assets
|
33
|
+
config.assets.debug = true
|
34
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
Dummy::Application.configure do
|
2
|
+
# Settings specified here will take precedence over those in config/application.rb
|
3
|
+
|
4
|
+
# The test environment is used exclusively to run your application's
|
5
|
+
# test suite. You never need to work with it otherwise. Remember that
|
6
|
+
# your test database is "scratch space" for the test suite and is wiped
|
7
|
+
# and recreated between test runs. Don't rely on the data there!
|
8
|
+
config.cache_classes = true
|
9
|
+
|
10
|
+
# Configure static asset server for tests with Cache-Control for performance
|
11
|
+
config.serve_static_assets = true
|
12
|
+
config.static_cache_control = "public, max-age=3600"
|
13
|
+
|
14
|
+
# Log error messages when you accidentally call methods on nil
|
15
|
+
config.whiny_nils = true
|
16
|
+
|
17
|
+
# Show full error reports and disable caching
|
18
|
+
config.consider_all_requests_local = true
|
19
|
+
config.action_controller.perform_caching = false
|
20
|
+
|
21
|
+
# Raise exceptions instead of rendering exception templates
|
22
|
+
config.action_dispatch.show_exceptions = false
|
23
|
+
|
24
|
+
# Disable request forgery protection in test environment
|
25
|
+
config.action_controller.allow_forgery_protection = false
|
26
|
+
|
27
|
+
# Raise exception on mass assignment protection for Active Record models
|
28
|
+
config.active_record.mass_assignment_sanitizer = :strict
|
29
|
+
|
30
|
+
# Print deprecation notices to the stderr
|
31
|
+
config.active_support.deprecation = :stderr
|
32
|
+
end
|
@@ -0,0 +1,7 @@
|
|
1
|
+
# Be sure to restart your server when you modify this file.
|
2
|
+
|
3
|
+
# Your secret key for verifying the integrity of signed cookies.
|
4
|
+
# If you change this key, all old signed cookies will become invalid!
|
5
|
+
# Make sure the secret is at least 30 characters and all random,
|
6
|
+
# no regular words or you'll be exposed to dictionary attacks.
|
7
|
+
Dummy::Application.config.secret_token = 'c2af159f67aa6955b415217bf5aa58779dec6fccc201c7bf38f9a8ad25893d88596778df8bb7106153666f41c3161cfb7f89b639a2c15a084abb6c2c57f74c55'
|
@@ -0,0 +1,8 @@
|
|
1
|
+
# Be sure to restart your server when you modify this file.
|
2
|
+
|
3
|
+
Dummy::Application.config.session_store :cookie_store, :key => '_dummy_session'
|
4
|
+
|
5
|
+
# Use the database for sessions instead of the cookie-based default,
|
6
|
+
# which shouldn't be used to store highly confidential information
|
7
|
+
# (create the session table with "rails generate session_migration")
|
8
|
+
# Dummy::Application.config.session_store :active_record_store
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# Be sure to restart your server when you modify this file.
|
2
|
+
#
|
3
|
+
# This file contains settings for ActionController::ParamsWrapper which
|
4
|
+
# is enabled by default.
|
5
|
+
|
6
|
+
# Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array.
|
7
|
+
ActiveSupport.on_load(:action_controller) do
|
8
|
+
wrap_parameters :format => [:json]
|
9
|
+
end
|
10
|
+
|
11
|
+
# Disable root element in JSON by default.
|
12
|
+
ActiveSupport.on_load(:active_record) do
|
13
|
+
self.include_root_in_json = false
|
14
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
Dummy::Application.routes.draw do
|
2
|
+
|
3
|
+
scope :to => 'enki/posts#index' do
|
4
|
+
get '/blag/posts.:format', :as => :formatted_posts
|
5
|
+
get '/blag/tags/(:tag)', :as => :posts
|
6
|
+
end
|
7
|
+
|
8
|
+
|
9
|
+
if defined?(Enki)
|
10
|
+
mount Enki::Engine => '/blog', :as => 'enki'
|
11
|
+
# mount Enki::Engine => Enki::Config.default[:engine, :mount_at], :as => 'enki'
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
@@ -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,36 @@
|
|
1
|
+
FactoryGirl.define do
|
2
|
+
|
3
|
+
factory :tag, :class => Enki::Tag do |a|
|
4
|
+
a.name 'Tag'
|
5
|
+
end
|
6
|
+
|
7
|
+
factory :page, :class => Enki::Post do |a|
|
8
|
+
a.title 'A page'
|
9
|
+
a.slug 'a-page'
|
10
|
+
a.body 'This is a page'
|
11
|
+
|
12
|
+
a.published_at 1.day.ago
|
13
|
+
a.created_at 1.day.ago
|
14
|
+
a.updated_at 1.day.ago
|
15
|
+
end
|
16
|
+
|
17
|
+
factory :post, :class => Enki::Post do |a|
|
18
|
+
a.title 'A post'
|
19
|
+
a.slug 'a-post'
|
20
|
+
a.body 'This is a post'
|
21
|
+
|
22
|
+
a.published_at 1.day.ago
|
23
|
+
a.created_at 1.day.ago
|
24
|
+
a.updated_at 1.day.ago
|
25
|
+
end
|
26
|
+
|
27
|
+
factory :comment, :class => Enki::Comment do |a|
|
28
|
+
a.author 'Don Alias'
|
29
|
+
a.author_email 'enki@enkiblog.com'
|
30
|
+
a.author_url 'http://enkiblog.com'
|
31
|
+
a.body 'I find this article thought provoking'
|
32
|
+
|
33
|
+
post
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Enki
|
4
|
+
describe PageTitleHelper do
|
5
|
+
include PageTitleHelper
|
6
|
+
|
7
|
+
before do
|
8
|
+
config = double('config')
|
9
|
+
config.stub!('[]').with(:title).and_return('Blog Title')
|
10
|
+
Enki.stub!(:config).and_return(config)
|
11
|
+
end
|
12
|
+
|
13
|
+
describe '#posts_title with no tag' do
|
14
|
+
it 'is the site title' do
|
15
|
+
posts_title(nil).should == "Blog Title"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe '#posts_title with tag' do
|
20
|
+
it 'is the titlelized tag name plus the site title' do
|
21
|
+
posts_title("ruby").should == "Ruby - Blog Title"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe '#post_title' do
|
26
|
+
it 'is the post title plus the site title' do
|
27
|
+
posts_title("My Post").should == "My Post - Blog Title"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe '#archives_title' do
|
32
|
+
it 'is "Archives" plus the site title' do
|
33
|
+
archives_title.should == "Archives - Blog Title"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe '#page_title' do
|
38
|
+
it 'is the page title plus the site title' do
|
39
|
+
posts_title("My Page").should == "My Page - Blog Title"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe '#html_title' do
|
44
|
+
it 'uses the given string when present' do
|
45
|
+
html_title('a').should == "a"
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'defaults to the configured title if nothing is supplied' do
|
49
|
+
html_title('' ).should == "Blog Title"
|
50
|
+
html_title(nil).should == "Blog Title"
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Enki
|
4
|
+
describe UrlHelper do
|
5
|
+
include UrlHelper
|
6
|
+
|
7
|
+
before do
|
8
|
+
config = double('config')
|
9
|
+
config.should_receive('[]').with(:engine, :mount_at).and_return('')
|
10
|
+
Enki.stub!(:config).and_return(config)
|
11
|
+
end
|
12
|
+
|
13
|
+
describe '#post_path' do
|
14
|
+
it 'should prefix slug with published_at' do
|
15
|
+
post = stub(
|
16
|
+
:published_at => Date.new(2012,1,1),
|
17
|
+
:slug => 'post'
|
18
|
+
)
|
19
|
+
post_path(post).should == '/2012/01/01/post'
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe String, '#slugorize' do
|
4
|
+
it "should lowercase everything" do
|
5
|
+
"ABCDEF".slugorize.should == "abcdef"
|
6
|
+
end
|
7
|
+
|
8
|
+
it "should leave alphanumerics and hyphens alone" do
|
9
|
+
"abc-123".slugorize.should == "abc-123"
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should ditch entities" do
|
13
|
+
"abc<-<xyz".slugorize.should == "abc-xyz"
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should replace & with and" do
|
17
|
+
"a-&-b-&-c".slugorize.should == "a-and-b-and-c"
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should strip all non-alphanumeric characters except - and &" do
|
21
|
+
'abc""!@#$%^*()/=+|\[],.<>123'.slugorize.should == "abc-123"
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should allow apostrophes for good punctuation" do
|
25
|
+
"tomato's".slugorize.should == "tomato's"
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should replace all whitespace with a dash" do
|
29
|
+
"abc\n\t xyz".slugorize.should == "abc-xyz"
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should trim dashes at the tail" do
|
33
|
+
"abc--".slugorize.should == "abc"
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should trim dashes at the head" do
|
37
|
+
"--abc".slugorize.should == "abc"
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should collapse multiple dashes" do
|
41
|
+
"abc---xyz".slugorize.should == "abc-xyz"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
|
3
|
+
module Enki
|
4
|
+
describe CommentActivity, '#comments' do
|
5
|
+
|
6
|
+
def valid_comment_attributes(extra = {})
|
7
|
+
{
|
8
|
+
:author => 'Don Alias',
|
9
|
+
:author_url => "me",
|
10
|
+
:author_email => "me@fake.com",
|
11
|
+
:body => 'This is a comment',
|
12
|
+
:post => Post.create!(:title => 'My Post', :body => "body", :tag_list => "ruby")
|
13
|
+
}.merge(extra)
|
14
|
+
end
|
15
|
+
|
16
|
+
context "find recent comments" do
|
17
|
+
before :each do
|
18
|
+
@comments = []
|
19
|
+
(1..10).each do |n|
|
20
|
+
@comments << Comment.create!(valid_comment_attributes(:created_at => Time.now - n * (60 * 60 * 24)))
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should have the comment activity sorted by when they were created" do
|
25
|
+
comment_activity = CommentActivity.find_recent
|
26
|
+
comment_activity.first.post.should == @comments.first.post
|
27
|
+
end
|
28
|
+
|
29
|
+
it do
|
30
|
+
comment_activity = CommentActivity.find_recent
|
31
|
+
comment_activity.should have_exactly(5).posts
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should not return repeated posts" do
|
35
|
+
comment = Comment.create! valid_comment_attributes(:post => Post.first, :created_at => Time.now)
|
36
|
+
comment_activity = CommentActivity.find_recent
|
37
|
+
comment_activity.select{|a| a.post == comment.post}.size.should == 1
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'finds the 5 most recent approved comments for the post' do
|
43
|
+
ret = [mock_model(Comment)]
|
44
|
+
comments = []
|
45
|
+
comments.should_receive(:find_recent).with(hash_including(:limit => 5)).and_return(ret)
|
46
|
+
post = mock_model(Post)
|
47
|
+
post.stub!(:approved_comments).and_return(comments)
|
48
|
+
CommentActivity.new(post).comments.should == ret
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'is memoized to avoid excess hits to the DB' do
|
52
|
+
post = mock_model(Post)
|
53
|
+
activity = CommentActivity.new(post)
|
54
|
+
|
55
|
+
post.should_receive(:approved_comments).once.and_return(mock('stub').as_null_object)
|
56
|
+
2.times { activity.comments }
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|