adva_blog 0.0.1

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 (43) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/Gemfile +4 -0
  4. data/LICENSE +22 -0
  5. data/README.md +29 -0
  6. data/Rakefile +2 -0
  7. data/adva_blog.gemspec +17 -0
  8. data/app/controllers/admin/blog/articles_controller.rb +5 -0
  9. data/app/controllers/admin/blog/categories_controller.rb +1 -0
  10. data/app/controllers/admin/blog/contents_controller.rb +5 -0
  11. data/app/controllers/admin/blogs_controller.rb +1 -0
  12. data/app/controllers/blog_articles_controller.rb +23 -0
  13. data/app/helpers/blog_helper.rb +49 -0
  14. data/app/models/blog.rb +34 -0
  15. data/app/views/admin/blog/articles/index.html.erb +40 -0
  16. data/app/views/admin/sections/settings/_blog.html.erb +11 -0
  17. data/app/views/blogs/articles/_article.html.erb +28 -0
  18. data/app/views/blogs/articles/_footer.html.erb +40 -0
  19. data/app/views/blogs/articles/index.atom.builder +21 -0
  20. data/app/views/blogs/articles/index.html.erb +4 -0
  21. data/app/views/blogs/articles/show.html.erb +14 -0
  22. data/config/initializers/base_controller.rb +3 -0
  23. data/config/routes.rb +49 -0
  24. data/lib/adva_blog.rb +10 -0
  25. data/lib/adva_blog/version.rb +3 -0
  26. data/test/contexts.rb +9 -0
  27. data/test/fixtures.rb +50 -0
  28. data/test/functional/blog_articles_controller_test.rb +139 -0
  29. data/test/functional/blog_articles_routes_test.rb +159 -0
  30. data/test/integration/admin/blog_article_test.rb +54 -0
  31. data/test/integration/admin/blog_ping_test.rb +68 -0
  32. data/test/integration/admin/blog_test.rb +43 -0
  33. data/test/integration/blog_article_test.rb +40 -0
  34. data/test/integration/blog_categories_test.rb +55 -0
  35. data/test/integration/blog_comment_test.rb +51 -0
  36. data/test/integration/blog_index_test.rb +104 -0
  37. data/test/test_helper.rb +2 -0
  38. data/test/unit/cells/blog_cell_test.rb +29 -0
  39. data/test/unit/helpers/blog_helper_test.rb +50 -0
  40. data/test/unit/helpers/content_helper_test.rb +19 -0
  41. data/test/unit/models/blog_test.rb +37 -0
  42. data/test/unit/models/counter_test.rb +44 -0
  43. metadata +101 -0
