Commit 44627b4a898e59f5a5082404e65bc09a19b65a88
1 parent
688b3512
Exists in
master
and in
29 other branches
use anti_spam plugin in suggest_articles
ActionItem2691
Showing
26 changed files
with
544 additions
and
58 deletions
Show diff stats
app/controllers/my_profile/cms_controller.rb
... | ... | @@ -267,7 +267,10 @@ class CmsController < MyProfileController |
267 | 267 | @back_to = params[:back_to] || request.referer || url_for(profile.public_profile_url) |
268 | 268 | @task = SuggestArticle.new(params[:task]) |
269 | 269 | if request.post? |
270 | - @task.target = profile | |
270 | + @task.target = profile | |
271 | + @task.ip_address = request.remote_ip | |
272 | + @task.user_agent = request.user_agent | |
273 | + @task.referrer = request.referrer | |
271 | 274 | if verify_recaptcha(:model => @task, :message => _('Please type the words correctly')) && @task.save |
272 | 275 | session[:notice] = _('Thanks for your suggestion. The community administrators were notified.') |
273 | 276 | redirect_to @back_to | ... | ... |
app/controllers/my_profile/profile_editor_controller.rb
... | ... | @@ -4,7 +4,7 @@ class ProfileEditorController < MyProfileController |
4 | 4 | protect 'destroy_profile', :profile, :only => [:destroy_profile] |
5 | 5 | |
6 | 6 | def index |
7 | - @pending_tasks = Task.to(profile).pending.select{|i| user.has_permission?(i.permission, profile)} | |
7 | + @pending_tasks = Task.to(profile).pending.without_spam.select{|i| user.has_permission?(i.permission, profile)} | |
8 | 8 | end |
9 | 9 | |
10 | 10 | helper :profile | ... | ... |
app/controllers/my_profile/spam_controller.rb
... | ... | @@ -14,9 +14,15 @@ class SpamController < MyProfileController |
14 | 14 | if params[:remove_comment] |
15 | 15 | profile.comments_received.find(params[:remove_comment]).destroy |
16 | 16 | end |
17 | + if params[:remove_task] | |
18 | + Task.to(profile).find_by_id(params[:remove_task]).destroy | |
19 | + end | |
17 | 20 | if params[:mark_comment_as_ham] |
18 | 21 | profile.comments_received.find(params[:mark_comment_as_ham]).ham! |
19 | 22 | end |
23 | + if params[:mark_task_as_ham] && (t = Task.to(profile).find_by_id(params[:mark_task_as_ham])) | |
24 | + t.ham! | |
25 | + end | |
20 | 26 | if request.xhr? |
21 | 27 | json_response(true) |
22 | 28 | else |
... | ... | @@ -28,7 +34,8 @@ class SpamController < MyProfileController |
28 | 34 | return |
29 | 35 | end |
30 | 36 | |
31 | - @spam = profile.comments_received.spam.paginate({:page => params[:page]}) | |
37 | + @comment_spam = profile.comments_received.spam.paginate({:page => params[:comments_page]}) | |
38 | + @task_spam = Task.to(profile).spam.paginate({:page => params[:tasks_page]}) | |
32 | 39 | end |
33 | 40 | |
34 | 41 | protected | ... | ... |
app/controllers/my_profile/tasks_controller.rb
... | ... | @@ -4,12 +4,12 @@ class TasksController < MyProfileController |
4 | 4 | |
5 | 5 | def index |
6 | 6 | @filter = params[:filter_type].blank? ? nil : params[:filter_type] |
7 | - @tasks = Task.to(profile).pending.of(@filter).order_by('created_at', 'asc').paginate(:per_page => Task.per_page, :page => params[:page]) | |
7 | + @tasks = Task.to(profile).without_spam.pending.of(@filter).order_by('created_at', 'asc').paginate(:per_page => Task.per_page, :page => params[:page]) | |
8 | 8 | @failed = params ? params[:failed] : {} |
9 | 9 | end |
10 | 10 | |
11 | 11 | def processed |
12 | - @tasks = Task.to(profile).closed.sort_by(&:created_at) | |
12 | + @tasks = Task.to(profile).without_spam.closed.sort_by(&:created_at) | |
13 | 13 | end |
14 | 14 | |
15 | 15 | VALID_DECISIONS = [ 'finish', 'cancel', 'skip' ] |
... | ... | @@ -57,7 +57,7 @@ class TasksController < MyProfileController |
57 | 57 | end |
58 | 58 | |
59 | 59 | def list_requested |
60 | - @tasks = Task.find_all_by_requestor_id(profile.id) | |
60 | + @tasks = Task.without_spam.find_all_by_requestor_id(profile.id) | |
61 | 61 | end |
62 | 62 | |
63 | 63 | def ticket_details | ... | ... |
app/models/spammer_logger.rb
... | ... | @@ -6,6 +6,8 @@ class SpammerLogger < Logger |
6 | 6 | if object |
7 | 7 | if object.kind_of?(Comment) |
8 | 8 | @logger << "[#{Time.now.strftime('%F %T %z')}] Comment-id: #{object.id} IP: #{spammer_ip}\n" |
9 | + elsif object.kind_of?(SuggestArticle) | |
10 | + @logger << "[#{Time.now.strftime('%F %T %z')}] SuggestArticle-id: #{object.id} IP: #{spammer_ip}\n" | |
9 | 11 | end |
10 | 12 | else |
11 | 13 | @logger << "[#{Time.now.strftime('%F %T %z')}] IP: #{spammer_ip}\n" | ... | ... |
app/models/suggest_article.rb
... | ... | @@ -11,6 +11,21 @@ class SuggestArticle < Task |
11 | 11 | settings_items :source, :type => String |
12 | 12 | settings_items :source_name, :type => String |
13 | 13 | settings_items :highlighted, :type => :boolean, :default => false |
14 | + settings_items :ip_address, :type => String | |
15 | + settings_items :user_agent, :type => String | |
16 | + settings_items :referrer, :type => String | |
17 | + | |
18 | + after_create :schedule_spam_checking | |
19 | + | |
20 | + def schedule_spam_checking | |
21 | + self.delay.check_for_spam | |
22 | + end | |
23 | + | |
24 | + include Noosfero::Plugin::HotSpot | |
25 | + | |
26 | + def check_for_spam | |
27 | + plugins.dispatch(:check_suggest_article_for_spam, self) | |
28 | + end | |
14 | 29 | |
15 | 30 | def sender |
16 | 31 | "#{name} (#{email})" |
... | ... | @@ -61,4 +76,25 @@ class SuggestArticle < Task |
61 | 76 | _('You need to login on %{system} in order to approve or reject this article.') % { :system => target.environment.name } |
62 | 77 | end |
63 | 78 | |
79 | + def spam! | |
80 | + super | |
81 | + SpammerLogger.log(ip_address, self) | |
82 | + self.delay.marked_as_spam | |
83 | + self | |
84 | + end | |
85 | + | |
86 | + def ham! | |
87 | + super | |
88 | + self.delay.marked_as_ham | |
89 | + self | |
90 | + end | |
91 | + | |
92 | + def marked_as_spam | |
93 | + plugins.dispatch(:suggest_article_marked_as_spam, self) | |
94 | + end | |
95 | + | |
96 | + def marked_as_ham | |
97 | + plugins.dispatch(:suggest_article_marked_as_ham, self) | |
98 | + end | |
99 | + | |
64 | 100 | end | ... | ... |
app/models/task.rb
... | ... | @@ -235,6 +235,26 @@ class Task < ActiveRecord::Base |
235 | 235 | end |
236 | 236 | end |
237 | 237 | |
238 | + def spam? | |
239 | + !spam.nil? && spam | |
240 | + end | |
241 | + | |
242 | + def ham? | |
243 | + !spam.nil? && !spam | |
244 | + end | |
245 | + | |
246 | + def spam! | |
247 | + self.spam = true | |
248 | + self.save! | |
249 | + self | |
250 | + end | |
251 | + | |
252 | + def ham! | |
253 | + self.spam = false | |
254 | + self.save! | |
255 | + self | |
256 | + end | |
257 | + | |
238 | 258 | protected |
239 | 259 | |
240 | 260 | # This method must be overrided in subclasses, and its implementation must do |
... | ... | @@ -274,6 +294,9 @@ class Task < ActiveRecord::Base |
274 | 294 | named_scope :opened, :conditions => { :status => [Task::Status::ACTIVE, Task::Status::HIDDEN] } |
275 | 295 | named_scope :of, lambda { |type| conditions = type ? "type LIKE '#{type}'" : "1=1"; {:conditions => [conditions]} } |
276 | 296 | named_scope :order_by, lambda { |attribute, ord| {:order => "#{attribute} #{ord}"} } |
297 | + named_scope :without_spam, :conditions => ['spam IS NULL OR spam = ?', false] | |
298 | + named_scope :spam, :conditions => ['spam = ?', true] | |
299 | + | |
277 | 300 | |
278 | 301 | named_scope :to, lambda { |profile| |
279 | 302 | environment_condition = nil | ... | ... |
... | ... | @@ -0,0 +1,11 @@ |
1 | +<%# FIXME should not need to replicate the article structure like this to be able to use the same formatting as the comments listing %> | |
2 | +<div id='article'> | |
3 | + <div class="comments" id="comments_list"> | |
4 | + <ul class="article-comments-list"> | |
5 | + <%= render :partial => 'comment/comment', :collection => @comment_spam %> | |
6 | + </ul> | |
7 | + </div> | |
8 | +</div> | |
9 | + | |
10 | +<%= pagination_links @comment_spam, :param_name => :comments_page %> | |
11 | + | ... | ... |
... | ... | @@ -0,0 +1,21 @@ |
1 | +<% render :layout => 'task', :locals => { :task => task } do %> | |
2 | + <% content_for :extra_buttons do %> | |
3 | + <%= button_to_function('down', _('Show details'), "toggleDetails(this, '#{_('Hide details')}', '#{_('Show details')}')" ) %> | |
4 | + <% end %> | |
5 | + | |
6 | + <% content_for :extra_content do %> | |
7 | + <ul class="suggest-article-details" style="display: none"> | |
8 | + <li><strong><%=_('Sent by')%></strong>: <%=task.name%> </li> | |
9 | + <li><strong><%=_('Email')%></strong>: <%=task.email%> </li> | |
10 | + <li><strong><%=_('Source')%></strong>: <%=task.source_name%> </li> | |
11 | + <li><strong><%=_('Source URL')%></strong>: <%=task.source%> </li> | |
12 | + <li><strong><%=_('Folder')%></strong>: <%=(a = Article.find_by_id(task.article_parent_id))?a.name : '<em>' + s_('Folder|none') + '</em>'%> </li> | |
13 | + <li><strong><%=_('Lead')%></strong>: <%=task.article_abstract.blank? ? '<em>' + s_('Abstract|empty') + '</em>' : task.article_abstract%> </li> | |
14 | + <li><strong><%=_('Body')%></strong>: | |
15 | + <div class='suggest-article-body'> | |
16 | + <%= task.article_body %> | |
17 | + </div> | |
18 | + </li> | |
19 | + </ul> | |
20 | + <% end %> | |
21 | +<% end %> | ... | ... |
... | ... | @@ -0,0 +1,18 @@ |
1 | +<div class="task_box" id="task-<%= task.id %>"> | |
2 | + <%= render :partial => 'tasks/task_icon', :locals => {:task => task} %> | |
3 | + <%= render :partial => 'tasks/task_title', :locals => {:task => task} %> | |
4 | + <div class="task-information"> | |
5 | + <%= task_information(task) %> | |
6 | + </div> | |
7 | + | |
8 | + <%= yield %> <% # ??? %> | |
9 | + | |
10 | + <% button_bar do %> | |
11 | + <%= button_to_function('new', _('Mark as NOT SPAM'), 'removeTaskBox(this, %s, "%s", "")' % [url_for(:mark_task_as_ham => task.id).to_json, "task-#{task.id}"]) %> | |
12 | + <%= yield :extra_buttons %> | |
13 | + <%= button_to_function('delete', _('Remove'), 'removeTaskBox(this, %s, "%s", %s)' % [url_for(:profile => params[:profile], :remove_task => task.id).to_json, "task-#{task.id}", _('Are you sure you want to remove this article suggestion?').to_json]) %> | |
14 | + | |
15 | + <% end %> | |
16 | + | |
17 | + <%= yield :extra_content %> | |
18 | +</div> | ... | ... |
app/views/spam/index.rhtml
1 | +<%= stylesheet('tasks') %> | |
2 | + | |
1 | 3 | <h1><%= _('Manage SPAM') %></h1> |
2 | 4 | |
3 | 5 | <% button_bar do %> |
... | ... | @@ -5,16 +7,21 @@ |
5 | 7 | <% end %> |
6 | 8 | |
7 | 9 | <%# FIXME should not need to replicate the article structure like this to be able to use the same formatting as the comments listing %> |
8 | -<div id='article'> | |
9 | - <div class="comments" id="comments_list"> | |
10 | - <ul class="article-comments-list"> | |
11 | - <%= render :partial => 'comment/comment', :collection => @spam %> | |
12 | - </ul> | |
13 | - </div> | |
14 | -</div> | |
15 | 10 | |
16 | -<%= pagination_links @spam %> | |
11 | +<% if @task_spam.length > 0 %> | |
12 | + <% tabs = [] %> | |
13 | + <% tabs << {:title => _('Comment Spam'), :id => 'comment-spam', | |
14 | + :content => (render :partial => 'comment_spam')} %> | |
15 | + <% tabs << {:title => _('Task Spam'), :id => 'task-spam', | |
16 | + :content => (render :partial => 'task_spam') } %> | |
17 | + <%= render_tabs(tabs) %> | |
18 | +<% else %> | |
19 | + <%= render :partial => 'comment_spam' %> | |
20 | +<% end %> | |
21 | + | |
17 | 22 | |
18 | 23 | <% button_bar do %> |
19 | 24 | <%= button :back, _('Back to control panel'), :controller => :profile_editor %> |
20 | 25 | <% end %> |
26 | + | |
27 | +<%= javascript_include_tag 'spam' %> | ... | ... |
app/views/tasks/_task.rhtml
1 | 1 | <div class="task_box" id="task-<%= task.id %>"> |
2 | 2 | |
3 | - <div class="task_icon"> | |
4 | - <% | |
5 | - icon_info = task.icon | |
6 | - if icon_info[:type] == :profile_image | |
7 | - icon = profile_image(icon_info[:profile], :minor) | |
8 | - elsif icon_info[:type] == :defined_image | |
9 | - icon = "<img src='#{icon_info[:src]}' alt='#{icon_info[:name]}' />" | |
10 | - end | |
11 | - %> | |
12 | - <%= | |
13 | - if icon_info[:url] | |
14 | - link_to(icon, icon_info[:url]) | |
15 | - else | |
16 | - icon | |
17 | - end | |
18 | - %> | |
19 | - | |
20 | - </div> | |
3 | + <%= render :partial => 'task_icon', :locals => {:task => task} %> | |
21 | 4 | |
22 | 5 | <div class="task_decisions"> |
23 | 6 | <%= |
... | ... | @@ -39,9 +22,7 @@ |
39 | 22 | %> |
40 | 23 | </div><!-- class="task_decisions" --> |
41 | 24 | |
42 | - <strong class="task_title"> | |
43 | - <%= task.title %> | |
44 | - </strong> | |
25 | + <%= render :partial => 'task_title', :locals => {:task => task} %> | |
45 | 26 | |
46 | 27 | <div class="task_information"> |
47 | 28 | <%= task_information(task) %> | ... | ... |
... | ... | @@ -0,0 +1,16 @@ |
1 | +<% | |
2 | + icon_info = task.icon | |
3 | + if icon_info[:type] == :profile_image | |
4 | + icon = profile_image(icon_info[:profile], :minor) | |
5 | + elsif icon_info[:type] == :defined_image | |
6 | + icon = "<img src='#{icon_info[:src]}' alt='#{icon_info[:name]}' />" | |
7 | + end | |
8 | + | |
9 | + if icon_info[:url] | |
10 | + icon = link_to(icon, icon_info[:url]) | |
11 | + end | |
12 | +%> | |
13 | + | |
14 | +<div class="task_icon"> | |
15 | + <%= icon %> | |
16 | +</div> | ... | ... |
... | ... | @@ -0,0 +1,13 @@ |
1 | +class AddSpamToTask < ActiveRecord::Migration | |
2 | + def self.up | |
3 | + change_table :tasks do |t| | |
4 | + t.boolean :spam, :default => false | |
5 | + end | |
6 | + Task.update_all ["spam = ?", false] | |
7 | + add_index :tasks, [:spam] | |
8 | + end | |
9 | + | |
10 | + def self.down | |
11 | + remove_column :tasks, :spam | |
12 | + end | |
13 | +end | ... | ... |
db/schema.rb
... | ... | @@ -9,7 +9,7 @@ |
9 | 9 | # |
10 | 10 | # It's strongly recommended to check this file into your version control system. |
11 | 11 | |
12 | -ActiveRecord::Schema.define(:version => 20130711213046) do | |
12 | +ActiveRecord::Schema.define(:version => 20131011164400) do | |
13 | 13 | |
14 | 14 | create_table "abuse_reports", :force => true do |t| |
15 | 15 | t.integer "reporter_id" |
... | ... | @@ -233,6 +233,50 @@ ActiveRecord::Schema.define(:version => 20130711213046) do |
233 | 233 | t.datetime "updated_at" |
234 | 234 | end |
235 | 235 | |
236 | + create_table "custom_forms_plugin_answers", :force => true do |t| | |
237 | + t.text "value" | |
238 | + t.integer "field_id" | |
239 | + t.integer "submission_id" | |
240 | + end | |
241 | + | |
242 | + create_table "custom_forms_plugin_fields", :force => true do |t| | |
243 | + t.string "name" | |
244 | + t.string "slug" | |
245 | + t.string "type" | |
246 | + t.string "default_value" | |
247 | + t.string "choices" | |
248 | + t.float "minimum" | |
249 | + t.float "maximum" | |
250 | + t.integer "form_id" | |
251 | + t.boolean "mandatory", :default => false | |
252 | + t.boolean "multiple" | |
253 | + t.boolean "list" | |
254 | + t.integer "position", :default => 0 | |
255 | + end | |
256 | + | |
257 | + create_table "custom_forms_plugin_forms", :force => true do |t| | |
258 | + t.string "name" | |
259 | + t.string "slug" | |
260 | + t.text "description" | |
261 | + t.integer "profile_id" | |
262 | + t.datetime "begining" | |
263 | + t.datetime "ending" | |
264 | + t.boolean "report_submissions", :default => false | |
265 | + t.boolean "on_membership", :default => false | |
266 | + t.string "access" | |
267 | + t.datetime "created_at" | |
268 | + t.datetime "updated_at" | |
269 | + end | |
270 | + | |
271 | + create_table "custom_forms_plugin_submissions", :force => true do |t| | |
272 | + t.string "author_name" | |
273 | + t.string "author_email" | |
274 | + t.integer "profile_id" | |
275 | + t.integer "form_id" | |
276 | + t.datetime "created_at" | |
277 | + t.datetime "updated_at" | |
278 | + end | |
279 | + | |
236 | 280 | create_table "delayed_jobs", :force => true do |t| |
237 | 281 | t.integer "priority", :default => 0 |
238 | 282 | t.integer "attempts", :default => 0 |
... | ... | @@ -547,8 +591,11 @@ ActiveRecord::Schema.define(:version => 20130711213046) do |
547 | 591 | t.datetime "created_at" |
548 | 592 | t.string "target_type" |
549 | 593 | t.integer "image_id" |
594 | + t.boolean "spam", :default => false | |
550 | 595 | end |
551 | 596 | |
597 | + add_index "tasks", ["spam"], :name => "index_tasks_on_spam" | |
598 | + | |
552 | 599 | create_table "thumbnails", :force => true do |t| |
553 | 600 | t.integer "size" |
554 | 601 | t.string "content_type" | ... | ... |
plugins/anti_spam/lib/anti_spam_plugin.rb
... | ... | @@ -5,7 +5,7 @@ class AntiSpamPlugin < Noosfero::Plugin |
5 | 5 | end |
6 | 6 | |
7 | 7 | def self.plugin_description |
8 | - _("Checks comments against a spam checking service compatible with the Akismet API") | |
8 | + _("Tests comments and suggested articles against a spam checking service compatible with the Akismet API") | |
9 | 9 | end |
10 | 10 | |
11 | 11 | def self.host_default_setting |
... | ... | @@ -13,30 +13,44 @@ class AntiSpamPlugin < Noosfero::Plugin |
13 | 13 | end |
14 | 14 | |
15 | 15 | def check_comment_for_spam(comment) |
16 | - if rakismet_call(comment, :spam?) | |
16 | + if rakismet_call AntiSpamPlugin::CommentWrapper.new(comment), comment.environment, :spam? | |
17 | 17 | comment.spam = true |
18 | 18 | comment.save! |
19 | 19 | end |
20 | 20 | end |
21 | 21 | |
22 | 22 | def comment_marked_as_spam(comment) |
23 | - rakismet_call(comment, :spam!) | |
23 | + rakismet_call AntiSpamPlugin::CommentWrapper.new(comment), comment.environment, :spam! | |
24 | 24 | end |
25 | 25 | |
26 | 26 | def comment_marked_as_ham(comment) |
27 | - rakismet_call(comment, :ham!) | |
27 | + rakismet_call AntiSpamPlugin::CommentWrapper.new(comment), comment.environment, :ham! | |
28 | + end | |
29 | + | |
30 | + def check_suggest_article_for_spam(suggest_article) | |
31 | + if rakismet_call AntiSpamPlugin::SuggestArticleWrapper.new(suggest_article), suggest_article.environment, :spam? | |
32 | + suggest_article.spam = true | |
33 | + suggest_article.save! | |
34 | + end | |
35 | + end | |
36 | + | |
37 | + def suggest_article_marked_as_spam(suggest_article) | |
38 | + rakismet_call AntiSpamPlugin::SuggestArticleWrapper.new(suggest_article), suggest_article.environment, :spam! | |
39 | + end | |
40 | + | |
41 | + def suggest_article_marked_as_ham(suggest_article) | |
42 | + rakismet_call AntiSpamPlugin::SuggestArticleWrapper.new(suggest_article), suggest_article.environment, :ham! | |
28 | 43 | end |
29 | 44 | |
30 | 45 | protected |
31 | 46 | |
32 | - def rakismet_call(comment, op) | |
33 | - settings = Noosfero::Plugin::Settings.new(comment.environment, self.class) | |
47 | + def rakismet_call(submission, environment, op) | |
48 | + settings = Noosfero::Plugin::Settings.new(environment, self.class) | |
34 | 49 | |
35 | 50 | Rakismet.host = settings.host |
36 | 51 | Rakismet.key = settings.api_key |
37 | - Rakismet.url = comment.environment.top_url | |
52 | + Rakismet.url = environment.top_url | |
38 | 53 | |
39 | - submission = AntiSpamPlugin::CommentWrapper.new(comment) | |
40 | 54 | submission.send(op) |
41 | 55 | end |
42 | 56 | ... | ... |
plugins/anti_spam/lib/anti_spam_plugin/suggest_article_wrapper.rb
0 → 100644
... | ... | @@ -0,0 +1,12 @@ |
1 | +class AntiSpamPlugin::SuggestArticleWrapper < Struct.new(:suggest_article) | |
2 | + | |
3 | + delegate :name, :email, :article_body, :ip_address, :user_agent, :referrer, :to => :suggest_article | |
4 | + | |
5 | + include Rakismet::Model | |
6 | + | |
7 | + alias :author :name | |
8 | + alias :author_email :email | |
9 | + alias :user_ip :ip_address | |
10 | + alias :content :article_body | |
11 | + | |
12 | +end | ... | ... |
plugins/anti_spam/test/unit/anti_spam_plugin/suggest_article_wrapper_test.rb
0 → 100644
... | ... | @@ -0,0 +1,45 @@ |
1 | +require 'test_helper' | |
2 | + | |
3 | +class AntiSpamPluginCommentWrapperTest < ActiveSupport::TestCase | |
4 | + | |
5 | + def setup | |
6 | + @suggest_article = SuggestArticle.new( | |
7 | + :article_body => 'comment body', | |
8 | + :name => 'author', | |
9 | + :email => 'foo@example.com', | |
10 | + :ip_address => '1.2.3.4', | |
11 | + :user_agent => 'Some Good Browser (I hope)', | |
12 | + :referrer => 'http://noosfero.org/' | |
13 | + ) | |
14 | + @wrapper = AntiSpamPlugin::SuggestArticleWrapper.new(@suggest_article) | |
15 | + end | |
16 | + | |
17 | + should 'use Rakismet::Model' do | |
18 | + assert_includes @wrapper.class.included_modules, Rakismet::Model | |
19 | + end | |
20 | + | |
21 | + should 'get contents' do | |
22 | + assert_equal @suggest_article.article_body, @wrapper.content | |
23 | + end | |
24 | + | |
25 | + should 'get author name' do | |
26 | + assert_equal @suggest_article.name, @wrapper.author | |
27 | + end | |
28 | + | |
29 | + should 'get author email' do | |
30 | + assert_equal @suggest_article.email, @wrapper.author_email | |
31 | + end | |
32 | + | |
33 | + should 'get IP address' do | |
34 | + assert_equal @suggest_article.ip_address, @wrapper.user_ip | |
35 | + end | |
36 | + | |
37 | + should 'get User-Agent' do | |
38 | + assert_equal @suggest_article.user_agent, @wrapper.user_agent | |
39 | + end | |
40 | + | |
41 | + should 'get get Referrer' do | |
42 | + assert_equal @suggest_article.referrer, @wrapper.referrer | |
43 | + end | |
44 | + | |
45 | +end | ... | ... |
plugins/anti_spam/test/unit/anti_spam_plugin_test.rb
... | ... | @@ -7,6 +7,11 @@ class AntiSpamPluginTest < ActiveSupport::TestCase |
7 | 7 | article = fast_create(TextileArticle, :profile_id => profile.id) |
8 | 8 | @comment = fast_create(Comment, :source_id => article.id, :source_type => 'Article') |
9 | 9 | |
10 | + | |
11 | + @suggest_article = SuggestArticle.new(:target_id => profile.id, :target_type => 'Profile', :article_name => 'article', :article_body => 'lorem ipsum', :email => 'invalid@example.com', :name => 'article') | |
12 | + | |
13 | + @suggest_article.save! | |
14 | + | |
10 | 15 | @settings = Noosfero::Plugin::Settings.new(@comment.environment, AntiSpamPlugin) |
11 | 16 | @settings.api_key = 'b8b80ddb8084062d0c9119c945ce3bc3' |
12 | 17 | @settings.save! |
... | ... | @@ -23,14 +28,32 @@ class AntiSpamPluginTest < ActiveSupport::TestCase |
23 | 28 | assert @comment.spam |
24 | 29 | end |
25 | 30 | |
26 | - should 'report spam' do | |
31 | + should 'report comment spam' do | |
27 | 32 | AntiSpamPlugin::CommentWrapper.any_instance.expects(:spam!) |
28 | 33 | @plugin.comment_marked_as_spam(@comment) |
29 | 34 | end |
30 | 35 | |
31 | - should 'report ham' do | |
36 | + should 'report comment ham' do | |
32 | 37 | AntiSpamPlugin::CommentWrapper.any_instance.expects(:ham!) |
33 | 38 | @plugin.comment_marked_as_ham(@comment) |
34 | 39 | end |
35 | 40 | |
41 | + should 'check for spam and mark suggest_article as spam if server says it is spam' do | |
42 | + AntiSpamPlugin::SuggestArticleWrapper.any_instance.expects(:spam?).returns(true) | |
43 | + @suggest_article.expects(:save!) | |
44 | + | |
45 | + @plugin.check_suggest_article_for_spam(@suggest_article) | |
46 | + assert @suggest_article.spam | |
47 | + end | |
48 | + | |
49 | + should 'report suggest_article spam' do | |
50 | + AntiSpamPlugin::SuggestArticleWrapper.any_instance.expects(:spam!) | |
51 | + @plugin.suggest_article_marked_as_spam(@suggest_article) | |
52 | + end | |
53 | + | |
54 | + should 'report suggest_article ham' do | |
55 | + AntiSpamPlugin::SuggestArticleWrapper.any_instance.expects(:ham!) | |
56 | + @plugin.suggest_article_marked_as_ham(@suggest_article) | |
57 | + end | |
58 | + | |
36 | 59 | end | ... | ... |
... | ... | @@ -0,0 +1,28 @@ |
1 | +function removeTaskBox(button, url, task_box_id, msg) { | |
2 | + var $ = jQuery; | |
3 | + if (msg && !confirm(msg)) { | |
4 | + return; | |
5 | + } | |
6 | + button = $(button); | |
7 | + button.addClass('task-button-loading'); | |
8 | + $.post(url, function (data) { | |
9 | + if (data.ok) { | |
10 | + $('#' + task_box_id).slideUp(); | |
11 | + } else { | |
12 | + button.removeClass('task-button-loading'); | |
13 | + button.addClass('task-button-failure'); | |
14 | + } | |
15 | + }); | |
16 | +} | |
17 | + | |
18 | +function toggleDetails(link, msg_hide, msg_show) { | |
19 | + var $ = jQuery; | |
20 | + $(link).toggleClass('icon-up icon-down'); | |
21 | + details = $(link).closest('.task_box').find('.suggest-article-details'); | |
22 | + if (details.css('display') == 'none') { | |
23 | + link.innerHTML = msg_hide; | |
24 | + } else { | |
25 | + link.innerHTML = msg_show; | |
26 | + } | |
27 | + details.slideToggle(); | |
28 | +} | ... | ... |
test/functional/spam_controller_test.rb
... | ... | @@ -4,37 +4,55 @@ class SpamControllerTest < ActionController::TestCase |
4 | 4 | |
5 | 5 | def setup |
6 | 6 | @profile = create_user.person |
7 | - @article = fast_create(TextileArticle, :profile_id => @profile.id) | |
8 | - @spam = fast_create(Comment, :source_id => @article.id, :spam => true, :name => 'foo', :email => 'foo@example.com') | |
9 | 7 | |
8 | + @community = fast_create(Community, :name => 'testcommunity') | |
9 | + @community.add_admin(@profile) | |
10 | + @article = fast_create(TextileArticle, :profile_id => @community.id) | |
11 | + @spam_comment = fast_create(Comment, :source_id => @article.id, :spam => true, :name => 'foo', :email => 'foo@example.com') | |
12 | + | |
13 | + @spam_suggest_article = SuggestArticle.create!(:name => 'spammer', :article_name => 'Spam article', :email => 'spammer@shady.place', :article_body => "Something you don't need", :target => @community, :spam => true) | |
10 | 14 | login_as @profile.identifier |
11 | 15 | end |
12 | 16 | |
13 | - test "should only list spammy comments" do | |
17 | + test "should only list spammy comments and spammy suggest articles" do | |
14 | 18 | ham = fast_create(Comment, :source_id => @article.id) |
15 | 19 | |
16 | - get :index, :profile => @profile.identifier | |
20 | + get :index, :profile => @community.identifier | |
17 | 21 | |
18 | - assert_equivalent [@spam], assigns(:spam) | |
22 | + assert_equivalent [@spam_comment], assigns(:comment_spam) | |
23 | + assert_equivalent [@spam_suggest_article], assigns(:task_spam) | |
19 | 24 | end |
20 | 25 | |
21 | 26 | test "should mark comments as ham" do |
22 | - post :index, :profile => @profile.identifier, :mark_comment_as_ham => @spam.id | |
27 | + post :index, :profile => @community.identifier, :mark_comment_as_ham => @spam_comment.id | |
28 | + | |
29 | + @spam_comment.reload | |
30 | + assert @spam_comment.ham? | |
31 | + end | |
32 | + | |
33 | + test "should mark suggest article as ham" do | |
34 | + post :index, :profile => @community.identifier, :mark_task_as_ham => @spam_suggest_article.id | |
23 | 35 | |
24 | - @spam.reload | |
25 | - assert @spam.ham? | |
36 | + @spam_suggest_article.reload | |
37 | + assert @spam_suggest_article.ham? | |
26 | 38 | end |
27 | 39 | |
28 | 40 | test "should remove comments" do |
29 | - post :index, :profile => @profile.identifier, :remove_comment => @spam.id | |
41 | + post :index, :profile => @community.identifier, :remove_comment => @spam_comment.id | |
42 | + | |
43 | + assert !Comment.exists?(@spam_comment.id) | |
44 | + end | |
45 | + | |
46 | + test "should remove suggest articles" do | |
47 | + post :index, :profile => @community.identifier, :remove_task => @spam_suggest_article.id | |
30 | 48 | |
31 | - assert !Comment.exists?(@spam.id) | |
49 | + assert !SuggestArticle.exists?(@spam_suggest_article.id) | |
32 | 50 | end |
33 | 51 | |
34 | 52 | should 'properly render spam that have replies' do |
35 | - reply_spam = fast_create(Comment, :source_id => @article_id, :reply_of_id => @spam.id) | |
53 | + reply_spam = fast_create(Comment, :source_id => @article_id, :reply_of_id => @spam_comment.id) | |
36 | 54 | |
37 | - get :index, :profile => @profile.identifier | |
55 | + get :index, :profile => @community.identifier | |
38 | 56 | assert_response :success |
39 | 57 | end |
40 | 58 | ... | ... |
test/functional/tasks_controller_test.rb
... | ... | @@ -38,6 +38,17 @@ class TasksControllerTest < ActionController::TestCase |
38 | 38 | assert_kind_of Array, assigns(:tasks) |
39 | 39 | end |
40 | 40 | |
41 | + should 'list pending tasks without spam' do | |
42 | + requestor = fast_create(Person) | |
43 | + task_spam = Task.create!(:requestor => requestor, :target => profile, :spam => true) | |
44 | + task_ham = Task.create!(:requestor => requestor, :target => profile, :spam => false) | |
45 | + | |
46 | + get :index | |
47 | + assert_response :success | |
48 | + assert_includes assigns(:tasks), task_ham | |
49 | + assert_not_includes assigns(:tasks), task_spam | |
50 | + end | |
51 | + | |
41 | 52 | should 'list processed tasks' do |
42 | 53 | get :processed |
43 | 54 | |
... | ... | @@ -46,6 +57,17 @@ class TasksControllerTest < ActionController::TestCase |
46 | 57 | assert_kind_of Array, assigns(:tasks) |
47 | 58 | end |
48 | 59 | |
60 | + should 'list processed tasks without spam' do | |
61 | + requestor = fast_create(Person) | |
62 | + task_spam = Task.create!(:status => Task::Status::FINISHED, :requestor => requestor, :target => profile, :spam => true) | |
63 | + task_ham = Task.create!(:status => Task::Status::FINISHED, :requestor => requestor, :target => profile, :spam => false) | |
64 | + | |
65 | + get :processed | |
66 | + assert_response :success | |
67 | + assert_includes assigns(:tasks), task_ham | |
68 | + assert_not_includes assigns(:tasks), task_spam | |
69 | + end | |
70 | + | |
49 | 71 | should 'be able to finish a task' do |
50 | 72 | t = profile.tasks.build; t.save! |
51 | 73 | |
... | ... | @@ -140,6 +162,15 @@ class TasksControllerTest < ActionController::TestCase |
140 | 162 | assert_includes assigns(:tasks), task |
141 | 163 | end |
142 | 164 | |
165 | + should 'list tasks that this profile created without spam' do | |
166 | + task_spam = Ticket.create!(:name => 'test', :requestor => profile, :spam => true) | |
167 | + task_ham = Ticket.create!(:name => 'test', :requestor => profile, :spam => false) | |
168 | + get :list_requested, :profile => profile.identifier | |
169 | + | |
170 | + assert_includes assigns(:tasks), task_ham | |
171 | + assert_not_includes assigns(:tasks), task_spam | |
172 | + end | |
173 | + | |
143 | 174 | should 'set target of ticket when creating it' do |
144 | 175 | f = create_user('friend').person |
145 | 176 | profile.add_friend f | ... | ... |
test/unit/suggest_article_test.rb
... | ... | @@ -150,5 +150,79 @@ class SuggestArticleTest < ActiveSupport::TestCase |
150 | 150 | assert_match(/#{task.name}.*suggested the publication of the article: #{task.subject}/, email.subject) |
151 | 151 | end |
152 | 152 | |
153 | + class EverythingIsSpam < Noosfero::Plugin | |
154 | + def check_suggest_article_for_spam(suggest_article) | |
155 | + suggest_article.spam! | |
156 | + end | |
157 | + end | |
158 | + | |
159 | + should 'delegate spam detection to plugins' do | |
160 | + Environment.default.enable_plugin(EverythingIsSpam) | |
161 | + | |
162 | + t1 = build(SuggestArticle, :target => @profile, :article_name => 'suggested article', :name => 'johndoe', :email => 'johndoe@example.com') | |
163 | + | |
164 | + EverythingIsSpam.any_instance.expects(:check_suggest_article_for_spam) | |
165 | + | |
166 | + t1.check_for_spam | |
167 | + end | |
168 | + | |
169 | + class SpamNotification < Noosfero::Plugin | |
170 | + class << self | |
171 | + attr_accessor :marked_as_spam | |
172 | + attr_accessor :marked_as_ham | |
173 | + end | |
174 | + | |
175 | + def check_suggest_article_for_spam(c) | |
176 | + # do nothing | |
177 | + end | |
178 | + | |
179 | + def suggest_article_marked_as_spam(c) | |
180 | + self.class.marked_as_spam = c | |
181 | + end | |
182 | + | |
183 | + def suggest_article_marked_as_ham(c) | |
184 | + self.class.marked_as_ham = c | |
185 | + end | |
186 | + end | |
187 | + | |
188 | + should 'notify plugins of suggest_articles being marked as spam' do | |
189 | + Environment.default.enable_plugin(SpamNotification) | |
190 | + | |
191 | + t = SuggestArticle.create!(:target => @profile, :article_name => 'suggested article', :name => 'johndoe', :article_body => 'wanna feel my body? my body baaaby', :email => 'johndoe@example.com') | |
192 | + | |
193 | + t.spam! | |
194 | + process_delayed_job_queue | |
195 | + | |
196 | + assert_equal t, SpamNotification.marked_as_spam | |
197 | + end | |
198 | + | |
199 | + should 'notify plugins of suggest_articles being marked as ham' do | |
200 | + Environment.default.enable_plugin(SpamNotification) | |
201 | + | |
202 | + t = SuggestArticle.create!(:target => @profile, :article_name => 'suggested article', :name => 'johndoe', :article_body => 'wanna feel my body? my body baaaby', :email => 'johndoe@example.com') | |
203 | + | |
204 | + t.ham! | |
205 | + process_delayed_job_queue | |
206 | + | |
207 | + assert_equal t, SpamNotification.marked_as_ham | |
208 | + end | |
209 | + | |
210 | + should 'store User-Agent' do | |
211 | + t = SuggestArticle.new(:user_agent => 'foo') | |
212 | + assert_equal 'foo', t.user_agent | |
213 | + end | |
214 | + | |
215 | + should 'store referrer' do | |
216 | + t = SuggestArticle.new(:referrer => 'bar') | |
217 | + assert_equal 'bar', t.referrer | |
218 | + end | |
219 | + | |
220 | + should 'log spammer ip after marking comment as spam' do | |
221 | + t = SuggestArticle.create!(:target => @profile, :article_name => 'suggested article', :name => 'johndoe', :article_body => 'wanna feel my body? my body baaaby', :email => 'johndoe@example.com', :ip_address => '192.168.0.1') | |
222 | + t.spam! | |
223 | + log = File.open('log/test_spammers.log') | |
224 | + assert_match "SuggestArticle-id: #{t.id} IP: 192.168.0.1", log.read | |
225 | + SpammerLogger.clean_log | |
226 | + end | |
153 | 227 | |
154 | 228 | end | ... | ... |
test/unit/task_test.rb
... | ... | @@ -372,6 +372,55 @@ class TaskTest < ActiveSupport::TestCase |
372 | 372 | assert_includes Task.closed, canceled |
373 | 373 | end |
374 | 374 | |
375 | + should 'be ham by default' do # ham means not spam | |
376 | + assert_equal false, Task.create.spam | |
377 | + end | |
378 | + | |
379 | + should 'be able to mark tasks as spam/ham/unknown' do | |
380 | + t = Task.new | |
381 | + t.spam = true | |
382 | + assert t.spam? | |
383 | + assert !t.ham? | |
384 | + | |
385 | + t.spam = false | |
386 | + assert t.ham? | |
387 | + assert !t.spam? | |
388 | + | |
389 | + t.spam = nil | |
390 | + assert !t.spam? | |
391 | + assert !t.ham? | |
392 | + end | |
393 | + | |
394 | + should 'be able to select non-spam tasks' do | |
395 | + t1 = fast_create(Task) | |
396 | + t2 = fast_create(Task, :spam => false) | |
397 | + t3 = fast_create(Task, :spam => true) | |
398 | + | |
399 | + assert_equivalent [t1,t2], Task.without_spam | |
400 | + end | |
401 | + | |
402 | + should 'be able to select spam tasks' do | |
403 | + t1 = fast_create(Task) | |
404 | + t2 = fast_create(Task, :spam => false) | |
405 | + t3 = fast_create(Task, :spam => true) | |
406 | + | |
407 | + assert_equivalent [t3], Task.spam | |
408 | + end | |
409 | + | |
410 | + should 'be able to mark as spam' do | |
411 | + t1 = fast_create(Task) | |
412 | + t1.spam! | |
413 | + t1.reload | |
414 | + assert t1.spam? | |
415 | + end | |
416 | + | |
417 | + should 'be able to mark as ham' do | |
418 | + t1 = fast_create(Task) | |
419 | + t1.ham! | |
420 | + t1.reload | |
421 | + assert t1.ham? | |
422 | + end | |
423 | + | |
375 | 424 | protected |
376 | 425 | |
377 | 426 | def sample_user | ... | ... |