Skip to content

Commit 298b452

Browse files
committed
Refactor Feedback validations
This moves most of the implementation up to the Feedback base class, ensures that checks on allowed feedback only happen if article is set, and ensures that at most one error message is set on article.
1 parent e37596d commit 298b452

File tree

5 files changed

+136
-79
lines changed

5 files changed

+136
-79
lines changed

app/models/comment.rb

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,18 +41,15 @@ def send_notifications
4141
private
4242

4343
def article_allows_feedback?
44-
return true if article.allow_comments?
45-
46-
errors.add(:article, "Article is not open to comments")
47-
false
44+
article.allow_comments?
4845
end
4946

5047
def blog_allows_feedback?
5148
true
5249
end
5350

54-
def check_article_closed_for_feedback
55-
errors.add(:article, "Comment are closed") if article.comments_closed?
51+
def article_closed_for_feedback?
52+
article.comments_closed?
5653
end
5754

5855
def originator

app/models/feedback.rb

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,7 @@ class Feedback < ApplicationRecord
1111
include PublifyGuid
1212
include ContentBase
1313

14-
validate :article_allows_this_feedback, on: :create
15-
validate :feedback_not_closed, on: :create
14+
validate :feedback_allowed, on: :create
1615
validates :article, presence: true
1716

1817
before_save :correct_url, :classify_content
@@ -99,8 +98,20 @@ def correct_url
9998
self.url = "http://#{url}" unless %r{^https?://}.match?(url)
10099
end
101100

102-
def article_allows_this_feedback
103-
article && blog_allows_feedback? && article_allows_feedback?
101+
def feedback_allowed
102+
return unless article
103+
104+
unless blog_allows_feedback?
105+
errors.add(:base, "#{plural_model_name} are disabled")
106+
return
107+
end
108+
109+
unless article_allows_feedback?
110+
errors.add(:article, "Article is not open for #{plural_model_name.downcase}")
111+
return
112+
end
113+
114+
errors.add(:article, "#{plural_model_name} are closed") if article_closed_for_feedback?
104115
end
105116

106117
def akismet_options
@@ -200,10 +211,6 @@ def report_as_ham
200211
end
201212
end
202213

203-
def feedback_not_closed
204-
check_article_closed_for_feedback
205-
end
206-
207214
def send_notifications
208215
nil
209216
end
@@ -242,4 +249,8 @@ def akismet_client
242249
def blog_id
243250
article.blog_id if article.present?
244251
end
252+
253+
def plural_model_name
254+
self.class.model_name.human.pluralize
255+
end
245256
end

app/models/trackback.rb

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -14,24 +14,6 @@ def process_trackback
1414
end
1515
end
1616

17-
def article_allows_feedback?
18-
return true if article.allow_pings?
19-
20-
errors.add(:article, "Article is not pingable")
21-
false
22-
end
23-
24-
def blog_allows_feedback?
25-
return true unless blog.global_pings_disable
26-
27-
errors.add(:base, "Pings are disabled")
28-
false
29-
end
30-
31-
def check_article_closed_for_feedback
32-
errors.add(:article, "Pings are closed") if article.pings_closed?
33-
end
34-
3517
def originator
3618
blog_name
3719
end
@@ -47,4 +29,18 @@ def body=(newval)
4729
def feed_title
4830
"Trackback from #{blog_name}: #{title} on #{article.title}"
4931
end
32+
33+
private
34+
35+
def article_allows_feedback?
36+
article.allow_pings?
37+
end
38+
39+
def blog_allows_feedback?
40+
!blog.global_pings_disable
41+
end
42+
43+
def article_closed_for_feedback?
44+
article.pings_closed?
45+
end
5046
end

spec/models/comment_spec.rb

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,29 @@
88

99
let(:published_article) { build_stubbed(:article, published_at: 1.hour.ago, blog: blog) }
1010

11-
def valid_comment(options = {})
12-
Comment.new({ author: "Bob", article: published_article, body: "nice post",
13-
ip: "1.2.3.4" }.merge(options))
11+
describe "validations" do
12+
let(:comment) { described_class.new }
13+
14+
it "allows an article with open comment window" do
15+
article = Article.new(blog: blog, allow_comments: true, state: "published",
16+
published_at: 1.day.ago)
17+
18+
expect(comment).to allow_value(article).for(:article)
19+
end
20+
21+
it "requires article comment window to be open" do
22+
article = Article.new(blog: blog, allow_comments: true)
23+
24+
expect(comment).not_to allow_value(article).for(:article).
25+
with_message("Comments are closed")
26+
end
27+
28+
it "requires article to be open to comments" do
29+
article = Article.new(blog: blog, allow_comments: false)
30+
31+
expect(comment).not_to allow_value(article).for(:article).
32+
with_message("Article is not open for comments")
33+
end
1434
end
1535

1636
describe "#permalink_url" do
@@ -88,6 +108,11 @@ def valid_comment(options = {})
88108
end
89109

90110
describe "#classify_content" do
111+
def valid_comment(options = {})
112+
Comment.new({ author: "Bob", article: published_article, body: "nice post",
113+
ip: "1.2.3.4" }.merge(options))
114+
end
115+
91116
it "rejects spam rbl" do
92117
comment = valid_comment(
93118
author: "Spammer",

spec/models/trackback_spec.rb

Lines changed: 72 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -4,57 +4,85 @@
44
require "publify_core/testing_support/dns_mock"
55

66
describe Trackback, type: :model do
7-
let(:article) { create(:article) }
7+
describe "validations" do
8+
let(:blog) { build_stubbed :blog }
9+
let(:trackback) { described_class.new }
810

9-
before do
10-
@blog = create(:blog)
11-
@blog.sp_global = true
12-
@blog.default_moderate_comments = false
13-
@blog.save!
14-
end
11+
it "allows an article with open trackback window" do
12+
article = Article.new(blog: blog, allow_pings: true, state: "published",
13+
published_at: 1.day.ago)
1514

16-
it "Incomplete trackbacks should not be accepted" do
17-
tb = described_class.new(blog_name: "Blog name",
18-
title: "Title",
19-
excerpt: "Excerpt",
20-
article_id: create(:article).id)
21-
expect(tb).not_to be_valid
22-
expect(tb.errors["url"]).to be_any
23-
end
15+
expect(trackback).to allow_value(article).for(:article)
16+
end
2417

25-
it "A valid trackback should be accepted" do
26-
tb = described_class.new(blog_name: "Blog name",
27-
title: "Title",
28-
url: "http://foo.com",
29-
excerpt: "Excerpt",
30-
article_id: create(:article).id)
31-
expect(tb).to be_valid
32-
tb.save
33-
expect(tb.guid.size).to be > 15
34-
expect(tb).not_to be_spam
35-
end
18+
it "requires article trackback window to be open" do
19+
article = Article.new(blog: blog, allow_pings: true)
3620

37-
it "Trackbacks with a spammy link in the excerpt should be rejected" do
38-
tb = article.trackbacks.
39-
build(ham_params.merge(excerpt: '<a href="http://chinaaircatering.com">spam</a>'))
40-
tb.classify_content
41-
expect(tb).to be_spammy
42-
end
21+
expect(trackback).not_to allow_value(article).for(:article).
22+
with_message("Trackbacks are closed")
23+
end
4324

44-
it "Trackbacks with a spammy source url should be rejected" do
45-
tb = article.trackbacks.build(ham_params.merge(url: "http://www.chinaircatering.com"))
46-
tb.classify_content
47-
expect(tb).to be_spammy
48-
end
25+
it "requires article to be open to trackback" do
26+
article = Article.new(blog: blog, allow_pings: false)
4927

50-
it "Trackbacks from a spammy ip address should be rejected" do
51-
tb = article.trackbacks.build(ham_params.merge(ip: "212.42.230.207"))
52-
tb.classify_content
53-
expect(tb).to be_spammy
28+
expect(trackback).not_to allow_value(article).for(:article).
29+
with_message("Article is not open for trackbacks")
30+
end
5431
end
5532

56-
def ham_params
57-
{ blog_name: "Blog", title: "trackback", excerpt: "bland",
58-
url: "http://notaspammer.com", ip: "212.42.230.206" }
33+
describe "spam detection" do
34+
let(:article) { create(:article) }
35+
36+
before do
37+
@blog = create(:blog)
38+
@blog.sp_global = true
39+
@blog.default_moderate_comments = false
40+
@blog.save!
41+
end
42+
43+
it "Incomplete trackbacks should not be accepted" do
44+
tb = described_class.new(blog_name: "Blog name",
45+
title: "Title",
46+
excerpt: "Excerpt",
47+
article_id: create(:article).id)
48+
expect(tb).not_to be_valid
49+
expect(tb.errors["url"]).to be_any
50+
end
51+
52+
it "A valid trackback should be accepted" do
53+
tb = described_class.new(blog_name: "Blog name",
54+
title: "Title",
55+
url: "http://foo.com",
56+
excerpt: "Excerpt",
57+
article_id: create(:article).id)
58+
expect(tb).to be_valid
59+
tb.save
60+
expect(tb.guid.size).to be > 15
61+
expect(tb).not_to be_spam
62+
end
63+
64+
it "Trackbacks with a spammy link in the excerpt should be rejected" do
65+
tb = article.trackbacks.
66+
build(ham_params.merge(excerpt: '<a href="http://chinaaircatering.com">spam</a>'))
67+
tb.classify_content
68+
expect(tb).to be_spammy
69+
end
70+
71+
it "Trackbacks with a spammy source url should be rejected" do
72+
tb = article.trackbacks.build(ham_params.merge(url: "http://www.chinaircatering.com"))
73+
tb.classify_content
74+
expect(tb).to be_spammy
75+
end
76+
77+
it "Trackbacks from a spammy ip address should be rejected" do
78+
tb = article.trackbacks.build(ham_params.merge(ip: "212.42.230.207"))
79+
tb.classify_content
80+
expect(tb).to be_spammy
81+
end
82+
83+
def ham_params
84+
{ blog_name: "Blog", title: "trackback", excerpt: "bland",
85+
url: "http://notaspammer.com", ip: "212.42.230.206" }
86+
end
5987
end
6088
end

0 commit comments

Comments
 (0)