beans-rakismet 1.2.2

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.
@@ -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==