@@ -0,0 +1,10 @@
1
+ # require "adva_blog/version"
2
+ require "rails"
3
+
4
+ module AdvaBlog
5
+ class Engine < Rails::Engine
6
+ initializer "adva_blog.init" do
7
+ Section.register_type 'Blog'
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,3 @@
1
+ module AdvaBlog
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,9 @@
1
+ class Test::Unit::TestCase
2
+ share :a_blog do
3
+ before do
4
+ @section = Blog.find_by_permalink 'a-blog'
5
+ @site = @section.site
6
+ set_request_host!
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,50 @@
1
+ user = User.find_by_first_name('a user')
2
+ admin = User.find_by_first_name('an admin')
3
+ moderator = User.find_by_first_name('a moderator')
4
+
5
+ site = Site.create! :name => 'site with blog',
6
+ :title => 'site with blog title',
7
+ :host => 'site-with-blog.com'
8
+
9
+ blog = Blog.create! :site => site,
10
+ :title => 'a blog',
11
+ :permalink => 'a-blog',
12
+ :comment_age => 0,
13
+ :published_at => Time.parse('2008-01-01 12:00:00')
14
+
15
+ category = Category.create! :section => blog,
16
+ :title => 'a category'
17
+
18
+ Category.create! :section => blog,
19
+ :title => 'another category'
20
+
21
+ Category.create! :section => blog,
22
+ :title => 'öäü'
23
+
24
+ Category.create! :section => blog,
25
+ :title => '$%&'
26
+
27
+ article = Article.create! :site => site,
28
+ :section => blog,
29
+ :title => 'a blog article',
30
+ :body => 'a blog article body',
31
+ :categories => [category],
32
+ :tag_list => 'foo bar',
33
+ :author => user,
34
+ :published_at => Time.parse('2008-01-01 12:00:00')
35
+
36
+ Article.create! :site => site,
37
+ :section => blog,
38
+ :title => 'an unpublished blog article',
39
+ :body => 'an unpublished blog article body',
40
+ :categories => [category],
41
+ :tag_list => 'foo bar',
42
+ :author => user
43
+
44
+ attributes = { :site => site, :section => blog, :commentable => article, :author => user }
45
+ Comment.create! attributes.merge(:body => 'the approved comment body', :approved => 1)
46
+ Comment.create! attributes.merge(:body => 'the unapproved comment body', :approved => 0)
47
+
48
+ admin.roles.create!(:name => 'admin', :context => site)
49
+ moderator.roles.create!(:name => 'moderator', :context => blog)
50
+
@@ -0,0 +1,139 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/../test_helper")
2
+
3
+ class BlogArticlesControllerTest < ActionController::TestCase
4
+ tests BlogArticlesController
5
+ with_common :a_blog, :a_category, :an_article
6
+
7
+ test "is an BaseController" do
8
+ @controller.should be_kind_of(BaseController)
9
+ end
10
+
11
+ { :blog_paths => %w( /a-blog
12
+ /a-blog/2008
13
+ /a-blog/2008/1 ),
14
+ :blog_category_paths => %w( /a-blog/categories/a-category
15
+ /a-blog/categories/a-category/2008
16
+ /a-blog/categories/a-category/2008/1 ),
17
+ :blog_tag_paths => %w( /a-blog/tags/foo+bar ),
18
+ :blog_feed_paths => %w( /a-blog.atom
19
+ /a-blog/categories/a-category.atom
20
+ /a-blog/tags/foo+bar.atom ),
21
+ :blog_comment_feed_paths => %w( /a-blog/comments.atom
22
+ /a-blog/2008/1/1/a-blog-article.atom ) }.each do |type, paths|
23
+
24
+ paths.each { |path| With.share(type) { before { @params = params_from path } } }
25
+ end
26
+
27
+ describe "GET to :index" do
28
+ action { get :index, @params }
29
+
30
+ with [:blog_paths, :blog_category_paths, :blog_tag_paths] do
31
+ it_assigns :section, :articles
32
+ it_caches_the_page :track => ['@article', '@articles', '@category', {'@site' => :tag_counts, '@section' => :tag_counts}]
33
+
34
+ it_assigns :category, :in => :blog_category_paths
35
+ it_assigns :tags, %(foo bar), :in => :blog_tag_paths
36
+
37
+ it_renders :template, :index
38
+ end
39
+
40
+ with "a blog path" do
41
+ # splitting this off so we do not test all these combinations on any of the paths above
42
+ before { @params = params_from('/a-blog') }
43
+
44
+ it "displays the article" do
45
+ has_tag('div[class~=entry]') { has_permalink @article }
46
+ end
47
+
48
+ it "shows the excerpt", :with => :article_has_an_excerpt do
49
+ does_not_have_text 'article body'
50
+ has_text 'article excerpt'
51
+ has_tag 'a', /read the rest of this entry/i
52
+ end
53
+
54
+ it "shows the body", :with => :article_has_no_excerpt do
55
+ has_text 'article body'
56
+ does_not_have_text 'article excerpt'
57
+ has_tag 'a', :text => /read the rest of this entry/i, :count => 0
58
+ end
59
+
60
+ it "displays the number of comments and links to them", :with => :comments_or_commenting_allowed do
61
+ has_tag 'div.meta a', /\d comment[s]?/i
62
+ end
63
+
64
+ it "does not display the number of comments", :with => :no_comments_and_commenting_not_allowed do
65
+ has_tag 'div.meta a', :text => /\d comment[s]?/, :count => 0
66
+ end
67
+
68
+ has_tag 'div[id=footer]', :if => :default_theme do
69
+ has_tag 'ul[id=categories_list]'
70
+ has_tag 'ul[id=archives]'
71
+ # has_tag 'ul[id=tags-list]' # FIXME currently tags are not displayed
72
+ end
73
+ end
74
+
75
+ with :blog_feed_paths do
76
+ it_assigns :section, :articles
77
+ it_renders :template, :index, :format => :atom
78
+ end
79
+ end
80
+
81
+ describe "GET to :show" do
82
+ action { get :show, {:section_id => @section.id}.merge(@article.full_permalink) }
83
+
84
+ with :the_article_is_published do
85
+ it_assigns :section, :article
86
+ it_caches_the_page :track => ['@article', '@articles', '@category', {'@site' => :tag_counts, '@section' => :tag_counts}]
87
+
88
+ it_renders :template, :show do
89
+ has_tag 'div[class~=entry]' do
90
+ # displays the title and links it to the article
91
+ has_permalink @article
92
+
93
+ # displays excerpt and body
94
+ has_text @article.excerpt
95
+ has_text @article.body
96
+
97
+ # displays an edit link for authorized users
98
+ has_authorized_tag 'a[href=?]', edit_admin_article_path(@site, @section, @article), /edit/i
99
+
100
+ # does not display a 'read more' link
101
+ assert @response.body !~ /read the rest of this entry/i
102
+
103
+ # FIXME
104
+ # lists the article's categories
105
+ # lists the article's tags
106
+ end
107
+ end
108
+
109
+ # FIXME
110
+ # when article has an approved comment: shows the comment
111
+ # when article has an unapproved comment: does not show any comments
112
+ # when article does not have any comments: does not show any comments
113
+ #
114
+ # when article allows commenting: shows comment form
115
+ # when article does not allow commenting: does not show comment form
116
+ end
117
+
118
+ # FIXME
119
+ # with "the article is not published" do
120
+ # when the user does not have edit permissions: 404, raises ActiveRecord::RecordNotFound
121
+ # when the user has edit permissions: renders show template, does not cache the page
122
+ # end
123
+
124
+ # FIXME
125
+ # with a permalink that does not point to an article: raises ActiveRecord::RecordNotFound
126
+ end
127
+
128
+ describe "GET to :comments" do
129
+ action { get :comments, @params }
130
+
131
+ with :the_article_is_published do
132
+ with :blog_comment_feed_paths do
133
+ # FIXME it_caches_the_page ...
134
+ it_assigns :section, :comments
135
+ it_renders :template, 'comments/comments', :format => :atom
136
+ end
137
+ end
138
+ end
139
+ end
@@ -0,0 +1,159 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/../test_helper")
2
+
3
+ class BlogArticlesRoutesTest < ActionController::TestCase
4
+ tests BlogArticlesController
5
+ with_common :default_routing_filters, :a_blog, :a_category, :an_article
6
+
7
+ # FIXME /blogs/1 is regenerated as /sections/1
8
+ paths = %W( /blogs/1/2007
9
+ /blogs/1/2007/1
10
+ /blogs/1/categories/a-category
11
+ /blogs/1/categories/a-category/2007
12
+ /blogs/1/categories/a-category/2007/1
13
+ /blogs/1/categories/a-category.atom
14
+ /blogs/1/tags/foo+bar
15
+ /blogs/1/tags/foo+bar/2007
16
+ /blogs/1/tags/foo+bar/2007/1
17
+ /blogs/1/tags/foo+bar.atom )
18
+
19
+ paths.each do |path|
20
+ test "regenerates the original path from the recognized params for #{path}" do
21
+ without_routing_filters do
22
+ params = ActionController::Routing::Routes.recognize_path(path, :method => :get)
23
+ assert_equal path, @controller.url_for(params.merge(:only_path => true))
24
+ end
25
+ end
26
+ end
27
+
28
+ describe "routing" do
29
+ ['', '/a-blog', '/de', '/de/a-blog'].each do |path_prefix|
30
+ ['', '/pages/2'].each do |path_suffix|
31
+
32
+ common = { :section_id => Blog.first.id.to_s, :path_prefix => path_prefix, :path_suffix => path_suffix }
33
+ common.merge! :locale => 'de' if path_prefix =~ /de/
34
+ common.merge! :page => 2 if path_suffix =~ /pages/
35
+
36
+ with_options common do |r|
37
+ r.it_maps :get, '/', :action => 'index'
38
+ r.it_maps :get, '/2000', :action => 'index', :year => '2000'
39
+ r.it_maps :get, '/2000/1', :action => 'index', :year => '2000', :month => '1'
40
+
41
+ r.it_maps :get, '/categories/foo', :action => 'index', :category_id => 'foo'
42
+ r.it_maps :get, '/categories/foo/2000', :action => 'index', :category_id => 'foo', :year => '2000'
43
+ r.it_maps :get, '/categories/foo/2000/1', :action => 'index', :category_id => 'foo', :year => '2000', :month => '1'
44
+
45
+ r.it_maps :get, '/tags/foo+bar', :action => 'index', :tags => 'foo+bar'
46
+ r.it_maps :get, '/tags/foo+bar/2000', :action => 'index', :tags => 'foo+bar', :year => '2000'
47
+ r.it_maps :get, '/tags/foo+bar/2000/1', :action => 'index', :tags => 'foo+bar', :year => '2000', :month => '1'
48
+
49
+ unless path_suffix =~ /pages/
50
+ r.it_maps :get, '/2000/1/1/an-article', :action => 'show', :year => '2000', :month => '1', :day => '1',
51
+ :permalink => 'an-article'
52
+
53
+ # article feeds
54
+ r.it_maps :get, '.atom', :action => 'index', :format => 'atom'
55
+ r.it_maps :get, '/categories/foo.atom', :action => 'index', :category_id => 'foo', :format => 'atom'
56
+ r.it_maps :get, '/tags/foo+bar.atom', :action => 'index', :tags => 'foo+bar', :format => 'atom'
57
+
58
+ # comment feeds
59
+ r.it_maps :get, '/2000/1/1/an-article.atom', :action => 'comments', :year => '2000', :month => '1', :day => '1',
60
+ :permalink => 'an-article', :format => 'atom'
61
+ end
62
+ end
63
+ end
64
+ end
65
+
66
+ # these do not work with a root section path because there's a reguar Comments resource
67
+ with_options :action => 'comments', :format => 'atom', :section_id => Blog.first.id.to_s do |r|
68
+ r.it_maps :get, '/a-blog/comments.atom'
69
+ r.it_maps :get, '/de/a-blog/comments.atom', :locale => 'de'
70
+ end
71
+ end
72
+
73
+ describe "the url_helper blog_path" do
74
+ before do
75
+ other = @section.site.sections.create! :title => 'another section' # FIXME move to db/populate
76
+ other.move_to_left_of @section
77
+
78
+ url_rewriter = ActionController::UrlRewriter.new @request, :controller => 'blog', :section => @section.id
79
+ @controller.instance_variable_set :@url, url_rewriter
80
+ @controller.instance_variable_set :@site, @site
81
+
82
+ I18n.default_locale = :en
83
+ I18n.locale = :de
84
+ end
85
+
86
+ blog_path = lambda { blog_path(@section) }
87
+ archive_path = lambda { blog_path(@section, :year => '2008', :month => '1') }
88
+ tag_path = lambda { blog_tag_path(@section, 'foo+bar') }
89
+ category_path = lambda { blog_category_path(@section, @category) }
90
+
91
+ paged_blog_path = lambda { blog_path(@section, :page => 2) }
92
+ paged_archive_path = lambda { blog_path(@section, :year => '2008', :month => '1', :page => 2) }
93
+ paged_tag_path = lambda { blog_tag_path(@section, 'foo+bar', :page => 2) }
94
+ paged_category_path = lambda { blog_category_path(@section, @category, :page => 2) }
95
+
96
+ blog_feed_path = lambda { blog_feed_path(@section.id, :format => :rss) }
97
+ tag_feed_path = lambda { tag_feed_path(@section, 'foo+bar', :rss) }
98
+ category_feed_path = lambda { category_feed_path(@section, @category, :rss) }
99
+
100
+ article_path = lambda { blog_article_path(@section, @article.full_permalink) }
101
+ comments_feed_path = lambda { blog_comments_path(@section, :format => :rss) }
102
+ article_comments_feed_path = lambda { blog_article_comments_path(@section, @article.full_permalink.merge(:format => :rss)) }
103
+
104
+ it_rewrites blog_path, :to => '/', :with => [:is_default_locale, :is_root_section]
105
+ it_rewrites blog_path, :to => '/de', :with => [:is_root_section]
106
+ it_rewrites blog_path, :to => '/a-blog', :with => [:is_default_locale]
107
+ it_rewrites blog_path, :to => '/de/a-blog'
108
+
109
+ it_rewrites archive_path, :to => '/2008/1', :with => [:is_default_locale, :is_root_section]
110
+ it_rewrites archive_path, :to => '/de/2008/1', :with => [:is_root_section]
111
+ it_rewrites archive_path, :to => '/a-blog/2008/1', :with => [:is_default_locale]
112
+ it_rewrites archive_path, :to => '/de/a-blog/2008/1'
113
+
114
+ it_rewrites tag_path, :to => '/tags/foo+bar', :with => [:is_default_locale, :is_root_section]
115
+ it_rewrites tag_path, :to => '/de/tags/foo+bar', :with => [:is_root_section]
116
+ it_rewrites tag_path, :to => '/a-blog/tags/foo+bar', :with => [:is_default_locale]
117
+ it_rewrites tag_path, :to => '/de/a-blog/tags/foo+bar'
118
+
119
+ it_rewrites category_path, :to => '/categories/a-category', :with => [:is_default_locale, :is_root_section]
120
+ it_rewrites category_path, :to => '/de/categories/a-category', :with => [:is_root_section]
121
+ it_rewrites category_path, :to => '/a-blog/categories/a-category', :with => [:is_default_locale]
122
+ it_rewrites category_path, :to => '/de/a-blog/categories/a-category'
123
+
124
+ it_rewrites paged_blog_path, :to => '/de/a-blog/pages/2'
125
+ it_rewrites paged_archive_path, :to => '/de/a-blog/2008/1/pages/2'
126
+ it_rewrites paged_tag_path, :to => '/de/a-blog/tags/foo+bar/pages/2'
127
+ it_rewrites paged_category_path, :to => '/de/a-blog/categories/a-category/pages/2'
128
+
129
+ it_rewrites blog_feed_path, :to => '/a-blog.rss', :with => [:is_default_locale, :is_root_section]
130
+ it_rewrites blog_feed_path, :to => '/de/a-blog.rss', :with => [:is_root_section]
131
+ it_rewrites blog_feed_path, :to => '/a-blog.rss', :with => [:is_default_locale]
132
+ it_rewrites blog_feed_path, :to => '/de/a-blog.rss'
133
+
134
+ it_rewrites tag_feed_path, :to => '/tags/foo+bar.rss', :with => [:is_default_locale, :is_root_section]
135
+ it_rewrites tag_feed_path, :to => '/de/tags/foo+bar.rss', :with => [:is_root_section]
136
+ it_rewrites tag_feed_path, :to => '/a-blog/tags/foo+bar.rss', :with => [:is_default_locale]
137
+ it_rewrites tag_feed_path, :to => '/de/a-blog/tags/foo+bar.rss'
138
+
139
+ it_rewrites category_feed_path, :to => '/categories/a-category.rss', :with => [:is_default_locale, :is_root_section]
140
+ it_rewrites category_feed_path, :to => '/de/categories/a-category.rss', :with => [:is_root_section]
141
+ it_rewrites category_feed_path, :to => '/a-blog/categories/a-category.rss', :with => [:is_default_locale]
142
+ it_rewrites category_feed_path, :to => '/de/a-blog/categories/a-category.rss'
143
+
144
+ it_rewrites article_path, :to => '/2008/1/1/a-blog-article', :with => [:is_default_locale, :is_root_section]
145
+ it_rewrites article_path, :to => '/de/2008/1/1/a-blog-article', :with => [:is_root_section]
146
+ it_rewrites article_path, :to => '/a-blog/2008/1/1/a-blog-article', :with => [:is_default_locale]
147
+ it_rewrites article_path, :to => '/de/a-blog/2008/1/1/a-blog-article'
148
+
149
+ it_rewrites comments_feed_path, :to => '/comments.rss', :with => [:is_default_locale, :is_root_section]
150
+ it_rewrites comments_feed_path, :to => '/de/comments.rss', :with => [:is_root_section]
151
+ it_rewrites comments_feed_path, :to => '/a-blog/comments.rss', :with => [:is_default_locale]
152
+ it_rewrites comments_feed_path, :to => '/de/a-blog/comments.rss'
153
+
154
+ it_rewrites article_comments_feed_path, :to => '/2008/1/1/a-blog-article.rss', :with => [:is_default_locale, :is_root_section]
155
+ it_rewrites article_comments_feed_path, :to => '/de/2008/1/1/a-blog-article.rss', :with => [:is_root_section]
156
+ it_rewrites article_comments_feed_path, :to => '/a-blog/2008/1/1/a-blog-article.rss', :with => [:is_default_locale]
157
+ it_rewrites article_comments_feed_path, :to => '/de/a-blog/2008/1/1/a-blog-article.rss'
158
+ end
159
+ end
@@ -0,0 +1,54 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../test_helper' )
2
+
3
+ module IntegrationTests
4
+ class AdminBlogArticleTest < ActionController::IntegrationTest
5
+ def setup
6
+ super
7
+ @section = Blog.first
8
+ @site = @section.site
9
+ use_site! @site
10
+ stub(Time).now.returns Time.utc(2008, 1, 1)
11
+ end
12
+
13
+ test "Admin creates an article, previews, edits and deletes it" do
14
+ login_as_admin
15
+ visit_admin_articles_index_page
16
+ create_a_new_article
17
+ revise_the_article
18
+ preview_article
19
+ delete_article
20
+ end
21
+
22
+ def visit_admin_articles_index_page
23
+ visit "/admin/sites/#{@site.id}/sections/#{@section.id}/articles"
24
+ end
25
+
26
+ def create_a_new_article
27
+ click_link "New"
28
+ fill_in 'article[title]', :with => 'the article title'
29
+ fill_in 'article[body]', :with => 'the article body'
30
+ click_button 'Save'
31
+ request.url.should =~ %r(/admin/sites/\d+/sections/\d+/articles/\d+/edit)
32
+ end
33
+
34
+ def revise_the_article
35
+ fill_in 'article[title]', :with => 'the revised article title'
36
+ fill_in 'article[body]', :with => 'the revised article body'
37
+ click_button 'Save'
38
+ request.url.should =~ %r(/admin/sites/\d+/sections/\d+/articles/\d+/edit)
39
+ @back_url = request.url
40
+ end
41
+
42
+ def preview_article
43
+ click_link 'Show'
44
+ request.url.should == controller.show_url(Article.find_by_permalink('the-article-title'))
45
+ end
46
+
47
+ def delete_article
48
+ visit @back_url
49
+ click_link 'Delete'
50
+ request.url.should =~ %r(/admin/sites/\d+/sections/\d+/articles)
51
+ response.body.should_not =~ %r(the revised article title)
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,68 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../test_helper' )
2
+
3
+ if Rails.plugin?(:adva_post_ping)
4
+ module IntegrationTests
5
+ class AdminBlogPingTest < ActionController::IntegrationTest
6
+ def setup
7
+ super
8
+ @section = Blog.first
9
+ @site = @section.site
10
+ use_site! @site
11
+ stub(Time).now.returns Time.utc(2008, 1, 2)
12
+
13
+ Article.old_add_observer(@observer = ArticlePingObserver.instance)
14
+
15
+ @ping_service = { :url => "http://rpc.pingomatic.com/", :type => :xmlrpc }
16
+ ArticlePingObserver::SERVICES.replace [@ping_service]
17
+ end
18
+
19
+ def teardown
20
+ super
21
+ Article.delete_observer(@observer)
22
+ end
23
+
24
+ test "The system pings FOO when a blog article is published" do
25
+ login_as_admin
26
+
27
+ visit "/admin/sites/#{@site.id}/sections/#{@section.id}/articles"
28
+ click_link "New"
29
+
30
+ expect_no_pings do
31
+ create_a_new_article
32
+ end
33
+
34
+ expect_ping_to(@ping_service) do
35
+ publish_article
36
+ end
37
+ end
38
+
39
+ def create_a_new_article
40
+ fill_in 'article[title]', :with => 'the article title'
41
+ fill_in 'article[body]', :with => 'the article body'
42
+ click_button 'Save'
43
+ request.url.should =~ %r(/admin/sites/\d+/sections/\d+/articles/\d+/edit)
44
+ end
45
+
46
+ def publish_article
47
+ uncheck 'article[draft]'
48
+ select_date "2008-1-1", :from => 'Publish on this date'
49
+ click_button 'Save'
50
+ request.url.should =~ %r(/admin/sites/\d+/sections/\d+/articles/\d+/edit)
51
+ end
52
+
53
+ def expect_no_pings
54
+ RR.dont_allow(ArticlePingObserver.instance).ping_service(anything, anything)
55
+ yield
56
+ RR.verify
57
+ RR.reset
58
+ end
59
+
60
+ def expect_ping_to(service)
61
+ RR.mock(ArticlePingObserver.instance).ping_service(service, anything)
62
+ yield
63
+ RR.verify
64
+ RR.reset
65
+ end
66
+ end
67
+ end
68
+ end