enki-engine 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 (206) hide show
  1. data/.gitignore +13 -0
  2. data/.rspec +1 -0
  3. data/.travis.yml +3 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE +284 -0
  6. data/README.textile +112 -0
  7. data/Rakefile +13 -0
  8. data/TODO.textile +8 -0
  9. data/app/assets/images/admin/flash_bg.gif +0 -0
  10. data/app/assets/images/admin/future_bg.png +0 -0
  11. data/app/assets/images/admin/gray_bg.gif +0 -0
  12. data/app/assets/images/admin/new_button.png +0 -0
  13. data/app/assets/images/admin/silver_bg.gif +0 -0
  14. data/app/assets/images/admin/submit_bg.gif +0 -0
  15. data/app/assets/images/admin/subnav_bg.gif +0 -0
  16. data/app/assets/images/openid_icon.png +0 -0
  17. data/app/assets/images/rails.png +0 -0
  18. data/app/assets/images/silk/arrow_undo.png +0 -0
  19. data/app/assets/images/silk/delete.png +0 -0
  20. data/app/assets/images/silk/pencil.png +0 -0
  21. data/app/assets/javascripts/admin/actions.js +18 -0
  22. data/app/assets/javascripts/admin/comments.js +3 -0
  23. data/app/assets/javascripts/admin/common.js +109 -0
  24. data/app/assets/javascripts/admin/dashboard.js +33 -0
  25. data/app/assets/javascripts/admin/edit-preview.js +40 -0
  26. data/app/assets/javascripts/admin/pages.js +1 -0
  27. data/app/assets/javascripts/admin/posts.js +1 -0
  28. data/app/assets/javascripts/admin/shortcut.js +223 -0
  29. data/app/assets/javascripts/admin.js +17 -0
  30. data/app/assets/javascripts/application.js +15 -0
  31. data/app/assets/javascripts/common.js +22 -0
  32. data/app/assets/javascripts/enki.js +13 -0
  33. data/app/assets/javascripts/live-comment-preview.js +36 -0
  34. data/app/assets/stylesheets/admin.css +304 -0
  35. data/app/assets/stylesheets/application.css.scss +486 -0
  36. data/app/assets/stylesheets/humanmsg.css +112 -0
  37. data/app/assets/stylesheets/login.css +65 -0
  38. data/app/controllers/enki/admin/base_controller.rb +15 -0
  39. data/app/controllers/enki/admin/comments_controller.rb +52 -0
  40. data/app/controllers/enki/admin/dashboard_controller.rb +12 -0
  41. data/app/controllers/enki/admin/health_controller.rb +20 -0
  42. data/app/controllers/enki/admin/pages_controller.rb +97 -0
  43. data/app/controllers/enki/admin/posts_controller.rb +104 -0
  44. data/app/controllers/enki/admin/undo_items_controller.rb +43 -0
  45. data/app/controllers/enki/application_controller.rb +21 -0
  46. data/app/controllers/enki/archives_controller.rb +7 -0
  47. data/app/controllers/enki/base_controller.rb +5 -0
  48. data/app/controllers/enki/comments_controller.rb +43 -0
  49. data/app/controllers/enki/pages_controller.rb +7 -0
  50. data/app/controllers/enki/posts_controller.rb +27 -0
  51. data/app/helpers/enki/admin/navigation_helper.rb +10 -0
  52. data/app/helpers/enki/application_helper.rb +35 -0
  53. data/app/helpers/enki/date_helper.rb +15 -0
  54. data/app/helpers/enki/form_helper.rb +7 -0
  55. data/app/helpers/enki/host_helper.rb +19 -0
  56. data/app/helpers/enki/navigation_helper.rb +23 -0
  57. data/app/helpers/enki/page_title_helper.rb +33 -0
  58. data/app/helpers/enki/posts_helper.rb +9 -0
  59. data/app/helpers/enki/tag_helper.rb +7 -0
  60. data/app/helpers/enki/url_helper.rb +25 -0
  61. data/app/models/enki/base/post.rb +153 -0
  62. data/app/models/enki/comment.rb +75 -0
  63. data/app/models/enki/comment_activity.rb +33 -0
  64. data/app/models/enki/delete_comment_undo.rb +33 -0
  65. data/app/models/enki/delete_page_undo.rb +32 -0
  66. data/app/models/enki/delete_post_undo.rb +36 -0
  67. data/app/models/enki/page.rb +42 -0
  68. data/app/models/enki/post.rb +4 -0
  69. data/app/models/enki/stats.rb +19 -0
  70. data/app/models/enki/tag.rb +19 -0
  71. data/app/models/enki/tagging.rb +7 -0
  72. data/app/models/enki/undo_item.rb +10 -0
  73. data/app/views/enki/admin/comments/_comment.html.erb +12 -0
  74. data/app/views/enki/admin/comments/index.html.erb +30 -0
  75. data/app/views/enki/admin/comments/show.html.erb +9 -0
  76. data/app/views/enki/admin/dashboard/show.html.erb +61 -0
  77. data/app/views/enki/admin/health/index.html.erb +3 -0
  78. data/app/views/enki/admin/pages/_form.html.erb +3 -0
  79. data/app/views/enki/admin/pages/_page.html.erb +12 -0
  80. data/app/views/enki/admin/pages/index.html.erb +25 -0
  81. data/app/views/enki/admin/pages/new.html.erb +8 -0
  82. data/app/views/enki/admin/pages/show.html.erb +8 -0
  83. data/app/views/enki/admin/posts/_form.html.erb +11 -0
  84. data/app/views/enki/admin/posts/_post.html.erb +12 -0
  85. data/app/views/enki/admin/posts/_taggings_form.html.erb +4 -0
  86. data/app/views/enki/admin/posts/_upload_form.html.erb +0 -0
  87. data/app/views/enki/admin/posts/index.html.erb +25 -0
  88. data/app/views/enki/admin/posts/new.html.erb +8 -0
  89. data/app/views/enki/admin/posts/show.html.erb +8 -0
  90. data/app/views/enki/admin/undo_items/index.html.erb +24 -0
  91. data/app/views/enki/archives/index.html.erb +17 -0
  92. data/app/views/enki/comments/_comment.html.erb +4 -0
  93. data/app/views/enki/pages/_page.html.erb +3 -0
  94. data/app/views/enki/pages/show.html.erb +5 -0
  95. data/app/views/enki/posts/_post.html.erb +13 -0
  96. data/app/views/enki/posts/index.atom.builder +27 -0
  97. data/app/views/enki/posts/index.html.erb +15 -0
  98. data/app/views/enki/posts/show.html.erb +37 -0
  99. data/autotest/discover.rb +2 -0
  100. data/config/cucumber.yml +8 -0
  101. data/config/enki.yml.sample +16 -0
  102. data/config/initializers/enki_ext.rb +3 -0
  103. data/config/initializers/set_chronic_timezone.rb +1 -0
  104. data/config/initializers/verification.rb +135 -0
  105. data/config/routes.rb +34 -0
  106. data/db/migrate/20110709024316_initialize_db.rb +97 -0
  107. data/db/seeds.rb +8 -0
  108. data/enki-engine.gemspec +47 -0
  109. data/features/admin_dashboard.feature +10 -0
  110. data/features/admin_health.feature +10 -0
  111. data/features/admin_undo.feature +20 -0
  112. data/features/browsing.feature +16 -0
  113. data/features/step_definitions/admin.rb +27 -0
  114. data/features/step_definitions/browsing.rb +3 -0
  115. data/features/step_definitions/posts.rb +11 -0
  116. data/features/step_definitions/web_steps.rb +1 -0
  117. data/features/support/env.rb +59 -0
  118. data/features/support/paths.rb +35 -0
  119. data/features/support/selectors.rb +39 -0
  120. data/lib/core_extensions/object.rb +9 -0
  121. data/lib/core_extensions/string.rb +22 -0
  122. data/lib/enki/config.rb +44 -0
  123. data/lib/enki/engine.rb +19 -0
  124. data/lib/enki/html5_tags.rb +8 -0
  125. data/lib/enki/pagination_shim.rb +25 -0
  126. data/lib/enki/version.rb +3 -0
  127. data/lib/enki.rb +14 -0
  128. data/lib/enki_formatter.rb +11 -0
  129. data/lib/tag_list.rb +2 -0
  130. data/lib/tags_helper.rb +13 -0
  131. data/lib/tasks/cucumber.rake +65 -0
  132. data/lib/tasks/enki.rake +29 -0
  133. data/lib/undo_failed.rb +2 -0
  134. data/script/cucumber +10 -0
  135. data/spec/controllers/admin/comments_controller_spec.rb +140 -0
  136. data/spec/controllers/admin/dashboard_controller_spec.rb +47 -0
  137. data/spec/controllers/admin/health_controller_spec.rb +49 -0
  138. data/spec/controllers/admin/pages_controller_spec.rb +136 -0
  139. data/spec/controllers/admin/posts_controller_spec.rb +183 -0
  140. data/spec/controllers/admin/undo_items_controller_spec.rb +93 -0
  141. data/spec/controllers/archives_controller_spec.rb +37 -0
  142. data/spec/controllers/comments_controller_spec.rb +126 -0
  143. data/spec/controllers/pages_controller_spec.rb +46 -0
  144. data/spec/controllers/posts_controller_spec.rb +168 -0
  145. data/spec/dummy/Gemfile +5 -0
  146. data/spec/dummy/Rakefile +7 -0
  147. data/spec/dummy/app/controllers/application_controller.rb +3 -0
  148. data/spec/dummy/config/application.rb +34 -0
  149. data/spec/dummy/config/boot.rb +10 -0
  150. data/spec/dummy/config/database.yml +6 -0
  151. data/spec/dummy/config/enki.yml +20 -0
  152. data/spec/dummy/config/environment.rb +5 -0
  153. data/spec/dummy/config/environments/development.rb +34 -0
  154. data/spec/dummy/config/environments/test.rb +32 -0
  155. data/spec/dummy/config/initializers/secret_token.rb +7 -0
  156. data/spec/dummy/config/initializers/session_store.rb +8 -0
  157. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  158. data/spec/dummy/config/locales/en.yml +5 -0
  159. data/spec/dummy/config/routes.rb +14 -0
  160. data/spec/dummy/config.ru +6 -0
  161. data/spec/dummy/script/rails +6 -0
  162. data/spec/factories/factories.rb +36 -0
  163. data/spec/helpers/page_title_helper_spec.rb +54 -0
  164. data/spec/helpers/url_helper_spec.rb +23 -0
  165. data/spec/lib/slugorize_spec.rb +44 -0
  166. data/spec/models/comment_activity_spec.rb +60 -0
  167. data/spec/models/comment_spec.rb +125 -0
  168. data/spec/models/delete_comment_undo_spec.rb +52 -0
  169. data/spec/models/delete_post_undo_spec.rb +18 -0
  170. data/spec/models/page_spec.rb +75 -0
  171. data/spec/models/post_spec.rb +257 -0
  172. data/spec/models/stats_spec.rb +28 -0
  173. data/spec/models/tag_spec.rb +13 -0
  174. data/spec/models/tagging_spec.rb +30 -0
  175. data/spec/rcov.opts +2 -0
  176. data/spec/routing/admin/pages_routing_spec.rb +29 -0
  177. data/spec/routing/archives_routing_spec.rb +9 -0
  178. data/spec/routing/comments_routing_spec.rb +17 -0
  179. data/spec/routing/pages_routing_spec.rb +9 -0
  180. data/spec/routing/posts_routing_spec.rb +26 -0
  181. data/spec/spec.opts +4 -0
  182. data/spec/spec_helper.rb +60 -0
  183. data/spec/support/be_valid_html5.rb +150 -0
  184. data/spec/support/be_valid_xhtml.rb +148 -0
  185. data/spec/support/routes_override_helper.rb +12 -0
  186. data/spec/views/admin/comments/index.html_spec.rb +26 -0
  187. data/spec/views/admin/comments/show.html_spec.rb +28 -0
  188. data/spec/views/admin/dashboard/show.html_spec.rb +37 -0
  189. data/spec/views/admin/pages/index.html_spec.rb +23 -0
  190. data/spec/views/admin/pages/new.html_spec.rb +16 -0
  191. data/spec/views/admin/pages/show.html_spec.rb +16 -0
  192. data/spec/views/admin/posts/index.html_spec.rb +24 -0
  193. data/spec/views/admin/posts/new.html_spec.rb +16 -0
  194. data/spec/views/admin/posts/show.html_spec.rb +16 -0
  195. data/spec/views/admin/undo_items/index.html_spec.rb +19 -0
  196. data/spec/views/archives/index.html_spec.rb +34 -0
  197. data/spec/views/pages/show.html_spec.rb +23 -0
  198. data/spec/views/posts/index.atom.builder_spec.rb +36 -0
  199. data/spec/views/posts/index.html_spec.rb +39 -0
  200. data/spec/views/posts/show.html_spec.rb +49 -0
  201. data/vendor/assets/javascripts/humanmsg.js +86 -0
  202. data/vendor/assets/javascripts/jquery.easing.1.3.js +205 -0
  203. data/vendor/assets/javascripts/jquery.form.js +869 -0
  204. data/vendor/assets/javascripts/jquery.jfeed.js +143 -0
  205. data/vendor/assets/javascripts/jquery.livequery.js +250 -0
  206. metadata +464 -0
