beans-rakismet 1.2.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,11 @@
1
+ .DS_Store
2
+ *.tmproj
3
+ tmtags
4
+ *.swp
5
+ *.swo
6
+ *.un~
7
+ coverage
8
+ rdoc
9
+ pkg
10
+ Gemfile.lock
11
+ .bundle
@@ -0,0 +1,35 @@
1
+ * Clean up gemspec and load paths [Steven Harman]
2
+ * Add Akismet is_test param [Steven Harman]
3
+ * Add Akismet user_role attribute [Steven Harman]
4
+ = 1.2.1
5
+ * Fix deprecated usage of HTTPResponse for Ruby 1.9.3 [Leonid Shevtsov]
6
+ = 1.2.0
7
+ * Rakismet attribute mappings are now inheritable
8
+ = 1.1.2
9
+ * Explicitly load version
10
+ = 1.1.1
11
+ * Fix SafeBuffer error under Rails 3.0.8 and 3.0.9 [Brandon Ferguson]
12
+ * Readme cleanup [Zeke Sikelianos]
13
+ * Drop Jeweler in favor of Bundler's gem tasks
14
+ = 1.1.0
15
+ * Add HTTP Proxy support [Francisco Trindade]
16
+ = 1.0.1
17
+ * Fix hash access for Ruby 1.9 [Alex Crichton]
18
+ = 1.0.0
19
+ * Update for Rails 3
20
+ * Remove filters and replace with middleware
21
+ * Remove initializers and replace with Railtie
22
+ = 0.4.0
23
+ * Rakismet is no longer injected into ActiveRecord or ActionController
24
+ * API changes to support newly decoupled modules
25
+ * Use Jeweler to manage gemspec
26
+ = 0.3.6
27
+ * Allow attributes to fall through to methods or AR attributes
28
+ = 0.3.5
29
+ * Added gemspec and rails/init.rb so rakismet can work as a gem [Michael Air]
30
+ * Added generator template and manifest [Michael Air]
31
+ = 0.3.0
32
+ * Abstract out Rakismet version string
33
+ * Set default Akismet Host
34
+ * Abstract out the Akismet host [Mike Burns]
35
+ * Started keeping a changelog :P
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2008 Josh French
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,229 @@
1
+ Rakismet
2
+ ========
3
+
4
+ **Akismet** (<http://akismet.com/>) is a collaborative spam filtering service.
5
+ **Rakismet** is easy Akismet integration with Rails and rack apps. TypePad's
6
+ AntiSpam service and generic Akismet endpoints are supported.
7
+
8
+ Compatibility
9
+ =============
10
+
11
+ **Rakismet >= 1.0.0** work with Rails 3 and other Rack-based frameworks.
12
+
13
+ **Rakismet <= 0.4.2** is compatible with Rails 2.
14
+
15
+ Getting Started
16
+ ===============
17
+
18
+ Once you've installed the Rakismet gem and added it to your application's Gemfile,
19
+ you'll need an API key. Head on over to http://akismet.com/signup/ and sign up
20
+ for a new username.
21
+
22
+ Configure the Rakismet key and the URL of your application by setting the following
23
+ in application.rb:
24
+
25
+ ```ruby
26
+ config.rakismet.key = 'your wordpress key'
27
+ config.rakismet.url = 'http://yourdomain.com/'
28
+ ```
29
+
30
+ or an initializer, for example `config/initializers/rakismet.rb`:
31
+
32
+ ```ruby
33
+ YourApp::Application.config.rakismet.key = 'your wordpress key'
34
+ YourApp::Application.config.rakismet.url = 'http://yourdomain.com/'
35
+ ```
36
+
37
+ If you wish to use another Akismet-compatible API provider such as TypePad's
38
+ antispam service, you'll also need to set `config.rakismet.host` to your service
39
+ provider's endpoint.
40
+
41
+ If you want to use a proxy to access akismet (i.e. your application is behind a
42
+ firewall), set the proxy_host and proxy_port option.
43
+
44
+ ```ruby
45
+ config.rakismet.proxy_host = 'http://yourdomain.com/'
46
+ config.rakismet.proxy_port = '8080'
47
+ ```
48
+
49
+ Checking For Spam
50
+ -----------------
51
+
52
+ First, introduce Rakismet to your model:
53
+
54
+ ```ruby
55
+ class Comment
56
+ include Rakismet::Model
57
+ end
58
+ ```
59
+
60
+ With Rakismet mixed in to your model, you'll get three instance methods for interacting with
61
+ Akismet:
62
+
63
+ * `spam?` submits the comment to Akismet and returns true if Akismet thinks the comment is spam, false if not.
64
+ * `ham!` resubmits a valid comment that Akismet erroneously marked as spam (marks it as a false positive.)
65
+ * `spam!` resubmits a spammy comment that Akismet missed (marks it as a false negative.)
66
+
67
+ The `ham!` and `spam!` methods will change the value of `spam?` but their
68
+ primary purpose is to send feedback to Akismet. The service works best when you
69
+ help correct the rare mistake; please consider using these methods if you're
70
+ moderating comments or otherwise reviewing the Akismet responses.
71
+
72
+ Configuring Your Model
73
+ ----------------------
74
+
75
+ Rakismet sends the following information to the spam-hungry robots at Akismet:
76
+
77
+ author : name submitted with the comment
78
+ author_url : URL submitted with the comment
79
+ author_email : email submitted with the comment
80
+ comment_type : Defaults to comment but you can set it to trackback, pingback, or something more appropriate
81
+ content : the content submitted
82
+ permalink : the permanent URL for the entry the comment belongs to
83
+ user_ip : IP address used to submit this comment
84
+ user_agent : user agent string
85
+ referrer : referring URL (note the spelling)
86
+
87
+ By default, Rakismet just looks for attributes or methods on your class that
88
+ match these names. You don't have to have accessors that match these exactly,
89
+ however. If yours differ, just tell Rakismet what to call them:
90
+
91
+ ```ruby
92
+ class Comment
93
+ include Rakismet::Model
94
+ attr_accessor :commenter_name, :commenter_email
95
+ rakismet_attrs :author => :commenter_name, :author_email => :commenter_email
96
+ end
97
+ ```
98
+
99
+ Or you can pass in a proc, to access associations:
100
+
101
+ ```ruby
102
+ class Comment < ActiveRecord::Base
103
+ include Rakismet::Model
104
+ belongs_to :author
105
+ rakismet_attrs :author => proc { author.name },
106
+ :author_email => proc { author.email }
107
+ end
108
+ ```
109
+
110
+ You can even hard-code specific fields:
111
+
112
+ ```ruby
113
+ class Trackback
114
+ include Rakismet::Model
115
+ rakismet_attrs :comment_type => "trackback"
116
+ end
117
+ ```
118
+
119
+ Optional Request Variables
120
+ --------------------------
121
+
122
+ Akismet wants certain information about the request environment: remote IP, the
123
+ user agent string, and the HTTP referer when available. Normally, Rakismet
124
+ asks your model for these. Storing this information on your model allows you to
125
+ call the `spam?` method at a later time. For instance, maybe you're storing your
126
+ comments in an administrative queue or processing them with a background job.
127
+
128
+ You don't need to have these three attributes on your model, however. If you
129
+ choose to omit them, Rakismet will instead look at the current request (if one
130
+ exists) and take the values from the request object instead.
131
+
132
+ This means that if you are **not storing the request variables**, you must call
133
+ `spam?` from within the controller action that handles comment submissions. That
134
+ way the IP, user agent, and referer will belong to the person submitting the
135
+ comment. If you're not storing the request variables and you call `spam?` at a
136
+ later time, the request information will be missing or invalid and Akismet won't
137
+ be able to do its job properly.
138
+
139
+ If you've decided to handle the request variables yourself, you can disable the
140
+ middleware responsible for tracking the request information by adding this to
141
+ your app initialization:
142
+
143
+ ```ruby
144
+ config.rakismet.use_middleware = false
145
+ ```
146
+
147
+ Testing
148
+ -------
149
+
150
+ Rakismet can be configued to tell Akismet that it should operate in test mode -
151
+ so Akismet will not change its behavior based on any test API calls, meaning
152
+ they will have no training effect. That means your tests can be somewhat
153
+ repeatable in the sense that one test won't influence subsequent calls.
154
+
155
+ You can configure Rakismet for test mode via application.rb:
156
+
157
+ ```ruby
158
+ config.rakismet.test = false # <- default
159
+ config.rakismet.test = true
160
+ ```
161
+
162
+ Or via an initializer:
163
+
164
+ ```ruby
165
+ YourApp::Application.config.rakismet.test = false # <- default
166
+ YourApp::Application.config.rakismet.test = true
167
+ ```
168
+
169
+ **NOTE**: When running in Rails, Rakismet will run in test mode when your Rails
170
+ environment is `test` or `development`, unless explictly configured otherwise.
171
+ Outside of Rails Rakismet defaults to test mode turned **off**.
172
+
173
+
174
+ Verifying Responses
175
+ -------------------
176
+
177
+ If you want to see what's happening behind the scenes, after you call one of
178
+ `@comment.spam?`, `@comment.spam!` or `@comment.ham!` you can check
179
+ `@comment.akismet_response`.
180
+
181
+ This will contain the last response from the Akismet server. In the case of
182
+ `spam?` it should be `true` or `false.` For `spam!` and `ham!` it should be
183
+ `Feedback received.` If Akismet returned an error instead (e.g. if you left out
184
+ some required information) this will contain the error message.
185
+
186
+ FAQ
187
+ ===
188
+
189
+ Why does Akismet think all of my test data is spam?
190
+ ---------------------------------------------------
191
+
192
+ Akismet needs enough information to decide if your test data is spam or not.
193
+ Try to supply as much as possible, especially the author name and request
194
+ variables.
195
+
196
+ How can I simulate a spam submission?
197
+ -------------------------------------
198
+
199
+ Most people have the opposite problem, where Akismet doesn't think anything is
200
+ spam. The only guaranteed way to trigger a positive spam response is to set the
201
+ comment author to "viagra-test-123".
202
+
203
+ If you've done this and `spam?` is still returning false, you're probably
204
+ missing the user IP or one of the key/url config variables. One way to check is
205
+ to call `@comment.akismet_response`. If you are missing a required field or
206
+ there was another error, this will hold the Akismet error message. If your comment
207
+ was processed normally, this value will simply be `true` or `false`.
208
+
209
+ Can I use Rakismet with a different ORM or framework?
210
+ -----------------------------------------------------
211
+
212
+ Sure. Rakismet doesn't care what your persistence layer is. It will work with
213
+ Datamapper, a NoSQL store, or whatever next month's DB flavor is.
214
+
215
+ Rakismet also has no dependencies on Rails or any of its components, and only
216
+ uses a small Rack middleware object to do some of its magic. Depending on your
217
+ framework, you may have to modify this slightly and/or manually place it in your
218
+ stack.
219
+
220
+ You'll also need to set a few config variables by hand. Instead of
221
+ `config.rakismet.key`, `config.rakismet.url`, and `config.rakismet.host`, set
222
+ these values directly with `Rakismet.key`, `Rakismet.url`, and `Rakismet.host`.
223
+
224
+ ---------------------------------------------------------------------------
225
+
226
+ If you have any implementation or usage questions, don't hesitate to get in
227
+ touch: josh@vitamin-j.com.
228
+
229
+ Copyright (c) 2008 Josh French, released under the MIT license
@@ -0,0 +1,9 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ require 'rspec/core/rake_task'
5
+ RSpec::Core::RakeTask.new do |spec|
6
+ spec.rspec_opts = ["--color", "--format progress"]
7
+ end
8
+
9
+ task :default => :spec
@@ -0,0 +1,88 @@
1
+ require 'net/http'
2
+ require 'uri'
3
+ require 'cgi'
4
+ require 'yaml'
5
+
6
+ require 'rakismet/model'
7
+ require 'rakismet/middleware'
8
+ require 'rakismet/version'
9
+ require 'rakismet/railtie.rb' if defined?(Rails)
10
+
11
+ module Rakismet
12
+ Request = Struct.new(:user_ip, :user_agent, :referrer)
13
+ Undefined = Class.new(NameError)
14
+
15
+ class << self
16
+ attr_accessor :key, :url, :host, :proxy_host, :proxy_port, :test
17
+
18
+ def request
19
+ @request ||= Request.new
20
+ end
21
+
22
+ def set_request_vars(env)
23
+ request.user_ip, request.user_agent, request.referrer =
24
+ env['REMOTE_ADDR'], env['HTTP_USER_AGENT'], env['HTTP_REFERER']
25
+ end
26
+
27
+ def clear_request
28
+ @request = Request.new
29
+ end
30
+
31
+ def headers
32
+ @headers ||= begin
33
+ user_agent = "Rakismet/#{Rakismet::VERSION}"
34
+ user_agent = "Rails/#{Rails.version} | " + user_agent if defined?(Rails)
35
+ { 'User-Agent' => user_agent, 'Content-Type' => 'application/x-www-form-urlencoded' }
36
+ end
37
+ end
38
+
39
+ def validate_key
40
+ validate_config
41
+ akismet = URI.parse(verify_url)
42
+ response = Net::HTTP::Proxy(proxy_host, proxy_port).start(akismet.host) do |http|
43
+ data = "key=#{Rakismet.key}&blog=#{Rakismet.url}"
44
+ http.post(akismet.path, data, Rakismet.headers)
45
+ end
46
+ @valid_key = (response.body == 'valid')
47
+ end
48
+
49
+ def valid_key?
50
+ @valid_key == true
51
+ end
52
+
53
+ def akismet_call(function, args={})
54
+ validate_config
55
+ args.merge!(:blog => Rakismet.url, :is_test => Rakismet.test_mode)
56
+ akismet = URI.parse(call_url(function))
57
+ response = Net::HTTP::Proxy(proxy_host, proxy_port).start(akismet.host) do |http|
58
+ params = args.map do |k,v|
59
+ param = v.class < String ? v.to_str : v.to_s # for ActiveSupport::SafeBuffer and Nil, respectively
60
+ "#{k}=#{CGI.escape(param)}"
61
+ end
62
+ http.post(akismet.path, params.join('&'), Rakismet.headers)
63
+ end
64
+ response.body
65
+ end
66
+
67
+ protected
68
+
69
+ def verify_url
70
+ "http://#{Rakismet.host}/1.1/verify-key"
71
+ end
72
+
73
+ def call_url(function)
74
+ "http://#{Rakismet.key}.#{Rakismet.host}/1.1/#{function}"
75
+ end
76
+
77
+ def validate_config
78
+ raise Undefined, "Rakismet.key is not defined" if Rakismet.key.nil? || Rakismet.key.empty?
79
+ raise Undefined, "Rakismet.url is not defined" if Rakismet.url.nil? || Rakismet.url.empty?
80
+ raise Undefined, "Rakismet.host is not defined" if Rakismet.host.nil? || Rakismet.host.empty?
81
+ end
82
+
83
+ def test_mode
84
+ test ? 1 : 0
85
+ end
86
+ end
87
+
88
+ end
@@ -0,0 +1,16 @@
1
+ module Rakismet
2
+ class Middleware
3
+
4
+ def initialize(app)
5
+ @app = app
6
+ end
7
+
8
+ def call(env)
9
+ Rakismet.set_request_vars(env)
10
+ response = @app.call(env)
11
+ Rakismet.clear_request
12
+ response
13
+ end
14
+
15
+ end
16
+ end
@@ -0,0 +1,86 @@
1
+ module Rakismet
2
+ module Model
3
+
4
+ def self.included(base)
5
+ base.class_eval do
6
+ attr_accessor :akismet_response
7
+ class << self; attr_accessor :akismet_attrs; end
8
+ extend ClassMethods
9
+ include InstanceMethods
10
+ self.rakismet_attrs
11
+ end
12
+ end
13
+
14
+ module ClassMethods
15
+ def rakismet_attrs(args={})
16
+ self.akismet_attrs ||= {}
17
+ [:comment_type, :author, :author_url, :author_email, :content, :user_role].each do |field|
18
+ # clunky, but throwing around +type+ will break your heart
19
+ fieldname = field.to_s =~ %r(^comment_) ? field : "comment_#{field}".intern
20
+ self.akismet_attrs[fieldname] = args.delete(field) || field
21
+ end
22
+ [:user_ip, :user_agent, :referrer].each do |field|
23
+ self.akismet_attrs[field] = args.delete(field) || field
24
+ end
25
+ args.each_pair do |f,v|
26
+ self.akismet_attrs[f] = v
27
+ end
28
+ end
29
+
30
+ def inherited(subclass)
31
+ super
32
+ subclass.rakismet_attrs akismet_attrs.dup
33
+ end
34
+ end
35
+
36
+ module InstanceMethods
37
+ def spam?
38
+ if instance_variable_defined? :@_spam
39
+ @_spam
40
+ else
41
+ data = akismet_data
42
+ self.akismet_response = Rakismet.akismet_call('comment-check', data)
43
+ @_spam = self.akismet_response == 'true'
44
+ end
45
+ end
46
+
47
+ def spam!
48
+ Rakismet.akismet_call('submit-spam', akismet_data)
49
+ @_spam = true
50
+ end
51
+
52
+ def ham!
53
+ Rakismet.akismet_call('submit-ham', akismet_data)
54
+ @_spam = false
55
+ end
56
+
57
+ private
58
+
59
+ def akismet_data
60
+ akismet = self.class.akismet_attrs.keys.inject({}) do |data,attr|
61
+ mapped_field = self.class.akismet_attrs[attr]
62
+ data.merge attr => if mapped_field.is_a?(Proc)
63
+ instance_eval(&mapped_field)
64
+ elsif !mapped_field.nil? && respond_to?(mapped_field)
65
+ send(mapped_field)
66
+ elsif not [:comment_type, :author, :author_email,
67
+ :author_url, :content, :user_role,
68
+ :user_ip, :referrer,
69
+ :user_agent].include?(mapped_field)
70
+ # we've excluded any fields that appear to
71
+ # have their default unmapped values
72
+ mapped_field
73
+ elsif respond_to?(attr)
74
+ send(attr)
75
+ elsif Rakismet.request.respond_to?(attr)
76
+ Rakismet.request.send(attr)
77
+ end
78
+ end
79
+ akismet.delete_if { |k,v| v.nil? || v.empty? }
80
+ akismet[:comment_type] ||= 'comment'
81
+ akismet
82
+ end
83
+ end
84
+
85
+ end
86
+ end
@@ -0,0 +1,22 @@
1
+ require 'rails'
2
+ require 'rakismet'
3
+
4
+ module Rakismet
5
+ class Railtie < Rails::Railtie
6
+
7
+ config.rakismet = ActiveSupport::OrderedOptions.new
8
+ config.rakismet.host = 'rest.akismet.com'
9
+ config.rakismet.use_middleware = true
10
+
11
+ initializer 'rakismet.setup', :after => :load_config_initializers do |app|
12
+ Rakismet.key = app.config.rakismet[:key]
13
+ Rakismet.url = app.config.rakismet[:url]
14
+ Rakismet.host = app.config.rakismet[:host]
15
+ Rakismet.proxy_host = app.config.rakismet[:proxy_host]
16
+ Rakismet.proxy_port = app.config.rakismet[:proxy_port]
17
+ Rakismet.test = app.config.rakismet.fetch(:test) { Rails.env.test? || Rails.env.development? }
18
+ app.middleware.use Rakismet::Middleware if app.config.rakismet.use_middleware
19
+ end
20
+
21
+ end
22
+ end
@@ -0,0 +1,3 @@
1
+ module Rakismet
2
+ VERSION = "1.2.2"
3
+ end
@@ -0,0 +1,25 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/rakismet/version', __FILE__)
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = "beans-rakismet"
6
+ s.version = Rakismet::VERSION
7
+ s.platform = Gem::Platform::RUBY
8
+ s.authors = ["Josh French"]
9
+ s.email = "josh@vitamin-j.com"
10
+ s.homepage = "http://github.com/joshfrench/rakismet"
11
+ s.summary = "Akismet and TypePad AntiSpam integration for Rails."
12
+ s.description = "Rakismet is the easiest way to integrate Akismet or TypePad's AntiSpam into your Rails app."
13
+ s.date = "2012-04-22"
14
+
15
+ s.rubyforge_project = "rakismet"
16
+ s.add_development_dependency "rake"
17
+ s.add_development_dependency "rspec", "~> 2.11"
18
+
19
+ s.files = `git ls-files`.split("\n")
20
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
21
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
22
+ s.require_paths = ["lib"]
23
+ s.extra_rdoc_files = ["README.md"]
24
+ end
25
+
@@ -0,0 +1 @@
1
+ --color
@@ -0,0 +1,25 @@
1
+ require 'spec_helper'
2
+
3
+ PROC = proc { author.reverse }
4
+
5
+ class BlockAkismetModel
6
+ include Rakismet::Model
7
+ rakismet_attrs :author => PROC
8
+ end
9
+
10
+ describe BlockAkismetModel do
11
+
12
+ before do
13
+ @block = BlockAkismetModel.new
14
+ comment_attrs.each_pair { |k,v| @block.stub!(k).and_return(v) }
15
+ end
16
+
17
+ it "should accept a block" do
18
+ BlockAkismetModel.akismet_attrs[:comment_author].should eql(PROC)
19
+ end
20
+
21
+ it "should eval block with self = instance" do
22
+ data = @block.send(:akismet_data)
23
+ data[:comment_author].should eql(comment_attrs[:author].reverse)
24
+ end
25
+ end
@@ -0,0 +1,20 @@
1
+ require 'spec_helper'
2
+
3
+ MAPPED_PARAMS = { :comment_type => :type2, :author => :author2, :content => :content2,
4
+ :author_email => :author_email2, :author_url => :author_url2,
5
+ :user_role => :user_role2 }
6
+
7
+ class CustomAkismetModel
8
+ include Rakismet::Model
9
+ rakismet_attrs MAPPED_PARAMS.dup
10
+ end
11
+
12
+
13
+ describe CustomAkismetModel do
14
+ it "should override default mappings" do
15
+ [:comment_type, :author, :author_url, :author_email, :content, :user_role].each do |field|
16
+ fieldname = field.to_s =~ %r(^comment_) ? field : "comment_#{field}".intern
17
+ CustomAkismetModel.akismet_attrs[fieldname].should eql(MAPPED_PARAMS[field])
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,16 @@
1
+ require 'spec_helper'
2
+
3
+ EXTRA = { :extra => :extra, :another => lambda { } }
4
+
5
+ class ExtendedAkismetModel
6
+ include Rakismet::Model
7
+ rakismet_attrs EXTRA.dup
8
+ end
9
+
10
+ describe ExtendedAkismetModel do
11
+ it "should include additional attributes" do
12
+ [:extra, :another].each do |field|
13
+ ExtendedAkismetModel.akismet_attrs[field].should eql(EXTRA[field])
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,98 @@
1
+ require 'spec_helper'
2
+
3
+ describe AkismetModel do
4
+
5
+ before do
6
+ @model = AkismetModel.new
7
+ comment_attrs.each_pair { |k,v| @model.stub!(k).and_return(v) }
8
+ end
9
+
10
+ it "should have default mappings" do
11
+ [:comment_type, :author, :author_email, :author_url, :content, :user_role].each do |field|
12
+ fieldname = field.to_s =~ %r(^comment_) ? field : "comment_#{field}".intern
13
+ AkismetModel.akismet_attrs[fieldname].should eql(field)
14
+ end
15
+ end
16
+
17
+ it "should have request mappings" do
18
+ [:user_ip, :user_agent, :referrer].each do |field|
19
+ AkismetModel.akismet_attrs[field].should eql(field)
20
+ end
21
+ end
22
+
23
+ it "should populate comment type" do
24
+ @model.send(:akismet_data)[:comment_type].should == comment_attrs[:comment_type]
25
+ end
26
+
27
+ describe ".spam?" do
28
+
29
+ it "should use request variables from Rakismet.request if absent in model" do
30
+ [:user_ip, :user_agent, :referrer].each do |field|
31
+ @model.should_not respond_to(:field)
32
+ end
33
+ Rakismet.stub!(:request).and_return(request)
34
+ Rakismet.should_receive(:akismet_call).
35
+ with('comment-check', akismet_attrs.merge(:user_ip => '127.0.0.1',
36
+ :user_agent => 'RSpec',
37
+ :referrer => 'http://test.host/referrer'))
38
+ @model.spam?
39
+ end
40
+
41
+ it "should cache result of #spam?" do
42
+ Rakismet.should_receive(:akismet_call).once
43
+ @model.spam?
44
+ @model.spam?
45
+ end
46
+
47
+ it "should be true if comment is spam" do
48
+ Rakismet.stub!(:akismet_call).and_return('true')
49
+ @model.should be_spam
50
+ end
51
+
52
+ it "should be false if comment is not spam" do
53
+ Rakismet.stub!(:akismet_call).and_return('false')
54
+ @model.should_not be_spam
55
+ end
56
+
57
+ it "should set akismet_response" do
58
+ Rakismet.stub!(:akismet_call).and_return('response')
59
+ @model.spam?
60
+ @model.akismet_response.should eql('response')
61
+ end
62
+
63
+ it "should not throw an error if request vars are missing" do
64
+ Rakismet.stub!(:request).and_return(empty_request)
65
+ lambda { @model.spam? }.should_not raise_error(NoMethodError)
66
+ end
67
+ end
68
+
69
+
70
+ describe ".spam!" do
71
+ it "should call Base.akismet_call with submit-spam" do
72
+ Rakismet.should_receive(:akismet_call).with('submit-spam', akismet_attrs)
73
+ @model.spam!
74
+ end
75
+
76
+ it "should mutate #spam?" do
77
+ Rakismet.stub!(:akismet_call)
78
+ @model.instance_variable_set(:@_spam, false)
79
+ @model.spam!
80
+ @model.should be_spam
81
+ end
82
+ end
83
+
84
+ describe ".ham!" do
85
+ it "should call Base.akismet_call with submit-ham" do
86
+ Rakismet.should_receive(:akismet_call).with('submit-ham', akismet_attrs)
87
+ @model.ham!
88
+ end
89
+
90
+ it "should mutate #spam?" do
91
+ Rakismet.stub!(:akismet_call)
92
+ @model.instance_variable_set(:@_spam, true)
93
+ @model.ham!
94
+ @model.should_not be_spam
95
+ end
96
+ end
97
+
98
+ end
@@ -0,0 +1,23 @@
1
+ require 'spec_helper'
2
+
3
+ class RequestParams
4
+ include Rakismet::Model
5
+ attr_accessor :user_ip, :user_agent, :referrer
6
+ end
7
+
8
+ describe RequestParams do
9
+ before do
10
+ @model = RequestParams.new
11
+ attrs = comment_attrs(:user_ip => '192.168.0.1', :user_agent => 'Rakismet', :referrer => 'http://localhost/referrer')
12
+ attrs.each_pair { |k,v| @model.stub!(k).and_return(v) }
13
+ end
14
+
15
+ it "should use local values even if Rakismet.request is populated" do
16
+ Rakismet.stub(:request).and_return(request)
17
+ Rakismet.should_receive(:akismet_call).
18
+ with('comment-check', akismet_attrs.merge(:user_ip => '192.168.0.1',
19
+ :user_agent => 'Rakismet',
20
+ :referrer => 'http://localhost/referrer'))
21
+ @model.spam?
22
+ end
23
+ end
@@ -0,0 +1,14 @@
1
+ require 'spec_helper'
2
+
3
+ class Subclass < AkismetModel
4
+ end
5
+
6
+ describe Subclass do
7
+ it "should inherit parent's rakismet attrs" do
8
+ Subclass.akismet_attrs.should eql AkismetModel.akismet_attrs # key/value equality
9
+ end
10
+
11
+ it "should get a new copy of parent's rakismet attrs" do
12
+ Subclass.akismet_attrs.should_not equal AkismetModel.akismet_attrs # object equality
13
+ end
14
+ end
@@ -0,0 +1,27 @@
1
+ require 'spec_helper'
2
+
3
+ describe Rakismet::Middleware do
4
+
5
+ let(:env) { { 'REMOTE_ADDR' => '127.0.0.1', 'HTTP_USER_AGENT' => 'RSpec', 'HTTP_REFERER' => 'http://test.host/referrer' } }
6
+ let(:app) { double(:app, :call => nil) }
7
+ let(:request) { double(:request).as_null_object }
8
+
9
+ before do
10
+ @middleware = Rakismet::Middleware.new(app)
11
+ end
12
+
13
+ it "should set set Rakismet.request variables" do
14
+ Rakismet.stub(:request).and_return(request)
15
+ request.should_receive(:user_ip=).with('127.0.0.1')
16
+ request.should_receive(:user_agent=).with('RSpec')
17
+ request.should_receive(:referrer=).with('http://test.host/referrer')
18
+ @middleware.call(env)
19
+ end
20
+
21
+ it "should clear Rakismet.request after request is complete" do
22
+ @middleware.call(env)
23
+ Rakismet.request.user_ip.should be_nil
24
+ Rakismet.request.user_agent.should be_nil
25
+ Rakismet.request.referrer.should be_nil
26
+ end
27
+ end
@@ -0,0 +1,123 @@
1
+ require 'spec_helper'
2
+
3
+ describe Rakismet do
4
+
5
+ def mock_response(body)
6
+ double(:response, :body => body)
7
+ end
8
+ let(:http) { double(:http, :post => mock_response('akismet response')) }
9
+
10
+ before do
11
+ Rakismet.key = 'dummy-key'
12
+ Rakismet.url = 'test.localhost'
13
+ Rakismet.host = 'endpoint.localhost'
14
+ end
15
+
16
+ describe "proxy host" do
17
+ it "should have proxy host and port as nil by default" do
18
+ Rakismet.proxy_host.should be_nil
19
+ Rakismet.proxy_port.should be_nil
20
+ end
21
+ end
22
+
23
+ describe ".validate_config" do
24
+ it "should raise an error if key is not found" do
25
+ Rakismet.key = ''
26
+ lambda { Rakismet.send(:validate_config) }.should raise_error(Rakismet::Undefined)
27
+ end
28
+
29
+ it "should raise an error if url is not found" do
30
+ Rakismet.url = ''
31
+ lambda { Rakismet.send(:validate_config) }.should raise_error(Rakismet::Undefined)
32
+ end
33
+
34
+ it "should raise an error if host is not found" do
35
+ Rakismet.host = ''
36
+ lambda { Rakismet.send(:validate_config) }.should raise_error(Rakismet::Undefined)
37
+ end
38
+ end
39
+
40
+ describe ".validate_key" do
41
+ before (:each) do
42
+ @proxy = mock(Net::HTTP)
43
+ Net::HTTP.stub!(:Proxy).and_return(@proxy)
44
+ end
45
+
46
+ it "should use proxy host and port" do
47
+ Rakismet.proxy_host = 'proxy_host'
48
+ Rakismet.proxy_port = 'proxy_port'
49
+ @proxy.stub!(:start).and_return(mock_response('valid'))
50
+ Net::HTTP.should_receive(:Proxy).with('proxy_host', 'proxy_port').and_return(@proxy)
51
+ Rakismet.validate_key
52
+ end
53
+
54
+ it "should set @@valid_key = true if key is valid" do
55
+ @proxy.stub!(:start).and_return(mock_response('valid'))
56
+ Rakismet.validate_key
57
+ Rakismet.valid_key?.should be_true
58
+ end
59
+
60
+ it "should set @@valid_key = false if key is invalid" do
61
+ @proxy.stub!(:start).and_return(mock_response('invalid'))
62
+ Rakismet.validate_key
63
+ Rakismet.valid_key?.should be_false
64
+ end
65
+
66
+ it "should build url with host" do
67
+ host = "api.antispam.typepad.com"
68
+ Rakismet.host = host
69
+ @proxy.should_receive(:start).with(host).and_yield(http)
70
+ Rakismet.validate_key
71
+ end
72
+ end
73
+
74
+ describe ".akismet_call" do
75
+ before do
76
+ @proxy = mock(Net::HTTP)
77
+ Net::HTTP.stub!(:Proxy).and_return(@proxy)
78
+ @proxy.stub(:start).and_yield(http)
79
+ end
80
+
81
+ it "should use proxy host and port" do
82
+ Rakismet.proxy_host = 'proxy_host'
83
+ Rakismet.proxy_port = 'proxy_port'
84
+ @proxy.stub!(:start).and_return(mock_response('valid'))
85
+ Net::HTTP.should_receive(:Proxy).with('proxy_host', 'proxy_port').and_return(@proxy)
86
+ Rakismet.send(:akismet_call, 'bogus-function')
87
+ end
88
+
89
+ it "should build url with API key for the correct host" do
90
+ host = 'api.antispam.typepad.com'
91
+ Rakismet.host = host
92
+ @proxy.should_receive(:start).with("#{Rakismet.key}.#{host}")
93
+ Rakismet.send(:akismet_call, 'bogus-function')
94
+ end
95
+
96
+ it "should post data to named function" do
97
+ http.should_receive(:post).with('/1.1/bogus-function', %r(foo=#{CGI.escape 'escape//this'}), Rakismet.headers)
98
+ Rakismet.send(:akismet_call, 'bogus-function', { :foo => 'escape//this' })
99
+ end
100
+
101
+ it "should default to not being in test mode" do
102
+ http.should_receive(:post).with(anything, %r(is_test=0), anything)
103
+ Rakismet.send(:akismet_call, 'bogus-function')
104
+ end
105
+
106
+ it "should be in test mode when configured" do
107
+ Rakismet.test = true
108
+ http.should_receive(:post).with(anything, %r(is_test=1), anything)
109
+ Rakismet.send(:akismet_call, 'bogus-function')
110
+ end
111
+
112
+ it "should return response.body" do
113
+ Rakismet.send(:akismet_call, 'bogus-function').should eql('akismet response')
114
+ end
115
+
116
+ it "should build query string when params are nil" do
117
+ lambda {
118
+ Rakismet.send(:akismet_call, 'bogus-function', { :nil_param => nil })
119
+ }.should_not raise_error(NoMethodError)
120
+ end
121
+ end
122
+
123
+ end
@@ -0,0 +1,34 @@
1
+ require File.expand_path "lib/rakismet"
2
+ require 'ostruct'
3
+
4
+ RSpec.configure do |config|
5
+ config.mock_with :rspec
6
+ end
7
+
8
+ class AkismetModel
9
+ include Rakismet::Model
10
+ end
11
+
12
+ def comment_attrs(attrs={})
13
+ { :comment_type => 'test', :author => 'Rails test',
14
+ :author_email => 'test@test.host', :author_url => 'test.host',
15
+ :content => 'comment content', :blog => Rakismet.url }.merge(attrs)
16
+ end
17
+
18
+ def akismet_attrs(attrs={})
19
+ { :comment_type => 'test', :comment_author_email => 'test@test.host',
20
+ :comment_author => 'Rails test', :comment_author_url => 'test.host',
21
+ :comment_content => 'comment content' }.merge(attrs)
22
+ end
23
+
24
+ def request
25
+ OpenStruct.new(:user_ip => '127.0.0.1',
26
+ :user_agent => 'RSpec',
27
+ :referrer => 'http://test.host/referrer')
28
+ end
29
+
30
+ def empty_request
31
+ OpenStruct.new(:user_ip => nil,
32
+ :user_agent => nil,
33
+ :referrer => nil)
34
+ end
metadata ADDED
@@ -0,0 +1,140 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: beans-rakismet
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.2.2
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Josh French
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-04-22 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rake
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: rspec
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: '2.11'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: '2.11'
46
+ description: Rakismet is the easiest way to integrate Akismet or TypePad's AntiSpam
47
+ into your Rails app.
48
+ email: josh@vitamin-j.com
49
+ executables: []
50
+ extensions: []
51
+ extra_rdoc_files:
52
+ - README.md
53
+ files:
54
+ - !binary |-
55
+ LmdpdGlnbm9yZQ==
56
+ - !binary |-
57
+ Q0hBTkdFTE9H
58
+ - !binary |-
59
+ R2VtZmlsZQ==
60
+ - !binary |-
61
+ TUlULUxJQ0VOU0U=
62
+ - !binary |-
63
+ UkVBRE1FLm1k
64
+ - !binary |-
65
+ UmFrZWZpbGU=
66
+ - !binary |-
67
+ bGliL3Jha2lzbWV0LnJi
68
+ - !binary |-
69
+ bGliL3Jha2lzbWV0L21pZGRsZXdhcmUucmI=
70
+ - !binary |-
71
+ bGliL3Jha2lzbWV0L21vZGVsLnJi
72
+ - !binary |-
73
+ bGliL3Jha2lzbWV0L3JhaWx0aWUucmI=
74
+ - !binary |-
75
+ bGliL3Jha2lzbWV0L3ZlcnNpb24ucmI=
76
+ - !binary |-
77
+ cmFraXNtZXQuZ2Vtc3BlYw==
78
+ - !binary |-
79
+ c3BlYy8ucnNwZWM=
80
+ - !binary |-
81
+ c3BlYy9tb2RlbHMvYmxvY2tfcGFyYW1zX3NwZWMucmI=
82
+ - !binary |-
83
+ c3BlYy9tb2RlbHMvY3VzdG9tX3BhcmFtc19zcGVjLnJi
84
+ - !binary |-
85
+ c3BlYy9tb2RlbHMvZXh0ZW5kZWRfcGFyYW1zX3NwZWMucmI=
86
+ - !binary |-
87
+ c3BlYy9tb2RlbHMvcmFraXNtZXRfbW9kZWxfc3BlYy5yYg==
88
+ - !binary |-
89
+ c3BlYy9tb2RlbHMvcmVxdWVzdF9wYXJhbXNfc3BlYy5yYg==
90
+ - !binary |-
91
+ c3BlYy9tb2RlbHMvc3ViY2xhc3Nfc3BlYy5yYg==
92
+ - !binary |-
93
+ c3BlYy9yYWtpc21ldF9taWRkbGV3YXJlX3NwZWMucmI=
94
+ - !binary |-
95
+ c3BlYy9yYWtpc21ldF9zcGVjLnJi
96
+ - !binary |-
97
+ c3BlYy9zcGVjX2hlbHBlci5yYg==
98
+ homepage: http://github.com/joshfrench/rakismet
99
+ licenses: []
100
+ post_install_message:
101
+ rdoc_options: []
102
+ require_paths:
103
+ - lib
104
+ required_ruby_version: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ required_rubygems_version: !ruby/object:Gem::Requirement
111
+ none: false
112
+ requirements:
113
+ - - ! '>='
114
+ - !ruby/object:Gem::Version
115
+ version: '0'
116
+ requirements: []
117
+ rubyforge_project: rakismet
118
+ rubygems_version: 1.8.24
119
+ signing_key:
120
+ specification_version: 3
121
+ summary: Akismet and TypePad AntiSpam integration for Rails.
122
+ test_files:
123
+ - !binary |-
124
+ c3BlYy9tb2RlbHMvYmxvY2tfcGFyYW1zX3NwZWMucmI=
125
+ - !binary |-
126
+ c3BlYy9tb2RlbHMvY3VzdG9tX3BhcmFtc19zcGVjLnJi
127
+ - !binary |-
128
+ c3BlYy9tb2RlbHMvZXh0ZW5kZWRfcGFyYW1zX3NwZWMucmI=
129
+ - !binary |-
130
+ c3BlYy9tb2RlbHMvcmFraXNtZXRfbW9kZWxfc3BlYy5yYg==
131
+ - !binary |-
132
+ c3BlYy9tb2RlbHMvcmVxdWVzdF9wYXJhbXNfc3BlYy5yYg==
133
+ - !binary |-
134
+ c3BlYy9tb2RlbHMvc3ViY2xhc3Nfc3BlYy5yYg==
135
+ - !binary |-
136
+ c3BlYy9yYWtpc21ldF9taWRkbGV3YXJlX3NwZWMucmI=
137
+ - !binary |-
138
+ c3BlYy9yYWtpc21ldF9zcGVjLnJi
139
+ - !binary |-
140
+ c3BlYy9zcGVjX2hlbHBlci5yYg==