rakismet 0.3.6 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +7 -0
- data/CHANGELOG +2 -0
- data/README.md +87 -79
- data/Rakefile +26 -0
- data/VERSION.yml +4 -0
- data/install.rb +7 -0
- data/lib/rakismet/{controller_extensions.rb → controller.rb} +3 -2
- data/lib/rakismet/{model_extensions.rb → model.rb} +3 -2
- data/lib/rakismet.rb +5 -7
- data/spec/controllers/rakismet_controller_spec.rb +54 -0
- data/spec/models/base_spec.rb +77 -0
- data/spec/models/rakismet_model_spec.rb +223 -0
- data/spec/spec.opts +6 -0
- data/spec/spec_helper.rb +28 -0
- data/uninstall.rb +1 -0
- metadata +24 -14
- data/rails/init.rb +0 -2
data/.gitignore
ADDED
data/CHANGELOG
CHANGED
data/README.md
CHANGED
@@ -21,14 +21,16 @@ vendor/plugins/rakismet/generators/rakismet/templates/config/initializers/rakism
|
|
21
21
|
As a gem
|
22
22
|
--------
|
23
23
|
|
24
|
-
`gem install rakismet`
|
25
|
-
|
24
|
+
`gem install rakismet`
|
25
|
+
|
26
|
+
In config/environment.rb, require the gem by adding `config.gem 'rakismet'`
|
27
|
+
within the config block.
|
26
28
|
|
27
29
|
From your app root, run `./script/generate rakismet` to create the Rakismet
|
28
30
|
initializer.
|
29
31
|
|
30
32
|
Getting Started
|
31
|
-
|
33
|
+
===============
|
32
34
|
|
33
35
|
Once you've installed Rakismet via your method of choice, you'll need an API
|
34
36
|
key from the folks at WordPress. Head on over to http://wordpress.com/api-keys/
|
@@ -39,49 +41,19 @@ Edit config/initializers/rakismet.rb and fill in `Rakismet::URL` and
|
|
39
41
|
from WordPress.
|
40
42
|
|
41
43
|
If you wish to use another Akismet-compatible API provider such as TypePad's
|
42
|
-
antispam service, you'll also need to change the `Rakismet::HOST
|
43
|
-
|
44
|
-
Finally, introduce Rakismet to your application. Let's assume you have a
|
45
|
-
Comment model and a CommentsController:
|
46
|
-
|
47
|
-
class Comment < ActiveRecord::Base
|
48
|
-
has_rakismet
|
49
|
-
end
|
50
|
-
|
51
|
-
class CommentsController < ActionController::Base
|
52
|
-
has_rakismet
|
53
|
-
end
|
54
|
-
|
55
|
-
|
56
|
-
Basic Usage
|
57
|
-
===========
|
44
|
+
antispam service, you'll also need to change the `Rakismet::HOST` to your
|
45
|
+
service provider's endpoint.
|
58
46
|
|
59
|
-
Rakismet
|
60
|
-
|
61
|
-
`spam?`
|
62
|
-
|
63
|
-
From within a CommentsController action, simply call `@comment.spam?` to get a
|
64
|
-
true/false response. True means it's spam, false means it's not. Well,
|
65
|
-
usually; it's possible something went wrong and Akismet returned an error
|
66
|
-
message. `@comment.spam?` will return false if this happens. You can check
|
67
|
-
`@comment.akismet_response` to be certain; anything other than 'true' or
|
68
|
-
'false' means you got an error. That said, as long as you're collecting the
|
69
|
-
data listed above it's probably sufficient to check `spam?` alone.
|
70
|
-
|
71
|
-
`ham!` and `spam!`
|
72
|
-
|
73
|
-
Akismet works best with your feedback. If you spot a comment that was
|
74
|
-
erroneously marked as spam, `@comment.ham!` will resubmit to Akismet, marked
|
75
|
-
as a false positive. Likewise if they missed a spammy comment,
|
76
|
-
`@comment.spam!` will resubmit marked as spam.
|
47
|
+
Rakismet::Model
|
48
|
+
---------------
|
77
49
|
|
50
|
+
First, introduce Rakismet to your model:
|
78
51
|
|
79
|
-
|
80
|
-
|
52
|
+
class Comment
|
53
|
+
include Rakismet::Model
|
54
|
+
end
|
81
55
|
|
82
|
-
Rakismet sends the following information to the spam-hungry robots at Akismet
|
83
|
-
This means these attributes should be stored in your Comment model or
|
84
|
-
accessible through that class's associations.
|
56
|
+
Rakismet sends the following information to the spam-hungry robots at Akismet:
|
85
57
|
|
86
58
|
author : name submitted with the comment
|
87
59
|
author_url : URL submitted with the comment
|
@@ -93,56 +65,92 @@ accessible through that class's associations.
|
|
93
65
|
user_agent : user agent string
|
94
66
|
referrer : http referer
|
95
67
|
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
current request object, if there is one. This means Rakismet can operate
|
100
|
-
asynchronously by storing the request attributes and validating the comment at
|
101
|
-
a later time. Or it can operate synchronously by plucking the request
|
102
|
-
attributes from the environment at the time the comment is initially submitted
|
103
|
-
and validating on the spot. The latter could work well with a before_create
|
104
|
-
callback.
|
105
|
-
|
106
|
-
|
107
|
-
Customizing the Comment Model
|
108
|
-
=============================
|
68
|
+
By default, Rakismet just looks for attributes or methods on your class that
|
69
|
+
match these names. You don't have to have accessors that match these exactly,
|
70
|
+
however. If yours differ, just tell Rakismet what to call them:
|
109
71
|
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
class Comment < ActiveRecord::Base
|
116
|
-
has_rakismet :author => :commenter_name,
|
117
|
-
:author_email => :commenter_email
|
72
|
+
class Comment
|
73
|
+
include Rakismet::Model
|
74
|
+
attr_accessor :commenter_name, :commenter_email
|
75
|
+
rakismet_attributes :author => :commenter_name,
|
76
|
+
:author_email => :commenter_email
|
118
77
|
end
|
119
78
|
|
120
79
|
Or you can pass in a proc, to access associations:
|
121
80
|
|
122
81
|
class Comment < ActiveRecord::Base
|
82
|
+
include Rakismet::Model
|
123
83
|
belongs_to :author
|
124
|
-
|
125
|
-
|
84
|
+
rakismet_attributes :author => proc { author.name },
|
85
|
+
:author_email => proc { author.email }
|
126
86
|
end
|
127
87
|
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
88
|
+
Rakismet::Controller
|
89
|
+
--------------------
|
90
|
+
Perhaps you want to check a comment's spam status at creation time, and you
|
91
|
+
have no need to keep track of request-specific information such as the user's
|
92
|
+
IP, user agent, or referrer.
|
133
93
|
|
134
|
-
|
135
|
-
|
94
|
+
You can add Rakismet to a controller and the IP, user agent, and referrer will
|
95
|
+
be taken from the current request instead of your model instance.
|
136
96
|
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
`:except` parameters that work like the standard before/around/after filter
|
141
|
-
options.
|
97
|
+
class MyController < ActionController::Base
|
98
|
+
include Rakismet::Controller
|
99
|
+
end
|
142
100
|
|
143
|
-
|
144
|
-
|
101
|
+
Since you probably won't be checking for spam in every action, Rakismet takes
|
102
|
+
`:only` and `:except` options just like other filters. You can reduce overhead
|
103
|
+
by specifying just the appropriate actions:
|
104
|
+
|
105
|
+
class MyController < ActionController::Base
|
106
|
+
include Rakismet::Controller
|
107
|
+
rakismet_filter :only => :create
|
145
108
|
end
|
146
109
|
|
110
|
+
Checking For Spam
|
111
|
+
=================
|
112
|
+
|
113
|
+
Rakismet provides three methods for interacting with Akismet:
|
114
|
+
|
115
|
+
* `spam?`
|
116
|
+
|
117
|
+
Simply call `@comment.spam?` to get a true/false response. True means it's spam, false means it's not. Well, usually; it's possible something went wrong
|
118
|
+
and Akismet returned an error message. `@comment.spam?` will return false if
|
119
|
+
this happens. You can check `@comment.akismet_response` to be certain;
|
120
|
+
anything other than 'true' or 'false' means you got an error. That said, as
|
121
|
+
long as you're collecting the data listed above it's probably sufficient to
|
122
|
+
check `spam?` alone.
|
123
|
+
|
124
|
+
Keep in mind that if you call `spam?` from within a controller action that
|
125
|
+
uses the Rakismet filter, the user IP, user agent, and referrer will be taken
|
126
|
+
from the current request regardless of what your model attributes are. In
|
127
|
+
other words: if you're not verifying comments at the moment they're submitted,
|
128
|
+
you probably want to store those attributes rather than rely on the controller
|
129
|
+
methods.
|
130
|
+
|
131
|
+
* `ham!` and
|
132
|
+
* `spam!`
|
133
|
+
|
134
|
+
Akismet works best with your feedback. If you spot a comment that was
|
135
|
+
erroneously marked as spam, `@comment.ham!` will resubmit to Akismet, marked
|
136
|
+
as a false positive. Likewise if they missed a spammy comment,
|
137
|
+
`@comment.spam!` will resubmit marked as spam.
|
138
|
+
|
139
|
+
Updating from Rakismet < 0.4
|
140
|
+
----------------------------
|
141
|
+
There were some significant changes to the API in version 0.4. This was done
|
142
|
+
to make Rakismet easier to use with persistence layers other than
|
143
|
+
ActiveRecord.
|
144
|
+
|
145
|
+
If you're updating from an older version, please note:
|
146
|
+
|
147
|
+
* Rakismet is no longer automatically injected into ActiveRecord and
|
148
|
+
ActionController. You'll need to manually include Rakismet with
|
149
|
+
`include Rakismet::Model` and `include Rakismet::Controller`.
|
150
|
+
* `ActiveRecord::Base#has_rakismet` now becomes
|
151
|
+
`Rakismet::Model#rakismet_attrs`.
|
152
|
+
* `ActionController::Base#has_rakismet` now becomes
|
153
|
+
`Rakismet::Controller#rakismet_filter`.
|
154
|
+
|
147
155
|
--------------------------------------------------------------
|
148
156
|
Copyright (c) 2008 Josh French, released under the MIT license
|
data/Rakefile
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "rakismet"
|
8
|
+
gem.summary = %Q{Akismet and TypePad AntiSpam integration for Rails.}
|
9
|
+
gem.description = %Q{Rakismet is the easiest way to integrate Akismet or TypePad's AntiSpam into your Rails app.}
|
10
|
+
gem.email = "josh@digitalpulp.com"
|
11
|
+
gem.homepage = "http://github.com/jfrench/rakismet"
|
12
|
+
gem.authors = ["Josh French"]
|
13
|
+
gem.rubyforge_project = %q{rakismet}
|
14
|
+
end
|
15
|
+
Jeweler::GemcutterTasks.new
|
16
|
+
rescue LoadError
|
17
|
+
puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
|
18
|
+
end
|
19
|
+
|
20
|
+
require 'spec/rake/spectask'
|
21
|
+
Spec::Rake::SpecTask.new(:spec) do |spec|
|
22
|
+
spec.libs << 'lib' << 'spec'
|
23
|
+
spec.spec_files = FileList['spec/**/*_spec.rb']
|
24
|
+
end
|
25
|
+
|
26
|
+
task :default => :spec
|
data/VERSION.yml
ADDED
data/install.rb
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
File.open(File.join(RAILS_ROOT, %w(config initializers rakismet.rb)) , 'w') do |f|
|
2
|
+
f.puts "Rakismet::KEY = ''"
|
3
|
+
f.puts "Rakismet::URL = ''"
|
4
|
+
f.puts "Rakismet::HOST = 'rest.akismet.com'"
|
5
|
+
end
|
6
|
+
|
7
|
+
puts "If you're updating from Rakismet < 0.4, please see the README for important changes to the API."
|
@@ -1,9 +1,10 @@
|
|
1
1
|
module Rakismet
|
2
|
-
module
|
2
|
+
module Controller
|
3
3
|
|
4
4
|
def self.included(base)
|
5
5
|
base.class_eval do
|
6
6
|
extend ClassMethods
|
7
|
+
around_filter :rakismet
|
7
8
|
end
|
8
9
|
end
|
9
10
|
|
@@ -15,7 +16,7 @@ module Rakismet
|
|
15
16
|
private :rakismet
|
16
17
|
|
17
18
|
module ClassMethods
|
18
|
-
def
|
19
|
+
def rakismet_filter(opts={})
|
19
20
|
skip_filter :rakismet # in case we're inheriting from another Rakismeted controller
|
20
21
|
opts.assert_valid_keys(:only, :except)
|
21
22
|
self.around_filter :rakismet, opts
|
@@ -1,5 +1,5 @@
|
|
1
1
|
module Rakismet
|
2
|
-
module
|
2
|
+
module Model
|
3
3
|
|
4
4
|
def self.included(base)
|
5
5
|
base.class_eval do
|
@@ -7,11 +7,12 @@ module Rakismet
|
|
7
7
|
class_inheritable_hash :akismet_attrs
|
8
8
|
extend ClassMethods
|
9
9
|
include InstanceMethods
|
10
|
+
self.rakismet_attrs
|
10
11
|
end
|
11
12
|
end
|
12
13
|
|
13
14
|
module ClassMethods
|
14
|
-
def
|
15
|
+
def rakismet_attrs(args={})
|
15
16
|
self.akismet_attrs ||= {}
|
16
17
|
[:comment_type, :author, :author_url, :author_email, :content].each do |field|
|
17
18
|
# clunky, but throwing around +type+ will break your heart
|
data/lib/rakismet.rb
CHANGED
@@ -1,15 +1,13 @@
|
|
1
1
|
require 'net/http'
|
2
2
|
require 'uri'
|
3
|
+
require 'yaml'
|
3
4
|
|
4
5
|
module Rakismet
|
5
|
-
module Version
|
6
|
-
Major = '0'
|
7
|
-
Minor = '3'
|
8
|
-
Tiny = '6'
|
9
|
-
end
|
10
|
-
|
11
6
|
def self.version
|
12
|
-
|
7
|
+
@version ||= begin
|
8
|
+
version = YAML.load_file(File.join(File.dirname(__FILE__), %w(.. VERSION.yml)))
|
9
|
+
[version[:major], version[:minor], version[:patch]].join('.')
|
10
|
+
end
|
13
11
|
end
|
14
12
|
|
15
13
|
class Base
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
|
3
|
+
ActionController::Routing::Routes.draw do |map|
|
4
|
+
map.connect ':controller/:action/:id'
|
5
|
+
end
|
6
|
+
|
7
|
+
class StubController < ActionController::Base
|
8
|
+
include Rakismet::Controller
|
9
|
+
def one ; render :nothing => true; end
|
10
|
+
def two ; render :nothing => true; end
|
11
|
+
end
|
12
|
+
|
13
|
+
describe StubController do
|
14
|
+
|
15
|
+
it "should set Rakismet::Base.rakismet_binding" do
|
16
|
+
Rakismet::Base.should_receive(:rakismet_binding=).twice
|
17
|
+
get :one
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should return Rakismet::Base.rakismet_binding to nil after request" do
|
21
|
+
get :one
|
22
|
+
Rakismet::Base.rakismet_binding.should be_nil
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should add around_filter" do
|
26
|
+
StubController.filter_chain.map(&:class).should include(ActionController::Filters::AroundFilter)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe StubController.subclass('OnlyActions') { rakismet_filter(:only => :one) } do
|
31
|
+
|
32
|
+
it "should add around filter to specified actions" do
|
33
|
+
Rakismet::Base.should_receive(:rakismet_binding=).twice
|
34
|
+
get :one
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should not add around filter to unspecified actions" do
|
38
|
+
Rakismet::Base.should_not_receive(:rakismet_binding=)
|
39
|
+
get :two
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe StubController.subclass('ExceptActions') { rakismet_filter(:except => :one) } do
|
44
|
+
|
45
|
+
it "should not add around filter to specified actions" do
|
46
|
+
Rakismet::Base.should_not_receive(:rakismet_binding=)
|
47
|
+
get :one
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should add around filter to other actions" do
|
51
|
+
Rakismet::Base.should_receive(:rakismet_binding=).twice
|
52
|
+
get :two
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
|
3
|
+
describe Rakismet::Base do
|
4
|
+
|
5
|
+
before do
|
6
|
+
load File.join(RAILS_ROOT, 'config', 'initializers', 'rakismet.rb')
|
7
|
+
end
|
8
|
+
|
9
|
+
describe ".validate_constants" do
|
10
|
+
it "should raise an error if key is not found" do
|
11
|
+
Rakismet::KEY = ""
|
12
|
+
lambda { Rakismet::Base.send(:validate_constants) }.should raise_error(Rakismet::Undefined)
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should raise an error if url is not found" do
|
16
|
+
Rakismet::URL = ""
|
17
|
+
lambda { Rakismet::Base.send(:validate_constants) }.should raise_error(Rakismet::Undefined)
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should raise an error if host is not found" do
|
21
|
+
Rakismet::HOST = ""
|
22
|
+
lambda { Rakismet::Base.send(:validate_constants) }.should raise_error(Rakismet::Undefined)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe ".validate_key" do
|
27
|
+
it "should set @@valid_key = true if key is valid" do
|
28
|
+
Net::HTTP.stub!(:start).and_return([nil, 'valid'])
|
29
|
+
Rakismet::Base.validate_key
|
30
|
+
Rakismet::Base.valid_key?.should be_true
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should set @@valid_key = false if key is invalid" do
|
34
|
+
Net::HTTP.stub!(:start).and_return([nil, 'invalid'])
|
35
|
+
Rakismet::Base.validate_key
|
36
|
+
Rakismet::Base.valid_key?.should be_false
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should build url with host" do
|
40
|
+
host = "api.antispam.typepad.com"
|
41
|
+
Rakismet::HOST = host
|
42
|
+
Net::HTTP.should_receive(:start).with(host).and_yield(mock(:http).as_null_object)
|
43
|
+
Rakismet::Base.validate_key
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe ".akismet_call" do
|
48
|
+
before do
|
49
|
+
@http = mock(:http)
|
50
|
+
Net::HTTP.stub!(:start).and_yield(@http)
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should build url with API key for the correct host" do
|
54
|
+
host = "api.antispam.typepad.com"
|
55
|
+
Rakismet::HOST = host
|
56
|
+
Net::HTTP.should_receive(:start).with("#{Rakismet::KEY}.#{host}").and_yield(mock(:http).as_null_object)
|
57
|
+
Rakismet::Base.send(:akismet_call, 'bogus-function')
|
58
|
+
end
|
59
|
+
|
60
|
+
it "should post data to named function" do
|
61
|
+
@http.should_receive(:post).with('/1.1/bogus-function', %r(foo=#{CGI.escape 'escape//this'}), Rakismet::HEADERS)
|
62
|
+
Rakismet::Base.send(:akismet_call, 'bogus-function', { :foo => 'escape//this' })
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should return response.body" do
|
66
|
+
Net::HTTP.stub!(:start).and_return([nil, 'akismet response'])
|
67
|
+
Rakismet::Base.send(:akismet_call, 'bogus-function').should eql('akismet response')
|
68
|
+
end
|
69
|
+
|
70
|
+
it "should build query string when params are nil" do
|
71
|
+
lambda {
|
72
|
+
Rakismet::Base.send(:akismet_call, 'bogus-function', { :nil_param => nil })
|
73
|
+
}.should_not raise_error(NoMethodError)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
@@ -0,0 +1,223 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
require 'ostruct'
|
3
|
+
|
4
|
+
class AkismetModel
|
5
|
+
include Rakismet::Model
|
6
|
+
end
|
7
|
+
|
8
|
+
class StoredParams
|
9
|
+
include Rakismet::Model
|
10
|
+
attr_accessor :user_ip, :user_agent, :referrer
|
11
|
+
end
|
12
|
+
|
13
|
+
describe AkismetModel do
|
14
|
+
|
15
|
+
before do
|
16
|
+
@model = AkismetModel.new
|
17
|
+
comment_attrs.each_pair { |k,v| @model.stub!(k).and_return(v) }
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should have default mappings" do
|
21
|
+
[:comment_type, :author, :author_email, :author_url, :content].each do |field|
|
22
|
+
fieldname = field.to_s =~ %r(^comment_) ? field : "comment_#{field}".intern
|
23
|
+
AkismetModel.akismet_attrs[fieldname].should eql(field)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should have nil placeholders for optional binding variables" do
|
28
|
+
[:user_ip, :user_agent, :referrer].each do |field|
|
29
|
+
AkismetModel.akismet_attrs.should have_key(field)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
mapped_params = { :comment_type => :type2, :author => :author2, :content => :content2,
|
34
|
+
:author_email => :author_email2, :author_url => :author_url2 }
|
35
|
+
|
36
|
+
describe override = AkismetModel.subclass('Override') { rakismet_attrs(mapped_params.dup) } do
|
37
|
+
it "should override default mappings" do
|
38
|
+
[:comment_type, :author, :author_url, :author_email, :content].each do |field|
|
39
|
+
fieldname = field.to_s =~ %r(^comment_) ? field : "comment_#{field}".intern
|
40
|
+
override.akismet_attrs[fieldname].should eql(mapped_params[field])
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
extended_params = { :user_ip => :stored_ip, :user_agent => :stored_agent,
|
46
|
+
:referrer => :stored_referrer }
|
47
|
+
|
48
|
+
describe extended = AkismetModel.subclass('Extended') { rakismet_attrs(extended_params.dup) } do
|
49
|
+
|
50
|
+
before do
|
51
|
+
@extended = extended.new
|
52
|
+
attrs = comment_attrs(:stored_ip => '127.0.0.1', :stored_agent => 'RSpec', :stored_referrer => 'http://test.host/')
|
53
|
+
attrs.each_pair { |k,v| @extended.stub!(k).and_return(v) }
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should extend optional mappings" do
|
57
|
+
[:user_ip, :user_agent, :referrer].each do |field|
|
58
|
+
extended.akismet_attrs[field].should eql(extended_params[field])
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
describe ".spam!" do
|
63
|
+
it "should use stored request vars if available" do
|
64
|
+
Rakismet::Base.should_receive(:akismet_call).
|
65
|
+
with('submit-spam', akismet_attrs(:user_ip => '127.0.0.1', :user_agent => 'RSpec',
|
66
|
+
:referrer => 'http://test.host/'))
|
67
|
+
@extended.spam!
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
describe ".ham!" do
|
72
|
+
it "should use stored request vars if available" do
|
73
|
+
Rakismet::Base.should_receive(:akismet_call).
|
74
|
+
with('submit-ham', akismet_attrs(:user_ip => '127.0.0.1', :user_agent => 'RSpec',
|
75
|
+
:referrer => 'http://test.host/'))
|
76
|
+
@extended.ham!
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
@proc = proc { author.reverse }
|
82
|
+
block_params = { :author => @proc }
|
83
|
+
|
84
|
+
describe block = AkismetModel.subclass('Block') { rakismet_attrs(block_params) } do
|
85
|
+
|
86
|
+
before do
|
87
|
+
@block = block.new
|
88
|
+
comment_attrs.each_pair { |k,v| @block.stub!(k).and_return(v) }
|
89
|
+
end
|
90
|
+
|
91
|
+
it "should accept a block" do
|
92
|
+
block.akismet_attrs[:author].should eql(@proc)
|
93
|
+
end
|
94
|
+
|
95
|
+
it "should eval block with self = instance" do
|
96
|
+
data = @block.send(:akismet_data)
|
97
|
+
data[:comment_author].should eql(comment_attrs[:author].reverse)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
extra_params = { :extra => :extra, :another => lambda { } }
|
102
|
+
|
103
|
+
describe extra = AkismetModel.subclass('ExtraParams') { rakismet_attrs(extra_params.dup) } do
|
104
|
+
it "should map additional attributes" do
|
105
|
+
[:extra, :another].each do |field|
|
106
|
+
extra.akismet_attrs[field].should eql(extra_params[field])
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
string_params = { :comment_type => 'pingback' }
|
112
|
+
|
113
|
+
describe string = AkismetModel.subclass('StringParams') { rakismet_attrs(string_params) } do
|
114
|
+
|
115
|
+
before do
|
116
|
+
@string = string.new
|
117
|
+
comment_attrs.each_pair { |k,v| @string.stub!(k).and_return(v) }
|
118
|
+
end
|
119
|
+
|
120
|
+
it "should map string attributes" do
|
121
|
+
@string.send(:akismet_data)[:comment_type].should eql('pingback')
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
describe ".spam?" do
|
126
|
+
|
127
|
+
before do
|
128
|
+
Rakismet::Base.rakismet_binding = request_binding
|
129
|
+
end
|
130
|
+
|
131
|
+
it "should eval request variables in context of Base.rakismet_binding" do
|
132
|
+
Rakismet::Base.should_receive(:akismet_call).
|
133
|
+
with('comment-check', akismet_attrs.merge(:user_ip => '127.0.0.1',
|
134
|
+
:user_agent => 'RSpec',
|
135
|
+
:referrer => 'http://test.host/referrer'))
|
136
|
+
@model.spam?
|
137
|
+
end
|
138
|
+
|
139
|
+
it "should be true if comment is spam" do
|
140
|
+
Rakismet::Base.stub!(:akismet_call).and_return('true')
|
141
|
+
@model.should be_spam
|
142
|
+
end
|
143
|
+
|
144
|
+
it "should be false if comment is not spam" do
|
145
|
+
Rakismet::Base.stub!(:akismet_call).and_return('false')
|
146
|
+
@model.should_not be_spam
|
147
|
+
end
|
148
|
+
|
149
|
+
it "should set last_akismet_response" do
|
150
|
+
Rakismet::Base.stub!(:akismet_call).and_return('response')
|
151
|
+
@model.spam?
|
152
|
+
@model.akismet_response.should eql('response')
|
153
|
+
end
|
154
|
+
|
155
|
+
it "should not throw an error if request vars are missing" do
|
156
|
+
Rakismet::Base.rakismet_binding = nil_binding
|
157
|
+
lambda { @model.spam? }.should_not raise_error(NoMethodError)
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
describe StoredParams do
|
162
|
+
before do
|
163
|
+
Rakismet::Base.rakismet_binding = nil
|
164
|
+
@model = StoredParams.new
|
165
|
+
comment_attrs.each_pair { |k,v| @model.stub!(k).and_return(v) }
|
166
|
+
end
|
167
|
+
|
168
|
+
it "should use local values if Rakismet binding is not present" do
|
169
|
+
@model.user_ip = '127.0.0.1'
|
170
|
+
@model.user_agent = 'RSpec'
|
171
|
+
@model.referrer = 'http://test.host/referrer'
|
172
|
+
|
173
|
+
Rakismet::Base.should_receive(:akismet_call).
|
174
|
+
with('comment-check', akismet_attrs.merge(:user_ip => '127.0.0.1',
|
175
|
+
:user_agent => 'RSpec',
|
176
|
+
:referrer => 'http://test.host/referrer'))
|
177
|
+
@model.spam?
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
describe ".spam!" do
|
182
|
+
it "should call Base.akismet_call with submit-spam" do
|
183
|
+
Rakismet::Base.should_receive(:akismet_call).with('submit-spam', akismet_attrs)
|
184
|
+
@model.spam!
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
describe ".ham!" do
|
189
|
+
it "should call Base.akismet_call with submit-ham" do
|
190
|
+
Rakismet::Base.should_receive(:akismet_call).with('submit-ham', akismet_attrs)
|
191
|
+
@model.ham!
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
private
|
196
|
+
|
197
|
+
def comment_attrs(attrs={})
|
198
|
+
{ :comment_type => 'test', :author => 'Rails test',
|
199
|
+
:author_email => 'test@test.host', :author_url => 'test.host',
|
200
|
+
:content => 'comment content', :blog => Rakismet::URL }.merge(attrs)
|
201
|
+
end
|
202
|
+
|
203
|
+
def akismet_attrs(attrs={})
|
204
|
+
{ :comment_type => 'test', :comment_author_email => 'test@test.host',
|
205
|
+
:comment_author => 'Rails test', :comment_author_url => 'test.host',
|
206
|
+
:comment_content => 'comment content' }.merge(attrs)
|
207
|
+
end
|
208
|
+
|
209
|
+
def request_binding
|
210
|
+
request = OpenStruct.new(:remote_ip => '127.0.0.1',
|
211
|
+
:user_agent => 'RSpec',
|
212
|
+
:referer => 'http://test.host/referrer')
|
213
|
+
binding
|
214
|
+
end
|
215
|
+
|
216
|
+
def nil_binding
|
217
|
+
request = OpenStruct.new(:remote_ip => nil,
|
218
|
+
:user_agent => nil,
|
219
|
+
:referer => nil)
|
220
|
+
binding
|
221
|
+
end
|
222
|
+
|
223
|
+
end
|
data/spec/spec.opts
ADDED
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
ENV["RAILS_ENV"] = "test"
|
2
|
+
require File.expand_path(File.dirname(__FILE__) + "/../../../../config/environment")
|
3
|
+
require 'spec'
|
4
|
+
require 'spec/rails'
|
5
|
+
|
6
|
+
Spec::Runner.configure do |config|
|
7
|
+
|
8
|
+
end
|
9
|
+
|
10
|
+
class Class
|
11
|
+
# Creates a new subclass of self, with a name "under" our own name. Example:
|
12
|
+
#
|
13
|
+
# x = Foo::Bar.subclass('Zap'){}
|
14
|
+
# x.name # => Foo::Bar::Zap_1
|
15
|
+
# x.superclass.name # => Foo::Bar
|
16
|
+
#
|
17
|
+
# Removed from RSpec after 1.1.something; reproduced here because much of the
|
18
|
+
# spec suite was already written with dynamic class creation.
|
19
|
+
def subclass(base_name, &body)
|
20
|
+
klass = Class.new(self)
|
21
|
+
class_name = "#{self.name}_#{base_name}"
|
22
|
+
instance_eval do
|
23
|
+
const_set(class_name, klass)
|
24
|
+
end
|
25
|
+
klass.instance_eval(&body)
|
26
|
+
klass
|
27
|
+
end
|
28
|
+
end
|
data/uninstall.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
File.delete(File.join(RAILS_ROOT, %w(config initializers rakismet.rb)))
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rakismet
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Josh French
|
@@ -9,11 +9,11 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date:
|
12
|
+
date: 2010-02-25 00:00:00 -05:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
16
|
-
description: Rakismet is
|
16
|
+
description: Rakismet is the easiest way to integrate Akismet or TypePad's AntiSpam into your Rails app.
|
17
17
|
email: josh@digitalpulp.com
|
18
18
|
executables: []
|
19
19
|
|
@@ -21,24 +21,31 @@ extensions: []
|
|
21
21
|
|
22
22
|
extra_rdoc_files:
|
23
23
|
- README.md
|
24
|
-
- MIT-LICENSE
|
25
24
|
files:
|
25
|
+
- .gitignore
|
26
26
|
- CHANGELOG
|
27
|
-
- README.md
|
28
27
|
- MIT-LICENSE
|
29
|
-
-
|
30
|
-
-
|
31
|
-
-
|
32
|
-
- lib/rakismet/model_extensions.rb
|
28
|
+
- README.md
|
29
|
+
- Rakefile
|
30
|
+
- VERSION.yml
|
33
31
|
- generators/rakismet/rakismet_generator.rb
|
34
32
|
- generators/rakismet/templates/config/initializers/rakismet.rb
|
33
|
+
- install.rb
|
34
|
+
- lib/rakismet.rb
|
35
|
+
- lib/rakismet/controller.rb
|
36
|
+
- lib/rakismet/model.rb
|
37
|
+
- spec/controllers/rakismet_controller_spec.rb
|
38
|
+
- spec/models/base_spec.rb
|
39
|
+
- spec/models/rakismet_model_spec.rb
|
40
|
+
- spec/spec.opts
|
41
|
+
- spec/spec_helper.rb
|
42
|
+
- uninstall.rb
|
35
43
|
has_rdoc: true
|
36
44
|
homepage: http://github.com/jfrench/rakismet
|
37
45
|
licenses: []
|
38
46
|
|
39
47
|
post_install_message:
|
40
48
|
rdoc_options:
|
41
|
-
- --inline-source
|
42
49
|
- --charset=UTF-8
|
43
50
|
require_paths:
|
44
51
|
- lib
|
@@ -57,9 +64,12 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
57
64
|
requirements: []
|
58
65
|
|
59
66
|
rubyforge_project: rakismet
|
60
|
-
rubygems_version: 1.3.
|
67
|
+
rubygems_version: 1.3.5
|
61
68
|
signing_key:
|
62
69
|
specification_version: 3
|
63
|
-
summary:
|
64
|
-
test_files:
|
65
|
-
|
70
|
+
summary: Akismet and TypePad AntiSpam integration for Rails.
|
71
|
+
test_files:
|
72
|
+
- spec/controllers/rakismet_controller_spec.rb
|
73
|
+
- spec/models/base_spec.rb
|
74
|
+
- spec/models/rakismet_model_spec.rb
|
75
|
+
- spec/spec_helper.rb
|
data/rails/init.rb
DELETED