refinerycms-blog 1.8.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (215) hide show
  1. data/.gitignore +54 -0
  2. data/.rspec +3 -0
  3. data/.travis.yml +18 -0
  4. data/Gemfile +68 -5
  5. data/Guardfile +20 -0
  6. data/Rakefile +21 -0
  7. data/{public/images/refinerycms-blog → app/assets/images/refinery/blog}/icons/cog.png +0 -0
  8. data/{public/images/refinerycms-blog → app/assets/images/refinery/blog}/icons/comment.png +0 -0
  9. data/{public/images/refinerycms-blog → app/assets/images/refinery/blog}/icons/comment_cross.png +0 -0
  10. data/{public/images/refinerycms-blog → app/assets/images/refinery/blog}/icons/comment_tick.png +0 -0
  11. data/{public/images/refinerycms-blog → app/assets/images/refinery/blog}/icons/comments.png +0 -0
  12. data/{public/images/refinerycms-blog → app/assets/images/refinery/blog}/icons/down.gif +0 -0
  13. data/{public/images/refinerycms-blog → app/assets/images/refinery/blog}/icons/folder.png +0 -0
  14. data/{public/images/refinerycms-blog → app/assets/images/refinery/blog}/icons/folder_add.png +0 -0
  15. data/{public/images/refinerycms-blog → app/assets/images/refinery/blog}/icons/folder_edit.png +0 -0
  16. data/{public/images/refinerycms-blog → app/assets/images/refinery/blog}/icons/page.png +0 -0
  17. data/{public/images/refinerycms-blog → app/assets/images/refinery/blog}/icons/page_add.png +0 -0
  18. data/{public/images/refinerycms-blog → app/assets/images/refinery/blog}/icons/page_copy.png +0 -0
  19. data/{public/images/refinerycms-blog → app/assets/images/refinery/blog}/icons/up.gif +0 -0
  20. data/{public/images/refinerycms-blog → app/assets/images/refinery/blog}/rss-feed.png +0 -0
  21. data/app/assets/images/refinerycms-blog/.gitkeep +0 -0
  22. data/{public/javascripts/refinery/refinerycms-blog.js → app/assets/javascripts/refinery/blog/backend.js} +66 -1
  23. data/{public/javascripts/refinerycms-blog.js → app/assets/javascripts/refinery/blog/frontend.js} +0 -0
  24. data/app/assets/javascripts/refinerycms-blog/.gitkeep +0 -0
  25. data/app/assets/stylesheets/refinery/blog/backend.css.scss +73 -0
  26. data/{public/stylesheets/refinerycms-blog.css → app/assets/stylesheets/refinery/blog/frontend.css.scss} +3 -3
  27. data/{public/stylesheets → app/assets/stylesheets/refinery/blog}/ui-lightness/images/ui-bg_diagonals-thick_18_b81900_40x40.png +0 -0
  28. data/{public/stylesheets → app/assets/stylesheets/refinery/blog}/ui-lightness/images/ui-bg_diagonals-thick_20_666666_40x40.png +0 -0
  29. data/{public/stylesheets → app/assets/stylesheets/refinery/blog}/ui-lightness/images/ui-bg_flat_10_000000_40x100.png +0 -0
  30. data/{public/stylesheets → app/assets/stylesheets/refinery/blog}/ui-lightness/images/ui-bg_glass_100_f6f6f6_1x400.png +0 -0
  31. data/{public/stylesheets → app/assets/stylesheets/refinery/blog}/ui-lightness/images/ui-bg_glass_100_fdf5ce_1x400.png +0 -0
  32. data/{public/stylesheets → app/assets/stylesheets/refinery/blog}/ui-lightness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  33. data/{public/stylesheets → app/assets/stylesheets/refinery/blog}/ui-lightness/images/ui-bg_gloss-wave_35_f6a828_500x100.png +0 -0
  34. data/{public/stylesheets → app/assets/stylesheets/refinery/blog}/ui-lightness/images/ui-bg_highlight-soft_100_eeeeee_1x100.png +0 -0
  35. data/{public/stylesheets → app/assets/stylesheets/refinery/blog}/ui-lightness/images/ui-bg_highlight-soft_75_ffe45c_1x100.png +0 -0
  36. data/{public/stylesheets → app/assets/stylesheets/refinery/blog}/ui-lightness/images/ui-icons_222222_256x240.png +0 -0
  37. data/{public/stylesheets → app/assets/stylesheets/refinery/blog}/ui-lightness/images/ui-icons_228ef1_256x240.png +0 -0
  38. data/{public/stylesheets → app/assets/stylesheets/refinery/blog}/ui-lightness/images/ui-icons_ef8c08_256x240.png +0 -0
  39. data/{public/stylesheets → app/assets/stylesheets/refinery/blog}/ui-lightness/images/ui-icons_ffd27a_256x240.png +0 -0
  40. data/{public/stylesheets → app/assets/stylesheets/refinery/blog}/ui-lightness/images/ui-icons_ffffff_256x240.png +0 -0
  41. data/{public/stylesheets/ui-lightness/jquery-ui-1.8.13.custom.css → app/assets/stylesheets/refinery/blog/ui-lightness/jquery-ui-1.8.13.custom.css.scss} +0 -0
  42. data/app/assets/stylesheets/refinerycms-blog/.gitkeep +0 -0
  43. data/app/controllers/.gitkeep +0 -0
  44. data/app/controllers/refinery/blog/admin/categories_controller.rb +12 -0
  45. data/app/controllers/refinery/blog/admin/comments_controller.rb +49 -0
  46. data/app/controllers/refinery/blog/admin/posts_controller.rb +90 -0
  47. data/app/controllers/refinery/blog/admin/settings_controller.rb +55 -0
  48. data/app/controllers/refinery/blog/blog_controller.rb +17 -0
  49. data/app/controllers/refinery/blog/categories_controller.rb +12 -0
  50. data/app/controllers/refinery/blog/posts_controller.rb +84 -0
  51. data/app/helpers/.gitkeep +0 -0
  52. data/app/helpers/refinery/blog/controller_helper.rb +29 -0
  53. data/app/helpers/refinery/blog/posts_helper.rb +72 -0
  54. data/app/mailers/refinery/blog/comment_mailer.rb +14 -0
  55. data/app/models/.gitkeep +0 -0
  56. data/app/models/refinery/blog/category.rb +23 -0
  57. data/app/models/refinery/blog/comment.rb +135 -0
  58. data/app/models/refinery/blog/comment_mailer.rb +1 -0
  59. data/app/models/refinery/blog/post.rb +115 -0
  60. data/app/models/refinery/categorization.rb +9 -0
  61. data/app/sweepers/refinery/blog_sweeper.rb +26 -0
  62. data/app/views/.gitkeep +0 -0
  63. data/app/views/{admin/blog → refinery/blog/admin}/_submenu.html.erb +21 -21
  64. data/app/views/{admin/blog → refinery/blog/admin}/categories/_category.html.erb +3 -3
  65. data/app/views/{admin/blog → refinery/blog/admin}/categories/_form.html.erb +4 -4
  66. data/app/views/{admin/blog/comments → refinery/blog/admin/categories}/_sortable_list.html.erb +2 -2
  67. data/app/views/{admin/blog → refinery/blog/admin}/categories/edit.html.erb +0 -0
  68. data/app/views/refinery/blog/admin/categories/index.html.erb +27 -0
  69. data/app/views/{admin/blog → refinery/blog/admin}/categories/new.html.erb +0 -0
  70. data/app/views/{admin/blog → refinery/blog/admin}/comments/_comment.html.erb +4 -4
  71. data/app/views/{admin/blog/categories → refinery/blog/admin/comments}/_sortable_list.html.erb +2 -2
  72. data/app/views/refinery/blog/admin/comments/index.html.erb +30 -0
  73. data/app/views/refinery/blog/admin/comments/show.html.erb +63 -0
  74. data/app/views/{admin/blog → refinery/blog/admin}/posts/_form.html.erb +53 -39
  75. data/app/views/{admin/blog → refinery/blog/admin}/posts/_form_part.html.erb +0 -0
  76. data/app/views/{admin/blog → refinery/blog/admin}/posts/_post.html.erb +4 -7
  77. data/app/views/{admin/blog → refinery/blog/admin}/posts/_sortable_list.html.erb +2 -2
  78. data/app/views/{admin/blog → refinery/blog/admin}/posts/_teaser_part.html.erb +2 -2
  79. data/app/views/{admin/blog → refinery/blog/admin}/posts/edit.html.erb +0 -0
  80. data/app/views/refinery/blog/admin/posts/index.html.erb +27 -0
  81. data/app/views/{admin/blog → refinery/blog/admin}/posts/new.html.erb +0 -0
  82. data/app/views/refinery/blog/admin/posts/uncategorized.html.erb +27 -0
  83. data/app/views/{admin/blog → refinery/blog/admin}/settings/notification_recipients.html.erb +3 -3
  84. data/app/views/refinery/blog/categories/show.html.erb +21 -0
  85. data/app/views/{blog → refinery/blog}/comment_mailer/notification.html.erb +1 -1
  86. data/app/views/{blog → refinery/blog}/posts/_comment.html.erb +2 -2
  87. data/app/views/refinery/blog/posts/_comments.html.erb +40 -0
  88. data/app/views/refinery/blog/posts/_nav.html.erb +17 -0
  89. data/app/views/refinery/blog/posts/_post.html.erb +37 -0
  90. data/app/views/refinery/blog/posts/archive.html.erb +17 -0
  91. data/app/views/refinery/blog/posts/index.html.erb +20 -0
  92. data/app/views/refinery/blog/posts/index.rss.builder +17 -0
  93. data/app/views/refinery/blog/posts/show.html.erb +21 -0
  94. data/app/views/refinery/blog/posts/tagged.html.erb +19 -0
  95. data/app/views/refinery/blog/shared/_body_content_right.html.erb +9 -0
  96. data/app/views/{blog → refinery/blog}/shared/_categories.html.erb +3 -3
  97. data/app/views/{blog → refinery/blog}/shared/_post.html.erb +11 -11
  98. data/app/views/refinery/blog/shared/_posts.html.erb +10 -0
  99. data/app/views/refinery/blog/shared/_rss_feed.html.erb +2 -0
  100. data/app/views/{blog → refinery/blog}/shared/_tags.html.erb +1 -1
  101. data/app/views/refinery/blog/widgets/_blog_archive.html.erb +10 -0
  102. data/app/views/refinery/shared/admin/_autocomplete.html.erb +5 -0
  103. data/changelog.md +2 -18
  104. data/config/initializers/url_validator.rb +84 -0
  105. data/config/locales/bg.yml +139 -139
  106. data/config/locales/cs.yml +119 -119
  107. data/config/locales/de.yml +121 -121
  108. data/config/locales/en.yml +147 -140
  109. data/config/locales/es.yml +119 -150
  110. data/config/locales/fr.yml +136 -136
  111. data/config/locales/it.yml +139 -139
  112. data/config/locales/ja.yml +2 -3
  113. data/config/locales/nb.yml +28 -27
  114. data/config/locales/nl.yml +125 -125
  115. data/config/locales/pl.yml +125 -125
  116. data/config/locales/pt-BR.yml +129 -134
  117. data/config/locales/ru.yml +119 -126
  118. data/config/locales/sk.yml +119 -119
  119. data/config/locales/zh-CN.yml +119 -119
  120. data/config/routes.rb +37 -33
  121. data/db/migrate/20110803223522_create_blog_structure.rb +52 -0
  122. data/db/migrate/20110803223523_add_user_id_to_blog_posts.rb +7 -0
  123. data/db/migrate/{3_acts_as_taggable_on_migration.rb → 20110803223524_acts_as_taggable_on_migration.rb} +2 -2
  124. data/db/migrate/20110803223526_add_cached_slugs.rb +6 -0
  125. data/db/migrate/20110803223527_add_custom_url_field_to_blog_posts.rb +5 -0
  126. data/db/migrate/20110803223528_add_custom_teaser_field_to_blog_posts.rb +6 -0
  127. data/db/migrate/20110803223529_add_primary_key_to_categorizations.rb +14 -0
  128. data/db/migrate/20120103055909_add_source_url_to_blog_posts.rb +7 -0
  129. data/db/migrate/20120223022021_add_access_count_to_posts.rb +8 -0
  130. data/db/migrate/20120227022021_add_slug_to_posts_and_categories.rb +9 -0
  131. data/db/{seeds/refinerycms_blog.rb → seeds.rb} +6 -7
  132. data/lib/generators/refinery/blog/blog_generator.rb +27 -0
  133. data/lib/generators/refinery/blog/templates/config/initializers/refinery/blog.rb.erb +11 -0
  134. data/lib/refinery/blog.rb +37 -0
  135. data/lib/refinery/blog/configuration.rb +14 -0
  136. data/lib/refinery/blog/engine.rb +25 -0
  137. data/lib/refinery/blog/tabs.rb +5 -11
  138. data/lib/refinery/blog/version.rb +3 -3
  139. data/lib/refinerycms-blog.rb +1 -41
  140. data/readme.md +24 -15
  141. data/refinerycms-blog.gemspec +19 -196
  142. data/script/rails +6 -0
  143. data/spec/factories/blog_categories.rb +5 -0
  144. data/spec/factories/blog_comments.rb +19 -0
  145. data/spec/factories/blog_posts.rb +13 -0
  146. data/spec/helpers/refinery/blog/posts_helper_spec.rb +71 -0
  147. data/spec/lib/refinery/blog/engine_spec.rb +26 -0
  148. data/spec/models/refinery/blog/category_spec.rb +42 -0
  149. data/spec/models/refinery/blog/comment_spec.rb +19 -0
  150. data/spec/models/refinery/blog/post_spec.rb +233 -0
  151. data/spec/requests/refinery/blog/admin/categories_spec.rb +20 -0
  152. data/spec/requests/refinery/blog/admin/comments_spec.rb +121 -0
  153. data/spec/requests/refinery/blog/admin/menu_spec.rb +13 -0
  154. data/spec/requests/refinery/blog/admin/posts_spec.rb +175 -0
  155. data/spec/requests/refinery/blog/categories_spec.rb +24 -0
  156. data/spec/requests/refinery/blog/posts_spec.rb +160 -0
  157. data/spec/spec_helper.rb +56 -0
  158. data/tasks/rspec.rake +4 -0
  159. data/tasks/testing.rake +9 -0
  160. metadata +281 -170
  161. data/app/controllers/admin/blog/categories_controller.rb +0 -11
  162. data/app/controllers/admin/blog/comments_controller.rb +0 -40
  163. data/app/controllers/admin/blog/posts_controller.rb +0 -97
  164. data/app/controllers/admin/blog/settings_controller.rb +0 -53
  165. data/app/controllers/blog/categories_controller.rb +0 -13
  166. data/app/controllers/blog/posts_controller.rb +0 -109
  167. data/app/controllers/blog_controller.rb +0 -16
  168. data/app/helpers/blog_posts_helper.rb +0 -56
  169. data/app/mailers/blog/comment_mailer.rb +0 -13
  170. data/app/models/blog/comment_mailer.rb +0 -1
  171. data/app/models/blog_category.rb +0 -19
  172. data/app/models/blog_comment.rb +0 -137
  173. data/app/models/blog_post.rb +0 -114
  174. data/app/models/categorization.rb +0 -7
  175. data/app/views/admin/blog/categories/index.html.erb +0 -26
  176. data/app/views/admin/blog/comments/index.html.erb +0 -35
  177. data/app/views/admin/blog/comments/show.html.erb +0 -63
  178. data/app/views/admin/blog/posts/_form.css.erb +0 -20
  179. data/app/views/admin/blog/posts/_form.js.erb +0 -23
  180. data/app/views/admin/blog/posts/index.html.erb +0 -28
  181. data/app/views/admin/blog/posts/uncategorized.html.erb +0 -26
  182. data/app/views/blog/categories/show.html.erb +0 -21
  183. data/app/views/blog/posts/_nav.html.erb +0 -11
  184. data/app/views/blog/posts/archive.html.erb +0 -20
  185. data/app/views/blog/posts/index.html.erb +0 -24
  186. data/app/views/blog/posts/index.rss.builder +0 -17
  187. data/app/views/blog/posts/show.html.erb +0 -98
  188. data/app/views/blog/posts/tagged.html.erb +0 -22
  189. data/app/views/blog/shared/_archive_list.html.erb +0 -9
  190. data/app/views/blog/shared/_related_posts.html.erb +0 -10
  191. data/app/views/blog/shared/_rss_feed.html.erb +0 -2
  192. data/app/views/shared/admin/_autocomplete.html.erb +0 -55
  193. data/db/migrate/1_create_blog_structure.rb +0 -54
  194. data/db/migrate/2_add_user_id_to_blog_posts.rb +0 -11
  195. data/db/migrate/4_create_seo_meta_for_blog.rb +0 -25
  196. data/db/migrate/5_add_cached_slugs.rb +0 -11
  197. data/db/migrate/6_add_custom_url_field_to_blog_posts.rb +0 -9
  198. data/db/migrate/7_add_custom_teaser_field_to_blog_posts.rb +0 -10
  199. data/db/migrate/8_add_primary_key_to_categorizations.rb +0 -12
  200. data/features/authors.feature +0 -15
  201. data/features/category.feature +0 -23
  202. data/features/support/factories/blog_categories.rb +0 -5
  203. data/features/support/factories/blog_comments.rb +0 -8
  204. data/features/support/factories/blog_posts.rb +0 -9
  205. data/features/support/paths.rb +0 -24
  206. data/features/support/step_definitions/authors_steps.rb +0 -7
  207. data/features/support/step_definitions/category_steps.rb +0 -11
  208. data/features/support/step_definitions/tags_steps.rb +0 -13
  209. data/features/tags.feature +0 -26
  210. data/lib/gemspec.rb +0 -37
  211. data/lib/generators/refinerycms_blog_generator.rb +0 -8
  212. data/public/stylesheets/refinery/refinerycms-blog.css +0 -55
  213. data/spec/models/blog_category_spec.rb +0 -41
  214. data/spec/models/blog_comment_spec.rb +0 -21
  215. data/spec/models/blog_post_spec.rb +0 -217
