rakismet 0.3.6 → 0.4.0
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.
- 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