@@ -0,0 +1,49 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+
3
+ module Enki
4
+
5
+ describe Admin::HealthController do
6
+ describe 'handling GET to index' do
7
+ before(:each) do
8
+ controller.stub!(:logged_in?).and_return(true)
9
+ get :index
10
+ end
11
+
12
+ it "is successful" do
13
+ response.should be_success
14
+ end
15
+
16
+ it "renders health template" do
17
+ response.should render_template("index")
18
+ end
19
+ end
20
+
21
+ describe 'handling POST to generate_exception' do
22
+ describe 'when logged in' do
23
+ it 'raises a RuntimeError' do
24
+ controller.stub!(:logged_in?).and_return(true)
25
+ lambda {
26
+ post :generate_exception
27
+ }.should raise_error
28
+ end
29
+ end
30
+
31
+ describe 'when not logged in' do
32
+ it 'does not raise' do
33
+ lambda {
34
+ post :generate_exception
35
+ }.should raise_error(Enki::NotLoggedInError)
36
+ end
37
+ end
38
+ end
39
+
40
+ describe 'handling GET to generate_exception' do
41
+ it '405s' do
42
+ controller.stub!(:logged_in?).and_return(true)
43
+ get :generate_exception
44
+ response.status.should == 405
45
+ response.headers['Allow'].should == 'POST'
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,136 @@
1
+ require 'spec_helper'
2
+
3
+ module Enki
4
+
5
+ describe Admin::PagesController do
6
+
7
+ before do
8
+ controller.stub!(:logged_in?).and_return(true)
9
+ end
10
+
11
+ describe 'handling GET to index' do
12
+ before(:each) do
13
+ @pages = [create(:page), create(:page)]
14
+ Page.stub!(:paginated).and_return(@pages)
15
+
16
+ get :index
17
+ end
18
+
19
+ it "is successful" do
20
+ response.should be_success
21
+ end
22
+
23
+ it "renders index template" do
24
+ response.should render_template('index')
25
+ end
26
+
27
+ it "finds pages for the view" do
28
+ assigns[:pages].should == @pages
29
+ end
30
+ end
31
+
32
+ describe 'handling GET to show' do
33
+ before(:each) do
34
+ @page = mock_model(Page)
35
+ Page.stub!(:find).and_return(@page)
36
+
37
+ get :show, :id => 1
38
+ end
39
+
40
+ it "is successful" do
41
+ response.should be_success
42
+ end
43
+
44
+ it "renders show template" do
45
+ response.should render_template('show')
46
+ end
47
+
48
+ it "finds page for the view" do
49
+ assigns[:page].should == @page
50
+ end
51
+ end
52
+
53
+ describe 'handling GET to new' do
54
+ before(:each) do
55
+ @page = mock_model(Page)
56
+ Page.stub!(:new).and_return(@page)
57
+
58
+ get :new
59
+ end
60
+
61
+ it('is successful') { response.should be_success}
62
+ it('assigns page for the view') { assigns[:page] == @page }
63
+ end
64
+
65
+ describe 'handling PUT to update with valid attributes' do
66
+ before(:each) do
67
+ @page = mock_model(Page, :title => 'A page')
68
+ @page.stub!(:update_attributes).and_return(true)
69
+ Page.stub!(:find).and_return(@page)
70
+ end
71
+
72
+ def do_put
73
+ session[:logged_in] = true
74
+ put :update, :id => 1, :enki_page => {
75
+ 'title' => 'My Post',
76
+ 'slug' => 'my-post',
77
+ 'body' => 'This is my post'
78
+ }
79
+ end
80
+
81
+ it 'updates the page' do
82
+ @page.should_receive(:update_attributes).with(
83
+ 'title' => 'My Post',
84
+ 'slug' => 'my-post',
85
+ 'body' => 'This is my post'
86
+ )
87
+
88
+ do_put
89
+ end
90
+
91
+ it 'it redirects to show' do
92
+ do_put
93
+ response.should be_redirect
94
+ response.should redirect_to(admin_page_path(@page))
95
+ end
96
+ end
97
+
98
+ describe 'handling PUT to update with invalid attributes' do
99
+ before(:each) do
100
+ @page = mock_model(Page)
101
+ @page.stub!(:update_attributes).and_return(false)
102
+ Page.stub!(:find).and_return(@page)
103
+ end
104
+
105
+ def do_put
106
+ put :update, :id => 1, :enki_page => {}
107
+ end
108
+
109
+ it 'renders show' do
110
+ do_put
111
+ response.should render_template('show')
112
+ end
113
+
114
+ it 'is unprocessable' do
115
+ do_put
116
+ response.status.should == 422
117
+ end
118
+ end
119
+ end
120
+
121
+ describe Admin::PagesController, 'with an AJAX request to preview' do
122
+ before(:each) do
123
+ controller.stub!(:logged_in?).and_return(true)
124
+
125
+ Page.should_receive(:build_for_preview).and_return(@page = mock_model(Page))
126
+ xhr :post, :preview, :enki_page => {
127
+ :title => 'My Page',
128
+ :body => 'body'
129
+ }
130
+ end
131
+
132
+ it "assigns a new page for the view" do
133
+ assigns[:page].should == @page
134
+ end
135
+ end
136
+ end
@@ -0,0 +1,183 @@
1
+ require 'spec_helper'
2
+
3
+ module Enki
4
+
5
+ describe Admin::PostsController do
6
+
7
+ before do
8
+ controller.stub!(:logged_in?).and_return(true)
9
+ end
10
+
11
+ describe 'handling GET to index' do
12
+ before(:each) do
13
+ @posts = [create(:post), create(:post)]
14
+ Post.stub!(:paginated).and_return(@posts)
15
+
16
+ get :index
17
+ end
18
+
19
+ it "is successful" do
20
+ response.should be_success
21
+ end
22
+
23
+ it "renders index template" do
24
+ response.should render_template('index')
25
+ end
26
+
27
+ it "finds posts for the view" do
28
+ assigns[:posts].should == @posts
29
+ end
30
+ end
31
+
32
+ describe 'handling GET to show' do
33
+ before(:each) do
34
+ @post = create(:post)
35
+
36
+ get :show, :id => @post.to_param
37
+ end
38
+
39
+ it "is successful" do
40
+ response.should be_success
41
+ end
42
+
43
+ it "renders show template" do
44
+ response.should render_template('show')
45
+ end
46
+
47
+ it "finds post for the view" do
48
+ assigns[:post].should == @post
49
+ end
50
+ end
51
+
52
+ describe 'handling GET to new' do
53
+ before(:each) do
54
+ @post = build(:post)
55
+ Post.stub!(:new).and_return(@post)
56
+
57
+ get :new
58
+ end
59
+
60
+ it('is successful') { response.should be_success}
61
+ it('assigns post for the view') { assigns[:post] == @post }
62
+ end
63
+
64
+ describe 'handling PUT to update with valid attributes' do
65
+ before(:each) do
66
+ @post = mock_model(Post, :title => 'A post')
67
+ @post.stub!(:update_attributes).and_return(true)
68
+
69
+ Post.stub!(:find).and_return(@post)
70
+ end
71
+
72
+ def do_put
73
+ put :update, :id => 1, :enki_post => valid_post_attributes
74
+ end
75
+
76
+ it 'updates the post' do
77
+ published_at = Time.now
78
+ @post.should_receive(:update_attributes).with(valid_post_attributes)
79
+ Time.stub!(:now).and_return(published_at)
80
+
81
+ do_put
82
+ end
83
+
84
+ it 'it redirects to show' do
85
+ do_put
86
+ response.should be_redirect
87
+ response.should redirect_to(admin_post_path(@post))
88
+ end
89
+ end
90
+
91
+ describe 'handling PUT to update with invalid attributes' do
92
+ before(:each) do
93
+ @post = create(:post)
94
+ Post.any_instance.stub(:update_attributes).and_return(false)
95
+
96
+ put :update, :id => @post.to_param, :enki_post => {}
97
+ end
98
+
99
+ it { should render_template('show') }
100
+ its(:status) { should be 422 }
101
+ end
102
+
103
+ describe 'handling POST to create with valid attributes' do
104
+ it 'creates a post' do
105
+ lambda { post :create, :enki_post => valid_post_attributes }.should change(Post, :count).by(1)
106
+ end
107
+ end
108
+
109
+ def valid_post_attributes
110
+ {
111
+ 'title' => "My Post",
112
+ 'body' => "hello this is my post",
113
+ 'minor_edit' => "0"
114
+ }
115
+ end
116
+
117
+ describe 'handling DELETE to destroy' do
118
+ before(:each) do
119
+ @post = Post.new
120
+ @post.stub!(:destroy_with_undo)
121
+ Post.stub!(:find).and_return(@post)
122
+ end
123
+
124
+ def do_delete
125
+ delete :destroy, :id => 1
126
+ end
127
+
128
+ it("redirects to index") do
129
+ do_delete
130
+ response.should be_redirect
131
+ response.should redirect_to(admin_posts_path)
132
+ end
133
+
134
+ it("deletes post") do
135
+ @post.should_receive(:destroy_with_undo)
136
+ do_delete
137
+ end
138
+ end
139
+
140
+ describe 'handling DELETE to destroy, JSON request' do
141
+ before(:each) do
142
+ @post = Post.new(:title => 'A post')
143
+ @post.stub!(:destroy_with_undo).and_return(mock_model(UndoItem, :description => 'hello'))
144
+ Post.stub!(:find).and_return(@post)
145
+ end
146
+
147
+ def do_delete
148
+ delete :destroy, :id => 1, :format => 'json'
149
+ end
150
+
151
+ it("deletes post") do
152
+ @post.should_receive(:destroy_with_undo).and_return(mock_model(UndoItem, :description => 'hello'))
153
+
154
+ do_delete
155
+ end
156
+
157
+ it("renders json including a description of the post") do
158
+ do_delete
159
+
160
+ JSON.parse(response.body)['undo_message'].should == 'hello'
161
+ end
162
+ end
163
+ end
164
+
165
+ describe Admin::PostsController, 'with an AJAX request to preview' do
166
+ before(:each) do
167
+ controller.stub!(:logged_in?).and_return(true)
168
+ @post = build(:post)
169
+ Post.should_receive(:build_for_preview).and_return(@post)
170
+
171
+ xhr :post, :preview, :enki_post => {
172
+ :title => 'My Post',
173
+ :body => 'body',
174
+ :tag_list => 'ruby',
175
+ :published_at => 'now'
176
+ }
177
+ end
178
+
179
+ it "assigns a new post for the view" do
180
+ assigns(:post).should == @post
181
+ end
182
+ end
183
+ end
@@ -0,0 +1,93 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+
3
+ module Enki
4
+
5
+ describe Admin::UndoItemsController do
6
+
7
+ before do
8
+ controller.stub!(:logged_in?).and_return(true)
9
+ end
10
+
11
+ describe 'handling GET to index' do
12
+ before(:each) do
13
+ @undo_items = [mock_model(UndoItem, :created_at => Time.now, :description => "hello", :id => 1)]
14
+ UndoItem.stub!(:find).and_return(@undo_items)
15
+
16
+ get :index
17
+ end
18
+
19
+ it("is successful") { response.should be_success }
20
+ it("renders index template") { response.should render_template('index') }
21
+ it("finds undo items for the view") { assigns[:undo_items].should == @undo_items }
22
+ end
23
+
24
+ describe 'handling POST to undo' do
25
+ before do
26
+ @item = mock_model(UndoItem, :complete_description => "hello")
27
+ @item.stub!(:process!)
28
+ UndoItem.stub!(:find).and_return(@item)
29
+ end
30
+
31
+ def do_post
32
+ request.env["HTTP_REFERER"] = "/bogus"
33
+
34
+ post :undo, :id => 1
35
+ end
36
+
37
+ it("redirects back") { do_post; response.should redirect_to("/bogus") }
38
+ it("stores complete_description in the flash") { do_post; flash[:notice].should == "hello" }
39
+ it("processes the item") { @item.should_receive(:process!); do_post }
40
+ end
41
+
42
+ describe 'handling POST to undo accepting JSON' do
43
+ before do
44
+ @item = mock_model(UndoItem, :complete_description => "hello")
45
+ @item.stub!(:process!).and_return(Post.new)
46
+ UndoItem.stub!(:find).and_return(@item)
47
+ end
48
+
49
+ def do_post
50
+ request.env["HTTP_REFERER"] = "/bogus"
51
+
52
+ post :undo, :id => 1, :format => 'json'
53
+ end
54
+
55
+ it("renders json") { do_post; response.should contain(/hello/) }
56
+ it("processes the item") { @item.should_receive(:process!); do_post }
57
+ end
58
+
59
+ describe 'handling POST to undo with invalid undo item' do
60
+ before do
61
+ @item = mock_model(UndoItem)
62
+ @item.stub!(:process!).and_raise(UndoFailed)
63
+ UndoItem.stub!(:find).and_return(@item)
64
+ end
65
+
66
+ def do_post
67
+ request.env["HTTP_REFERER"] = "/bogus"
68
+
69
+ post :undo, :id => 1
70
+ end
71
+
72
+ it("redirects back") { do_post; response.should redirect_to("/bogus") }
73
+ it("stores notice in the flash") { do_post; flash[:notice].should_not be_nil }
74
+ end
75
+
76
+ describe 'handling POST to undo with invalid undo item accepting JSON' do
77
+ before do
78
+ @item = mock_model(UndoItem)
79
+ @item.stub!(:process!).and_raise(UndoFailed)
80
+ UndoItem.stub!(:find).and_return(@item)
81
+ end
82
+
83
+ def do_post
84
+ request.env["HTTP_REFERER"] = "/bogus"
85
+
86
+ post :undo, :id => 1, :format => 'json'
87
+ end
88
+
89
+ it("renders json") { do_post; response.should contain(/message/) }
90
+ end
91
+ end
92
+
93
+ end
@@ -0,0 +1,37 @@
1
+ require 'spec_helper'
2
+
3
+ module Enki
4
+ describe ArchivesController do
5
+ describe 'handling GET to index' do
6
+ before(:each) do
7
+ month = Struct.new(:date, :posts)
8
+ @months = [ month.new( 1.month.ago.utc.beginning_of_month, [create(:post)] ) ]
9
+ Post.stub!(:find_all_grouped_by_month).and_return(@months)
10
+ end
11
+
12
+ it "should be successful" do
13
+ get :index
14
+
15
+ response.should be_success
16
+ end
17
+
18
+ it "should render index template" do
19
+ get :index
20
+
21
+ response.should render_template('index')
22
+ end
23
+
24
+ it "should assign the found months for the view" do
25
+ get :index
26
+
27
+ assigns[:months].should == @months
28
+ end
29
+
30
+ it 'should find posts grouped by month' do
31
+ Post.should_receive(:find_all_grouped_by_month).and_return(@months)
32
+
33
+ get :index
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,126 @@
1
+ require 'spec_helper'
2
+
3
+ module Enki
4
+
5
+ describe CommentsController, 'with GET to #index' do
6
+ include UrlHelper
7
+
8
+ it 'redirects to the parent post URL' do
9
+ @mock_post = mock_model(Post,
10
+ :published_at => 1.year.ago,
11
+ :slug => 'a-post'
12
+ )
13
+ Post.stub!(:find_by_permalink).and_return(@mock_post)
14
+ get :index, :year => '2007', :month => '01', :day => '01', :slug => 'a-post'
15
+ response.should be_redirect
16
+ response.should redirect_to(post_path(@mock_post))
17
+ end
18
+ end
19
+
20
+ shared_examples_for 'creating new comment' do
21
+ include UrlHelper
22
+
23
+ it 'assigns comment' do
24
+ assigns(:comment).should_not be_nil
25
+ end
26
+
27
+ it 'creates a new comment on the post' do
28
+ assigns(:comment).should_not be_new_record
29
+ end
30
+
31
+ it 'redirects to post' do
32
+ response.should be_redirect
33
+ response.should redirect_to(post_path(@mock_post))
34
+ end
35
+ end
36
+
37
+ shared_examples_for "invalid comment" do
38
+ it 'renders posts/show' do
39
+ response.should be_success
40
+ response.should render_template('posts/show')
41
+ end
42
+
43
+ it 'leaves comment in invalid state' do
44
+ assigns(:comment).should_not be_valid
45
+ end
46
+ end
47
+
48
+ describe CommentsController, 'handling commenting' do
49
+ def mock_post!
50
+ @mock_post = mock_model(Post)
51
+ {
52
+ :approved_comments => @mock_comments = [mock_model(Comment)],
53
+ :new_record? => false,
54
+ :published_at => 1.year.ago,
55
+ :created_at => 1.year.ago,
56
+ :denormalize_comments_count! => nil,
57
+ :slug => 'a-post',
58
+ :day => '01'
59
+ }.each_pair do |attribute, value|
60
+ @mock_post.stub!(attribute).and_return(value)
61
+ end
62
+ Post.stub!(:find_by_permalink).and_return(@mock_post)
63
+ @mock_post
64
+ end
65
+
66
+ describe "with a POST to #index (non-OpenID comment)" do
67
+ before(:each) do
68
+ mock_post!
69
+
70
+ post :create, :year => '2007', :month => '01', :day => '01', :slug => 'a-post', :comment => {
71
+ :author => 'Don Alias',
72
+ :body => 'This is a comment',
73
+
74
+ # Attributes you are not allowed to set
75
+ :author_url => 'http://www.enkiblog.com',
76
+ :author_email => 'donalias@enkiblog.com',
77
+ :created_at => @created_at = 1.year.ago,
78
+ :updated_at => @updated_at = 1.year.ago,
79
+ }
80
+ end
81
+
82
+
83
+ it "allows setting of author" do
84
+ assigns(:comment).author.should == 'Don Alias'
85
+ end
86
+
87
+ it "allows setting of body" do
88
+ assigns(:comment).body.should == 'This is a comment'
89
+ end
90
+
91
+ it "forbids setting of author_url" do
92
+ assigns(:comment).author_url.should be_blank
93
+ end
94
+
95
+ it "forbids setting of author_email" do
96
+ assigns(:comment).author_email.should be_blank
97
+ end
98
+
99
+ it "forbids setting of created_at" do
100
+ assigns(:comment).created_at.should_not == @created_at
101
+ end
102
+
103
+ it "forbids setting of updated_at" do
104
+ assigns(:comment).updated_at.should_not == @updated_at
105
+ end
106
+ end
107
+ end
108
+
109
+ describe CommentsController, 'with an AJAX request to new' do
110
+ before(:each) do
111
+ @comment = build(:comment, :created_at => Time.local(2007, 01, 01))
112
+ Comment.should_receive(:build_for_preview).and_return(@comment)
113
+
114
+ xhr :get, :new, :year => '2007', :month => '01', :day => '01', :slug => 'a-post', :comment => {
115
+ :author => 'Don Alias',
116
+ :body => 'A comment'
117
+ }
118
+ end
119
+
120
+ its(:response) { should be_success }
121
+ it "assigns a new comment for the view" do
122
+ assigns(:comment).should == @comment
123
+ end
124
+ end
125
+
126
+ end
@@ -0,0 +1,46 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ module Enki
4
+
5
+ describe PagesController do
6
+ describe 'handling GET for a single post' do
7
+ before(:each) do
8
+ @page = mock_model(Page)
9
+ Page.stub!(:find_by_slug).and_return(@page)
10
+ end
11
+
12
+ def do_get
13
+ get :show, :id => 'a-page'
14
+ end
15
+
16
+ it "should be successful" do
17
+ do_get
18
+ response.should be_success
19
+ end
20
+
21
+ it "should render show template" do
22
+ do_get
23
+ response.should render_template('show')
24
+ end
25
+
26
+ it 'should find the page requested' do
27
+ Page.should_receive(:find_by_slug).with('a-page').and_return(@page)
28
+ do_get
29
+ end
30
+
31
+ it 'should assign the page found for the view' do
32
+ do_get
33
+ assigns[:page].should equal(@page)
34
+ end
35
+ end
36
+
37
+ describe 'handling GET with invalid page' do
38
+ it 'raises a RecordNotFound error' do
39
+ Page.stub!(:find_by_slug).and_return(nil)
40
+ lambda {
41
+ get :show, :id => 'a-page'
42
+ }.should raise_error(ActiveRecord::RecordNotFound)
43
+ end
44
+ end
45
+ end
46
+ end