@@ -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,5 @@
1
+ FactoryGirl.define do
2
+ factory :blog_category, :class => Refinery::Blog::Category do
3
+ sequence(:title) { |n| "Shopping #{n}" }
4
+ end
5
+ end
@@ -0,0 +1,19 @@
1
+ FactoryGirl.define do
2
+ factory :blog_comment, :class => Refinery::Blog::Comment do
3
+ name "Joe Commenter"
4
+ sequence(:email) { |n| "person#{n}@example.com" }
5
+ body "Which one is the best for picking up new shoes?"
6
+ association :post, :factory => :blog_post
7
+
8
+ trait :approved do
9
+ state 'approved'
10
+ end
11
+
12
+ trait :rejected do
13
+ state 'rejected'
14
+ end
15
+
16
+ factory :approved_comment, :traits => [:approved]
17
+ factory :rejected_comment, :traits => [:rejected]
18
+ end
19
+ end
@@ -0,0 +1,13 @@
1
+ FactoryGirl.define do
2
+ factory :blog_post, :class => Refinery::Blog::Post do
3
+ sequence(:title) { |n| "Top #{n} Shopping Centers in Chicago" }
4
+ body "These are the top ten shopping centers in Chicago. You're going to read a long blog post about them. Come to peace with it."
5
+ draft false
6
+ tag_list "chicago, shopping, fun times"
7
+ published_at Time.now
8
+
9
+ factory :blog_post_draft do
10
+ draft true
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,71 @@
1
+ require 'spec_helper'
2
+
3
+ module Refinery
4
+ module Blog
5
+ describe PostsHelper do
6
+ describe "#blog_archive_widget" do
7
+ let(:html) { helper.blog_archive_widget(dates) }
8
+ let(:links) { Capybara.string(html).find("#blog_archive_widget ul") }
9
+
10
+ context "with no archive dates" do
11
+ let(:dates) { [] }
12
+
13
+ it "does not display anything" do
14
+ html.should be_blank
15
+ end
16
+ end
17
+
18
+ context "with archive dates" do
19
+ let(:recent_post) { 2.months.ago }
20
+ let(:old_post) { 4.years.ago }
21
+
22
+ let(:dates) do
23
+ [old_post, recent_post].map do |date|
24
+ [date, date.beginning_of_month, date.end_of_month]
25
+ end.flatten
26
+ end
27
+
28
+ it "has a link for the month of dates not older than one year" do
29
+ month = Date::MONTHNAMES[recent_post.month]
30
+ year = recent_post.year
31
+
32
+ links.should have_link("#{month} #{year} (3)")
33
+ end
34
+
35
+ it "has a link for the year of dates older than one year" do
36
+ year = old_post.year
37
+
38
+ links.should have_link("#{year} (3)")
39
+ end
40
+
41
+ it "sorts recent links before old links" do
42
+ links.find("li:first").should have_content(recent_post.year.to_s)
43
+ links.find("li:last").should have_content(old_post.year.to_s)
44
+ end
45
+ end
46
+
47
+ context "with multiple recent dates" do
48
+ let(:dates) { [3.months.ago, 2.months.ago] }
49
+
50
+ it "sorts by the more recent date" do
51
+ first, second = dates.map {|p| Date::MONTHNAMES[p.month] }
52
+
53
+ links.find("li:first").should have_content(second)
54
+ links.find("li:last").should have_content(first)
55
+ end
56
+ end
57
+
58
+ context "with multiple old dates" do
59
+ let(:dates) { [5.years.ago, 4.years.ago] }
60
+
61
+ it "sorts by the more recent date" do
62
+ first, second = dates.map {|p| p.year.to_s }
63
+
64
+ links.find("li:first").should have_content(second)
65
+ links.find("li:last").should have_content(first)
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,26 @@
1
+ require 'spec_helper'
2
+
3
+ module Refinery
4
+ module Blog
5
+ describe Engine do
6
+ describe "plugin activity" do
7
+ let(:activity) do
8
+ Refinery::Plugins.registered.find_by_name("refinerycms_blog").activity.first
9
+ end
10
+
11
+ it "sets the correct path for activity entries" do
12
+ activity.url.should eq("refinery.edit_blog_admin_post_path")
13
+ end
14
+ end
15
+
16
+ describe ".load_seed" do
17
+ it "is idempotent" do
18
+ Engine.load_seed
19
+ Engine.load_seed
20
+
21
+ Refinery::Page.where(:link_url => '/blog').count.should eq(1)
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,42 @@
1
+ require 'spec_helper'
2
+
3
+ module Refinery
4
+ module Blog
5
+ describe Category do
6
+ let(:category) { FactoryGirl.create(:blog_category) }
7
+
8
+ describe "validations" do
9
+ it "requires title" do
10
+ FactoryGirl.build(:blog_category, :title => "").should_not be_valid
11
+ end
12
+
13
+ it "won't allow duplicate titles" do
14
+ FactoryGirl.build(:blog_category, :title => category.title).should_not be_valid
15
+ end
16
+ end
17
+
18
+ describe "blog posts association" do
19
+ it "has a posts attribute" do
20
+ category.should respond_to(:posts)
21
+ end
22
+
23
+ it "returns posts by published_at date in descending order" do
24
+ first_post = category.posts.create!({ :title => "Breaking News: Joe Sak is hot stuff you guys!!", :body => "True story.", :published_at => Time.now.yesterday })
25
+ latest_post = category.posts.create!({ :title => "parndt is p. okay", :body => "For a Kiwi.", :published_at => Time.now })
26
+
27
+ category.posts.first.should == latest_post
28
+ end
29
+
30
+ end
31
+
32
+ describe "#post_count" do
33
+ it "returns post count in category" do
34
+ 2.times do
35
+ category.posts << FactoryGirl.create(:blog_post)
36
+ end
37
+ category.post_count.should == 2
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,19 @@
1
+ require 'spec_helper'
2
+
3
+ module Refinery
4
+ module Blog
5
+ describe Comment do
6
+ context "wiring up" do
7
+ let(:comment) { FactoryGirl.create(:blog_comment) }
8
+
9
+ it "saves" do
10
+ comment.should_not be_nil
11
+ end
12
+
13
+ it "has a blog post" do
14
+ comment.post.should_not be_nil
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,233 @@
1
+ require 'spec_helper'
2
+
3
+ module Refinery
4
+ module Blog
5
+ describe Post do
6
+ let(:post) { FactoryGirl.create(:blog_post) }
7
+
8
+ describe "validations" do
9
+ it "requires title" do
10
+ FactoryGirl.build(:blog_post, :title => "").should_not be_valid
11
+ end
12
+
13
+ it "won't allow duplicate titles" do
14
+ FactoryGirl.build(:blog_post, :title => post.title).should_not be_valid
15
+ end
16
+
17
+ it "requires body" do
18
+ FactoryGirl.build(:blog_post, :body => nil).should_not be_valid
19
+ end
20
+ end
21
+
22
+ describe "comments association" do
23
+
24
+ it "have a comments attribute" do
25
+ post.should respond_to(:comments)
26
+ end
27
+
28
+ it "destroys associated comments" do
29
+ FactoryGirl.create(:blog_comment, :blog_post_id => post.id)
30
+ post.destroy
31
+ Blog::Comment.where(:blog_post_id => post.id).should be_empty
32
+ end
33
+ end
34
+
35
+ describe "categories association" do
36
+ it "have categories attribute" do
37
+ post.should respond_to(:categories)
38
+ end
39
+ end
40
+
41
+ describe "tags" do
42
+ it "acts as taggable" do
43
+ post.should respond_to(:tag_list)
44
+
45
+ #the factory has default tags, including 'chicago'
46
+ post.tag_list.should include("chicago")
47
+ end
48
+ end
49
+
50
+ describe "authors" do
51
+ it "are authored" do
52
+ described_class.instance_methods.map(&:to_sym).should include(:author)
53
+ end
54
+ end
55
+
56
+ describe "by_archive" do
57
+ before do
58
+ @post1 = FactoryGirl.create(:blog_post, :published_at => Date.new(2011, 3, 11))
59
+ @post2 = FactoryGirl.create(:blog_post, :published_at => Date.new(2011, 3, 12))
60
+
61
+ #2 months before
62
+ FactoryGirl.create(:blog_post, :published_at => Date.new(2011, 1, 10))
63
+ end
64
+
65
+ it "returns all posts from specified month" do
66
+ #check for this month
67
+ date = "03/2011"
68
+ described_class.by_archive(Time.parse(date)).count.should be == 2
69
+ described_class.by_archive(Time.parse(date)).should == [@post2, @post1]
70
+ end
71
+ end
72
+
73
+ describe ".published_dates_older_than" do
74
+ before do
75
+ @post1 = FactoryGirl.create(:blog_post, :published_at => Time.now - 2.months)
76
+ @post2 = FactoryGirl.create(:blog_post, :published_at => Time.now - 1.month)
77
+ FactoryGirl.create(:blog_post, :published_at => Time.now)
78
+ end
79
+
80
+ it "returns all published dates older than the argument" do
81
+ expected = [@post2.published_at, @post1.published_at]
82
+
83
+ described_class.published_dates_older_than(1.day.ago).should eq(expected)
84
+ end
85
+ end
86
+
87
+ describe "live" do
88
+ before do
89
+ @post1 = FactoryGirl.create(:blog_post, :published_at => Time.now.advance(:minutes => -2))
90
+ @post2 = FactoryGirl.create(:blog_post, :published_at => Time.now.advance(:minutes => -1))
91
+ FactoryGirl.create(:blog_post, :draft => true)
92
+ FactoryGirl.create(:blog_post, :published_at => Time.now + 1.minute)
93
+ end
94
+
95
+ it "returns all posts which aren't in draft and pub date isn't in future" do
96
+ described_class.live.count.should be == 2
97
+ described_class.live.should == [@post2, @post1]
98
+ end
99
+ end
100
+
101
+ describe "uncategorized" do
102
+ before do
103
+ @uncategorized_post = FactoryGirl.create(:blog_post)
104
+ @categorized_post = FactoryGirl.create(:blog_post)
105
+
106
+ @categorized_post.categories << FactoryGirl.create(:blog_category)
107
+ end
108
+
109
+ it "returns uncategorized posts if they exist" do
110
+ described_class.uncategorized.should include @uncategorized_post
111
+ described_class.uncategorized.should_not include @categorized_post
112
+ end
113
+ end
114
+
115
+ describe "#live?" do
116
+ it "returns true if post is not in draft and it's published" do
117
+ Factory.build(:blog_post).should be_live
118
+ end
119
+
120
+ it "returns false if post is in draft" do
121
+ Factory.build(:blog_post, :draft => true).should_not be_live
122
+ end
123
+
124
+ it "returns false if post pub date is in future" do
125
+ Factory.build(:blog_post, :published_at => Time.now.advance(:minutes => 1)).should_not be_live
126
+ end
127
+ end
128
+
129
+ describe "#next" do
130
+ before do
131
+ FactoryGirl.create(:blog_post, :published_at => Time.now.advance(:minutes => -1))
132
+ @post = FactoryGirl.create(:blog_post)
133
+ end
134
+
135
+ it "returns next article when called on current article" do
136
+ described_class.last.next.should == @post
137
+ end
138
+ end
139
+
140
+ describe "#prev" do
141
+ before do
142
+ FactoryGirl.create(:blog_post)
143
+ @post = FactoryGirl.create(:blog_post, :published_at => Time.now.advance(:minutes => -1))
144
+ end
145
+
146
+ it "returns previous article when called on current article" do
147
+ described_class.first.prev.should == @post
148
+ end
149
+ end
150
+
151
+ describe ".comments_allowed?" do
152
+ context "with Refinery::Setting comments_allowed set to true" do
153
+ before do
154
+ Refinery::Setting.set(:comments_allowed, { :scoping => 'blog', :value => true })
155
+ end
156
+
157
+ it "should be true" do
158
+ described_class.comments_allowed?.should be_true
159
+ end
160
+ end
161
+
162
+ context "with Refinery::Setting comments_allowed set to false" do
163
+ before do
164
+ Refinery::Setting.set(:comments_allowed, { :scoping => 'blog', :value => false })
165
+ end
166
+
167
+ it "should be false" do
168
+ described_class.comments_allowed?.should be_false
169
+ end
170
+ end
171
+ end
172
+
173
+ describe "custom teasers" do
174
+ it "should allow a custom teaser" do
175
+ FactoryGirl.create(:blog_post, :custom_teaser => 'This is some custom content').should be_valid
176
+ end
177
+ end
178
+
179
+ describe ".teasers_enabled?" do
180
+ context "with Refinery::Setting teasers_enabled set to true" do
181
+ before do
182
+ Refinery::Setting.set(:teasers_enabled, { :scoping => 'blog', :value => true })
183
+ end
184
+
185
+ it "should be true" do
186
+ described_class.teasers_enabled?.should be_true
187
+ end
188
+ end
189
+
190
+ context "with Refinery::Setting teasers_enabled set to false" do
191
+ before do
192
+ Refinery::Setting.set(:teasers_enabled, { :scoping => 'blog', :value => false })
193
+ end
194
+
195
+ it "should be false" do
196
+ described_class.teasers_enabled?.should be_false
197
+ end
198
+ end
199
+ end
200
+
201
+ describe "source url" do
202
+ it "should allow a source url and title" do
203
+ p = FactoryGirl.create(:blog_post, :source_url => 'google.com', :source_url_title => 'author')
204
+ p.should be_valid
205
+ p.source_url.should include('google')
206
+ p.source_url_title.should include('author')
207
+ end
208
+ end
209
+
210
+ describe ".validate_source_url?" do
211
+ context "with Refinery::Blog.validate_source_url set to true" do
212
+ before do
213
+ Refinery::Blog.validate_source_url = true
214
+ end
215
+ it "should have canonical url" do
216
+ p = FactoryGirl.create(:blog_post, :source_url => 'google.com', :source_url_title => 'google')
217
+ p.source_url.should include('www')
218
+ end
219
+ end
220
+ context "with Refinery::Blog.validate_source_url set to false" do
221
+ before do
222
+ Refinery::Blog.validate_source_url = false
223
+ end
224
+ it "should have original url" do
225
+ p = FactoryGirl.create(:blog_post, :source_url => 'google.com', :source_url_title => 'google')
226
+ p.source_url.should_not include('www')
227
+ end
228
+ end
229
+ end
230
+
231
+ end
232
+ end
233
+ end
@@ -0,0 +1,20 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Categories admin" do
4
+ login_refinery_user
5
+
6
+ let(:title) { "lol" }
7
+
8
+ it "can create categories" do
9
+ visit refinery.admin_root_path
10
+
11
+ within("nav#menu") { click_link "Blog" }
12
+ within("nav.multilist") { click_link "Create new category" }
13
+
14
+ fill_in "Title", :with => title
15
+ click_button "Save"
16
+
17
+ category = Refinery::Blog::Category.first
18
+ category.title.should eq(title)
19
+ end
20
+ end