despamilator_rails 1.0.1 → 1.1
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/Gemfile +9 -7
- data/Gemfile.lock +53 -19
- data/History.txt +6 -0
- data/Manifest.txt +0 -1
- data/README.rdoc +2 -6
- data/Rakefile +9 -13
- data/despamilator-rails.gemspec +8 -11
- data/lib/despamilator_rails.rb +72 -84
- data/lib/despamilator_rails/active_record_validator.rb +15 -0
- data/lib/despamilator_rails/data_mapper_validator.rb +21 -0
- data/spec/active_record_spec.rb +18 -0
- data/spec/data_mapper_spec.rb +17 -0
- data/spec/fixtures/active_record_test_class.rb +8 -2
- data/spec/fixtures/data_mapper_test_class.rb +15 -0
- data/spec/spam_protected_model_shared.rb +97 -0
- data/spec/spec_helper.rb +4 -17
- metadata +15 -29
- data/spec/active_record_integration_spec.rb +0 -8
- data/spec/despamilator_rails_spec.rb +0 -120
- data/spec/test_db_migrations/create_test_model_table.rb +0 -10
data/.gitignore
ADDED
data/Gemfile
CHANGED
@@ -1,17 +1,19 @@
|
|
1
1
|
# A sample Gemfile
|
2
2
|
source "http://rubygems.org"
|
3
3
|
|
4
|
-
gem 'hoe', '>= 2.7.0'
|
5
|
-
gem 'newgem', '>= 1.5.3'
|
6
|
-
gem 'activesupport', '>= 2.3.10'
|
7
|
-
|
8
|
-
# while we're fetching from git, we need to execute everything with 'bundle exec'
|
9
|
-
#gem 'despamilator', :git => 'git://github.com/moowahaha/despamilator.git'
|
10
4
|
gem 'despamilator', '>= 1.0'
|
5
|
+
gem 'activemodel', '>= 3.0.0'
|
11
6
|
|
12
7
|
group :test do
|
8
|
+
gem 'activerecord', '>= 3.0.0'
|
9
|
+
gem 'dm-migrations', '>= 1.0.2'
|
10
|
+
gem 'dm-validations', '>= 1.0.2'
|
11
|
+
gem 'dm-sqlite-adapter', '>= 1.0.2'
|
13
12
|
gem 'rspec', '>= 2.4.0'
|
14
13
|
gem 'sqlite3', '>= 0.1.1'
|
15
|
-
gem 'activerecord', '>= 2.3.10'
|
16
14
|
gem 'one_hundred_percent_coverage'
|
17
15
|
end
|
16
|
+
|
17
|
+
group :development do
|
18
|
+
gem 'ruby-debug19'
|
19
|
+
end
|
data/Gemfile.lock
CHANGED
@@ -1,22 +1,46 @@
|
|
1
1
|
GEM
|
2
2
|
remote: http://rubygems.org/
|
3
3
|
specs:
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
4
|
+
activemodel (3.0.3)
|
5
|
+
activesupport (= 3.0.3)
|
6
|
+
builder (~> 2.1.2)
|
7
|
+
i18n (~> 0.4)
|
8
|
+
activerecord (3.0.3)
|
9
|
+
activemodel (= 3.0.3)
|
10
|
+
activesupport (= 3.0.3)
|
11
|
+
arel (~> 2.0.2)
|
12
|
+
tzinfo (~> 0.3.23)
|
13
|
+
activesupport (3.0.3)
|
14
|
+
addressable (2.2.2)
|
15
|
+
archive-tar-minitar (0.5.2)
|
16
|
+
arel (2.0.6)
|
17
|
+
builder (2.1.2)
|
18
|
+
columnize (0.3.2)
|
19
|
+
data_objects (0.10.2)
|
20
|
+
addressable (~> 2.1)
|
8
21
|
despamilator (1.0)
|
9
22
|
diff-lcs (1.1.2)
|
23
|
+
dm-core (1.0.2)
|
24
|
+
addressable (~> 2.2)
|
25
|
+
extlib (~> 0.9.15)
|
26
|
+
dm-do-adapter (1.0.2)
|
27
|
+
data_objects (~> 0.10.2)
|
28
|
+
dm-core (~> 1.0.2)
|
29
|
+
dm-migrations (1.0.2)
|
30
|
+
dm-core (~> 1.0.2)
|
31
|
+
dm-sqlite-adapter (1.0.2)
|
32
|
+
dm-do-adapter (~> 1.0.2)
|
33
|
+
do_sqlite3 (~> 0.10.2)
|
34
|
+
dm-validations (1.0.2)
|
35
|
+
dm-core (~> 1.0.2)
|
36
|
+
do_sqlite3 (0.10.2)
|
37
|
+
data_objects (= 0.10.2)
|
38
|
+
extlib (0.9.15)
|
10
39
|
ffi (1.0.4)
|
11
40
|
rake (>= 0.8.7)
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
RedCloth (>= 4.1.1)
|
16
|
-
activesupport (~> 2.3.4)
|
17
|
-
hoe (>= 2.4.0)
|
18
|
-
rubigen (>= 1.5.3)
|
19
|
-
syntax (>= 1.0.0)
|
41
|
+
i18n (0.5.0)
|
42
|
+
linecache19 (0.5.11)
|
43
|
+
ruby_core_source (>= 0.1.4)
|
20
44
|
one_hundred_percent_coverage (0.0.2)
|
21
45
|
simplecov (>= 0.3.7)
|
22
46
|
rake (0.8.7)
|
@@ -28,24 +52,34 @@ GEM
|
|
28
52
|
rspec-expectations (2.4.0)
|
29
53
|
diff-lcs (~> 1.1.2)
|
30
54
|
rspec-mocks (2.4.0)
|
31
|
-
|
32
|
-
|
55
|
+
ruby-debug-base19 (0.11.24)
|
56
|
+
columnize (>= 0.3.1)
|
57
|
+
linecache19 (>= 0.5.11)
|
58
|
+
ruby_core_source (>= 0.1.4)
|
59
|
+
ruby-debug19 (0.11.6)
|
60
|
+
columnize (>= 0.3.1)
|
61
|
+
linecache19 (>= 0.5.11)
|
62
|
+
ruby-debug-base19 (>= 0.11.19)
|
63
|
+
ruby_core_source (0.1.4)
|
64
|
+
archive-tar-minitar (>= 0.5.2)
|
33
65
|
simplecov (0.3.7)
|
34
66
|
simplecov-html (>= 0.3.7)
|
35
67
|
simplecov-html (0.3.9)
|
36
68
|
sqlite3 (0.1.1)
|
37
69
|
ffi (>= 0.6.3)
|
38
|
-
|
70
|
+
tzinfo (0.3.23)
|
39
71
|
|
40
72
|
PLATFORMS
|
41
73
|
ruby
|
42
74
|
|
43
75
|
DEPENDENCIES
|
44
|
-
|
45
|
-
|
76
|
+
activemodel (>= 3.0.0)
|
77
|
+
activerecord (>= 3.0.0)
|
46
78
|
despamilator (>= 1.0)
|
47
|
-
|
48
|
-
|
79
|
+
dm-migrations (>= 1.0.2)
|
80
|
+
dm-sqlite-adapter (>= 1.0.2)
|
81
|
+
dm-validations (>= 1.0.2)
|
49
82
|
one_hundred_percent_coverage
|
50
83
|
rspec (>= 2.4.0)
|
84
|
+
ruby-debug19
|
51
85
|
sqlite3 (>= 0.1.1)
|
data/History.txt
CHANGED
data/Manifest.txt
CHANGED
data/README.rdoc
CHANGED
@@ -5,18 +5,14 @@
|
|
5
5
|
== DESCRIPTION:
|
6
6
|
|
7
7
|
Spam detection plugin for Rails & ActiveRecord. Uses all the standard Rails conventions and
|
8
|
-
my Despamilator gem.
|
8
|
+
my Despamilator gem. This gem only supports Rails 3. See despamilator_rails2 for Rails 2 support.
|
9
9
|
|
10
10
|
== FEATURES/PROBLEMS:
|
11
11
|
|
12
12
|
* To fix the iconv error when developing with Ruby 1.9.2 and RVM,
|
13
13
|
see: http://blog.footle.org/2010/07/29/installing-ruby-1-9-2-via-rvm-on-os-x/ .
|
14
14
|
|
15
|
-
*
|
16
|
-
newer versions.
|
17
|
-
|
18
|
-
* DataMapper not yet supported. That's on the list!
|
19
|
-
|
15
|
+
* Does not support Rails 2. See despamilator_rails2 for support.
|
20
16
|
|
21
17
|
== SYNOPSIS:
|
22
18
|
|
data/Rakefile
CHANGED
@@ -1,23 +1,14 @@
|
|
1
1
|
require 'rubygems'
|
2
|
-
gem 'hoe', '>= 2.1.0'
|
3
|
-
require 'hoe'
|
4
2
|
require 'fileutils'
|
5
3
|
require './lib/despamilator_rails'
|
6
4
|
|
7
|
-
|
5
|
+
task :default => [:test]
|
8
6
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
self.extra_deps = [['despamilator','>= 1.0'], ['activerecord', '>= 2.3.2']]
|
7
|
+
desc "Run specs"
|
8
|
+
task :test do
|
9
|
+
sh "rspec spec"
|
13
10
|
end
|
14
11
|
|
15
|
-
require 'newgem/tasks'
|
16
|
-
Dir['tasks/**/*.rake'].each { |t| load t }
|
17
|
-
|
18
|
-
task :default => [:spec]
|
19
|
-
task :test => [:spec]
|
20
|
-
|
21
12
|
desc "Generate appropriate rdoc"
|
22
13
|
task :rdoc do
|
23
14
|
sh "rdoc README.rdoc lib/despamilator_rails.rb"
|
@@ -28,3 +19,8 @@ task :cultivate do
|
|
28
19
|
sh "touch Manifest.txt; rake check_manifest |grep -v \"(in \" | patch"
|
29
20
|
sh "rake debug_gem | grep -v \"(in \" > `basename \\`pwd\\``.gemspec"
|
30
21
|
end
|
22
|
+
|
23
|
+
desc "Build the gem"
|
24
|
+
task :package do
|
25
|
+
sh "gem build despamilator-rails.gemspec"
|
26
|
+
end
|
data/despamilator-rails.gemspec
CHANGED
@@ -2,21 +2,21 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = %q{despamilator_rails}
|
5
|
-
s.version = "1.
|
5
|
+
s.version = "1.1"
|
6
6
|
|
7
7
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
8
|
s.authors = ["Stephen Hardisty"]
|
9
9
|
s.date = %q{2011-01-09}
|
10
|
-
s.description = %q{
|
10
|
+
s.description = %q{Adds a Rails-esque validation method for use in Rails 3 with ActiveRecord or DataMapper}
|
11
11
|
s.email = ["moowahaha@hotmail.com"]
|
12
12
|
s.extra_rdoc_files = ["History.txt", "Manifest.txt"]
|
13
|
-
s.files =
|
13
|
+
s.files = `git ls-files`.split("\n")
|
14
14
|
s.homepage = %q{https://github.com/moowahaha/despamilator-rails}
|
15
|
-
s.rdoc_options = ["
|
15
|
+
s.rdoc_options = ["lib/despamilator_rails.rb", "README.rdoc"]
|
16
16
|
s.require_paths = ["lib"]
|
17
17
|
s.rubyforge_project = %q{despamilator_rails}
|
18
18
|
s.rubygems_version = %q{1.3.7}
|
19
|
-
s.summary = %q{
|
19
|
+
s.summary = %q{Anti-spam validation hooks for Rails.}
|
20
20
|
|
21
21
|
if s.respond_to? :specification_version then
|
22
22
|
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
@@ -24,16 +24,13 @@ Gem::Specification.new do |s|
|
|
24
24
|
|
25
25
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
26
26
|
s.add_runtime_dependency(%q<despamilator>, [">= 1.0"])
|
27
|
-
s.add_runtime_dependency(%q<
|
28
|
-
s.add_development_dependency(%q<hoe>, [">= 2.8.0"])
|
27
|
+
s.add_runtime_dependency(%q<activemodel>, [">= 3.0.0"])
|
29
28
|
else
|
30
29
|
s.add_dependency(%q<despamilator>, [">= 1.0"])
|
31
|
-
s.add_dependency(%q<
|
32
|
-
s.add_dependency(%q<hoe>, [">= 2.8.0"])
|
30
|
+
s.add_dependency(%q<activemodel>, [">= 3.0.0"])
|
33
31
|
end
|
34
32
|
else
|
35
33
|
s.add_dependency(%q<despamilator>, [">= 1.0"])
|
36
|
-
s.add_dependency(%q<
|
37
|
-
s.add_dependency(%q<hoe>, [">= 2.8.0"])
|
34
|
+
s.add_dependency(%q<activemodel>, [">= 3.0.0"])
|
38
35
|
end
|
39
36
|
end
|
data/lib/despamilator_rails.rb
CHANGED
@@ -1,102 +1,90 @@
|
|
1
1
|
require 'despamilator'
|
2
|
-
require '
|
2
|
+
require 'active_model'
|
3
3
|
|
4
|
-
|
5
|
-
|
4
|
+
Dir.glob(File.join(File.dirname(__FILE__), 'despamilator_rails', '*.rb')) do |file|
|
5
|
+
require file
|
6
6
|
end
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
# require 'despamilator_rails'
|
15
|
-
#
|
16
|
-
# In your model (basic example):
|
17
|
-
#
|
18
|
-
# class YourModel < ActiveRecord::Base
|
19
|
-
# validate_with_despamilator :attributes => [:some_field]
|
20
|
-
# end
|
21
|
-
#
|
22
|
-
# When "some_field" is assigned a spammy value, it will add to the errors. For example...
|
23
|
-
#
|
24
|
-
# YourModel.new(:some_field => spammy_value).save! #=> ActiveRecord::RecordInvalid exception!
|
25
|
-
#
|
26
|
-
# Or...
|
27
|
-
#
|
28
|
-
# your_instance = YourModel.new(:some_field => spammy_value)
|
29
|
-
# your_instance.save
|
30
|
-
# your_instance.errors.full_messages.should #=> ["Some field looks like spam"]
|
31
|
-
#
|
32
|
-
# If you want to configure the threshold (which defaults to 1) or add your own callback, you can do the following:
|
33
|
-
#
|
34
|
-
# class YourModel < ActiveRecord::Base
|
35
|
-
# validate_with_despamilator :attributes => [:some_field], :threshold => 1 do |field, value, despamilator|
|
36
|
-
# raise "spam! field: #{field}, value: #{value}, score: #{despamailtor.score}"
|
37
|
-
# end
|
38
|
-
# end
|
39
|
-
#
|
40
|
-
# This example will...
|
41
|
-
#
|
42
|
-
# your_instance = YourModel.new(:some_field => "spammy string")
|
43
|
-
# your_instance.save! #=> Exception "spam! field: some_field, value: spammy string, score: 123"
|
44
|
-
#
|
45
|
-
# The callback will receive the field name, the value and the instance of the Despamilator class.
|
46
|
-
|
47
|
-
def self.validate_with_despamilator settings, &block
|
48
|
-
assign_despamilator_attributes settings
|
49
|
-
assign_despamilator_threshold settings
|
50
|
-
assign_despamilator_callback block
|
51
|
-
|
52
|
-
add_despamilator_validation settings
|
53
|
-
end
|
54
|
-
|
55
|
-
private
|
56
|
-
|
57
|
-
class << self
|
58
|
-
|
59
|
-
def add_despamilator_validation settings
|
60
|
-
|
61
|
-
send(validation_method(:save), settings) do |record|
|
62
|
-
|
63
|
-
record.despamilator_checked_attributes.each do |attribute|
|
64
|
-
text = record.send(attribute)
|
65
|
-
dspam = Despamilator.new(text)
|
8
|
+
class DespamilatorActiveRecordValidator < ActiveModel::EachValidator
|
9
|
+
def validate_each(record, attribute, text)
|
10
|
+
dspam = Despamilator.new(text)
|
11
|
+
record.despamilator_callback(attribute, text, dspam) if dspam.score >= record.despamilator_threshold
|
12
|
+
end
|
13
|
+
end
|
66
14
|
|
67
|
-
|
68
|
-
end
|
15
|
+
module DespamilatorRails
|
69
16
|
|
70
|
-
|
17
|
+
# In your model (basic example):
|
18
|
+
#
|
19
|
+
# class YourModel < ActiveRecord::Base
|
20
|
+
# validate_with_despamilator :attributes => [:some_field]
|
21
|
+
# end
|
22
|
+
#
|
23
|
+
# When "some_field" is assigned a spammy value, it will add to the errors. For example...
|
24
|
+
#
|
25
|
+
# YourModel.new(:some_field => spammy_value).save! #=> ActiveRecord::RecordInvalid exception!
|
26
|
+
#
|
27
|
+
# Or...
|
28
|
+
#
|
29
|
+
# your_instance = YourModel.new(:some_field => spammy_value)
|
30
|
+
# your_instance.save
|
31
|
+
# your_instance.errors.full_messages.should #=> ["Some field looks like spam"]
|
32
|
+
#
|
33
|
+
# Note that, by default, DataMapper behaves slightly differently in that it will not raise exceptions
|
34
|
+
# unless you code a callback to deal with that. Instead it will return "false" on an unsuccessful save.
|
35
|
+
#
|
36
|
+
# If you want to configure the threshold (which defaults to 1) or add your own callback, you can do the following:
|
37
|
+
#
|
38
|
+
# class YourModel < ActiveRecord::Base
|
39
|
+
# validate_with_despamilator :attributes => [:some_field], :threshold => 1 do |field, value, despamilator|
|
40
|
+
# raise "spam! field: #{field}, value: #{value}, score: #{despamailtor.score}"
|
41
|
+
# end
|
42
|
+
# end
|
43
|
+
#
|
44
|
+
# This example will...
|
45
|
+
#
|
46
|
+
# your_instance = YourModel.new(:some_field => "spammy string")
|
47
|
+
# your_instance.save! #=> Exception "spam! field: some_field, value: spammy string, score: 123"
|
48
|
+
#
|
49
|
+
# The callback will receive the field name, the value and the instance of the Despamilator class.
|
50
|
+
|
51
|
+
def validate_with_despamilator settings, & block
|
52
|
+
extend(respond_to?(:validates_with_block) ? DespamilatorRails::DataMapperValidator : DespamilatorRails::ActiveRecordValidator)
|
53
|
+
|
54
|
+
assign_despamilator_threshold settings
|
55
|
+
assign_despamilator_callback block
|
56
|
+
|
57
|
+
add_despamilator_validation settings
|
58
|
+
end
|
71
59
|
|
72
|
-
|
60
|
+
private
|
73
61
|
|
74
|
-
|
75
|
-
clean_attributes = settings[:attributes].reject do |attribute|
|
76
|
-
attribute.blank?
|
77
|
-
end
|
62
|
+
def add_despamilator_validation settings
|
78
63
|
|
79
|
-
|
64
|
+
clean_despamilator_attributes(settings).each do |attribute|
|
65
|
+
setup_despamilation_detection_for attribute
|
66
|
+
end
|
80
67
|
|
81
|
-
|
82
|
-
end
|
68
|
+
end
|
83
69
|
|
84
|
-
|
85
|
-
|
86
|
-
|
70
|
+
def clean_despamilator_attributes(settings)
|
71
|
+
clean_attributes = settings[:attributes].reject do |attribute|
|
72
|
+
attribute.blank?
|
73
|
+
end
|
87
74
|
|
88
|
-
|
89
|
-
define_method(:despamilator_callback, block || default_despamilator_detection_response)
|
90
|
-
end
|
75
|
+
raise('At least one attribute must be defined') if clean_attributes.empty?
|
91
76
|
|
92
|
-
|
93
|
-
|
94
|
-
errors.add(attribute, "looks like spam")
|
95
|
-
}
|
96
|
-
end
|
77
|
+
clean_attributes
|
78
|
+
end
|
97
79
|
|
98
|
-
|
80
|
+
def assign_despamilator_threshold(settings)
|
81
|
+
define_method(:despamilator_threshold, lambda { settings[:threshold] || 1 })
|
82
|
+
end
|
99
83
|
|
84
|
+
def assign_despamilator_callback(block)
|
85
|
+
define_method(:despamilator_callback, block || default_despamilator_detection_response)
|
100
86
|
end
|
101
87
|
|
102
88
|
end
|
89
|
+
|
90
|
+
Module.send(:include, DespamilatorRails)
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module DespamilatorRails
|
2
|
+
module ActiveRecordValidator
|
3
|
+
|
4
|
+
def setup_despamilation_detection_for attribute
|
5
|
+
validates attribute, :despamilator_active_record => true
|
6
|
+
end
|
7
|
+
|
8
|
+
def default_despamilator_detection_response
|
9
|
+
lambda { |attribute, value, dspam|
|
10
|
+
errors.add(attribute, "looks like spam")
|
11
|
+
}
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module DespamilatorRails
|
2
|
+
module DataMapperValidator
|
3
|
+
|
4
|
+
def setup_despamilation_detection_for attribute
|
5
|
+
|
6
|
+
validates_with_block attribute do
|
7
|
+
text = send(attribute)
|
8
|
+
dspam = Despamilator.new(text)
|
9
|
+
despamilator_callback(attribute, text, dspam) if dspam.score >= despamilator_threshold
|
10
|
+
end
|
11
|
+
|
12
|
+
end
|
13
|
+
|
14
|
+
def default_despamilator_detection_response
|
15
|
+
lambda { |attribute, value, dspam|
|
16
|
+
[false, "looks like spam"]
|
17
|
+
}
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
describe SomeActiveRecordModel do
|
2
|
+
|
3
|
+
it_should_behave_like "a spam protected model"
|
4
|
+
|
5
|
+
it "should notify of spam detection in a railsy way" do
|
6
|
+
|
7
|
+
class SomeActiveRecordModelWithSpam < SomeActiveRecordModel
|
8
|
+
validate_with_despamilator :attributes => [:some_field]
|
9
|
+
end
|
10
|
+
|
11
|
+
some_model = SomeActiveRecordModelWithSpam.new
|
12
|
+
some_model.some_field = Despamilator.gtubs_test_string
|
13
|
+
|
14
|
+
-> {some_model.save!}.should raise_error(ActiveRecord::RecordInvalid)
|
15
|
+
some_model.errors.full_messages.should == ["Some field looks like spam"]
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
describe SomeDataMapperModel do
|
2
|
+
|
3
|
+
it_should_behave_like "a spam protected model"
|
4
|
+
|
5
|
+
it "should notify of spam detection in a railsy way" do
|
6
|
+
|
7
|
+
class SomeDataMapperModelWithSpam < SomeDataMapperModel
|
8
|
+
validate_with_despamilator :attributes => [:some_field]
|
9
|
+
end
|
10
|
+
|
11
|
+
some_model = SomeDataMapperModelWithSpam.new
|
12
|
+
some_model.some_field = Despamilator.gtubs_test_string
|
13
|
+
|
14
|
+
some_model.save.should be_false
|
15
|
+
some_model.errors.first.should == ["looks like spam"]
|
16
|
+
end
|
17
|
+
end
|
@@ -1,5 +1,11 @@
|
|
1
|
-
|
1
|
+
require 'active_record'
|
2
2
|
|
3
|
-
|
3
|
+
class SomeActiveRecordModel < ActiveRecord::Base
|
4
|
+
|
5
|
+
establish_connection :adapter => 'sqlite3', :database => 'test.sqlite3'
|
6
|
+
|
7
|
+
connection.create_table table_name, :force => true do |t|
|
8
|
+
t.text :some_field
|
9
|
+
end
|
4
10
|
|
5
11
|
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'dm-migrations'
|
2
|
+
require 'dm-validations'
|
3
|
+
|
4
|
+
class SomeDataMapperModel
|
5
|
+
|
6
|
+
DataMapper.setup(:default, 'sqlite::memory:')
|
7
|
+
|
8
|
+
include DataMapper::Resource
|
9
|
+
|
10
|
+
property :id, Serial
|
11
|
+
property :some_field, Text
|
12
|
+
|
13
|
+
end
|
14
|
+
|
15
|
+
DataMapper.auto_migrate!
|
@@ -0,0 +1,97 @@
|
|
1
|
+
shared_examples_for "a spam protected model" do
|
2
|
+
|
3
|
+
before do
|
4
|
+
Object.send(:remove_const, :TestClass) if Module.constants.include?(:TestClass)
|
5
|
+
end
|
6
|
+
|
7
|
+
it "should be just fine when no spam is passed" do
|
8
|
+
some_instance = described_class.new
|
9
|
+
some_instance.some_field = 'hello'
|
10
|
+
|
11
|
+
some_instance.save.should be_true
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should check for spam on save" do
|
15
|
+
|
16
|
+
class TestClass < described_class
|
17
|
+
validate_with_despamilator :attributes => [:some_field]
|
18
|
+
end
|
19
|
+
|
20
|
+
some_instance = TestClass.new
|
21
|
+
some_instance.some_field = Despamilator.gtubs_test_string
|
22
|
+
|
23
|
+
some_instance.save.should be_false
|
24
|
+
end
|
25
|
+
|
26
|
+
describe "threshold" do
|
27
|
+
|
28
|
+
it "should default to 1" do
|
29
|
+
|
30
|
+
class TestClass < described_class
|
31
|
+
validate_with_despamilator :attributes => [:some_field]
|
32
|
+
end
|
33
|
+
|
34
|
+
some_model = TestClass.new
|
35
|
+
some_model.despamilator_threshold.should == 1
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should be settable" do
|
39
|
+
|
40
|
+
class TestClass < described_class
|
41
|
+
validate_with_despamilator :attributes => [:some_field], :threshold => 9
|
42
|
+
end
|
43
|
+
|
44
|
+
some_model = TestClass.new
|
45
|
+
some_model.despamilator_threshold.should == 9
|
46
|
+
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
describe "attributes" do
|
52
|
+
|
53
|
+
it "should cause an exception when an empty array is passed" do
|
54
|
+
|
55
|
+
->{
|
56
|
+
class TestClass < described_class
|
57
|
+
validate_with_despamilator :attributes => []
|
58
|
+
end
|
59
|
+
}.should raise_error('At least one attribute must be defined')
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
it "should cause an exception when an empty string is passed" do
|
64
|
+
|
65
|
+
-> {
|
66
|
+
class TestClass < described_class
|
67
|
+
validate_with_despamilator :attributes => ['']
|
68
|
+
end
|
69
|
+
}.should raise_error('At least one attribute must be defined')
|
70
|
+
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
|
75
|
+
it "should allow a block to be specified" do
|
76
|
+
|
77
|
+
class TestClass < described_class
|
78
|
+
def do_something field, value, despamilator
|
79
|
+
end
|
80
|
+
|
81
|
+
validate_with_despamilator :attributes => [:some_field] do |field, value, despamilator|
|
82
|
+
do_something(field, value, despamilator)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
fake_despamilator = mock('despamilator')
|
87
|
+
Despamilator.should_receive(:new).and_return(fake_despamilator)
|
88
|
+
fake_despamilator.should_receive(:score).and_return(10000)
|
89
|
+
|
90
|
+
some_model = TestClass.new
|
91
|
+
some_model.should_receive(:do_something).with(:some_field, 'blah', fake_despamilator)
|
92
|
+
some_model.some_field = 'blah'
|
93
|
+
some_model.save
|
94
|
+
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,22 +1,9 @@
|
|
1
1
|
require 'one_hundred_percent_coverage'
|
2
|
+
|
2
3
|
require File.join(File.dirname(__FILE__), '..', 'lib', 'despamilator_rails')
|
3
|
-
require 'active_record'
|
4
4
|
|
5
|
-
|
6
|
-
require file
|
5
|
+
%w{active_record_test_class data_mapper_test_class}.each do |file|
|
6
|
+
require File.join(File.dirname(__FILE__), 'fixtures', file)
|
7
7
|
end
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
File.unlink(db_file) if File.exists?(db_file)
|
12
|
-
|
13
|
-
ActiveRecord::Base.establish_connection(
|
14
|
-
:adapter => 'sqlite3',
|
15
|
-
:database => db_file
|
16
|
-
)
|
17
|
-
|
18
|
-
CreateSomeModel.migrate(:up)
|
19
|
-
|
20
|
-
Dir.glob(File.join(File.dirname(__FILE__), 'fixtures', '*.rb')).each do |file|
|
21
|
-
require file
|
22
|
-
end
|
9
|
+
require File.join(File.dirname(__FILE__), 'spam_protected_model_shared')
|
metadata
CHANGED
@@ -4,9 +4,8 @@ version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 1
|
7
|
-
- 0
|
8
7
|
- 1
|
9
|
-
version: 1.
|
8
|
+
version: "1.1"
|
10
9
|
platform: ruby
|
11
10
|
authors:
|
12
11
|
- Stephen Hardisty
|
@@ -32,7 +31,7 @@ dependencies:
|
|
32
31
|
type: :runtime
|
33
32
|
version_requirements: *id001
|
34
33
|
- !ruby/object:Gem::Dependency
|
35
|
-
name:
|
34
|
+
name: activemodel
|
36
35
|
prerelease: false
|
37
36
|
requirement: &id002 !ruby/object:Gem::Requirement
|
38
37
|
none: false
|
@@ -40,30 +39,13 @@ dependencies:
|
|
40
39
|
- - ">="
|
41
40
|
- !ruby/object:Gem::Version
|
42
41
|
segments:
|
43
|
-
- 2
|
44
42
|
- 3
|
45
|
-
-
|
46
|
-
|
43
|
+
- 0
|
44
|
+
- 0
|
45
|
+
version: 3.0.0
|
47
46
|
type: :runtime
|
48
47
|
version_requirements: *id002
|
49
|
-
-
|
50
|
-
name: hoe
|
51
|
-
prerelease: false
|
52
|
-
requirement: &id003 !ruby/object:Gem::Requirement
|
53
|
-
none: false
|
54
|
-
requirements:
|
55
|
-
- - ">="
|
56
|
-
- !ruby/object:Gem::Version
|
57
|
-
segments:
|
58
|
-
- 2
|
59
|
-
- 8
|
60
|
-
- 0
|
61
|
-
version: 2.8.0
|
62
|
-
type: :development
|
63
|
-
version_requirements: *id003
|
64
|
-
description: |-
|
65
|
-
Spam detection plugin for Rails & ActiveRecord. Uses all the standard Rails conventions and
|
66
|
-
my Despamilator gem.
|
48
|
+
description: Adds a Rails-esque validation method for use in Rails 3 with ActiveRecord or DataMapper
|
67
49
|
email:
|
68
50
|
- moowahaha@hotmail.com
|
69
51
|
executables: []
|
@@ -74,6 +56,7 @@ extra_rdoc_files:
|
|
74
56
|
- History.txt
|
75
57
|
- Manifest.txt
|
76
58
|
files:
|
59
|
+
- .gitignore
|
77
60
|
- .rspec
|
78
61
|
- .rvmrc
|
79
62
|
- Gemfile
|
@@ -84,18 +67,21 @@ files:
|
|
84
67
|
- Rakefile
|
85
68
|
- despamilator-rails.gemspec
|
86
69
|
- lib/despamilator_rails.rb
|
87
|
-
-
|
88
|
-
-
|
70
|
+
- lib/despamilator_rails/active_record_validator.rb
|
71
|
+
- lib/despamilator_rails/data_mapper_validator.rb
|
72
|
+
- spec/active_record_spec.rb
|
73
|
+
- spec/data_mapper_spec.rb
|
89
74
|
- spec/fixtures/active_record_test_class.rb
|
75
|
+
- spec/fixtures/data_mapper_test_class.rb
|
76
|
+
- spec/spam_protected_model_shared.rb
|
90
77
|
- spec/spec_helper.rb
|
91
|
-
- spec/test_db_migrations/create_test_model_table.rb
|
92
78
|
has_rdoc: true
|
93
79
|
homepage: https://github.com/moowahaha/despamilator-rails
|
94
80
|
licenses: []
|
95
81
|
|
96
82
|
post_install_message:
|
97
83
|
rdoc_options:
|
98
|
-
-
|
84
|
+
- lib/despamilator_rails.rb
|
99
85
|
- README.rdoc
|
100
86
|
require_paths:
|
101
87
|
- lib
|
@@ -121,6 +107,6 @@ rubyforge_project: despamilator_rails
|
|
121
107
|
rubygems_version: 1.3.7
|
122
108
|
signing_key:
|
123
109
|
specification_version: 3
|
124
|
-
summary:
|
110
|
+
summary: Anti-spam validation hooks for Rails.
|
125
111
|
test_files: []
|
126
112
|
|
@@ -1,120 +0,0 @@
|
|
1
|
-
describe "despamilator_rails" do
|
2
|
-
|
3
|
-
it "should notify of spam detection in a railsy way" do
|
4
|
-
|
5
|
-
class SomeModelWithSpam < ActiveRecord::Base
|
6
|
-
set_table_name 'some_models'
|
7
|
-
validate_with_despamilator :attributes => [:some_field]
|
8
|
-
end
|
9
|
-
|
10
|
-
some_model = SomeModelWithSpam.new
|
11
|
-
some_model.some_field = Despamilator.gtubs_test_string
|
12
|
-
|
13
|
-
-> {some_model.save!}.should raise_error(ActiveRecord::RecordInvalid)
|
14
|
-
some_model.errors.full_messages.should == ["Some field looks like spam"]
|
15
|
-
end
|
16
|
-
|
17
|
-
describe "threshold" do
|
18
|
-
|
19
|
-
it "should default to 1" do
|
20
|
-
|
21
|
-
class SomeModelWithDefaultThreshold < ActiveRecord::Base
|
22
|
-
set_table_name 'some_models'
|
23
|
-
validate_with_despamilator :attributes => [:some_field]
|
24
|
-
end
|
25
|
-
|
26
|
-
some_model = SomeModelWithDefaultThreshold.new
|
27
|
-
some_model.despamilator_threshold.should == 1
|
28
|
-
end
|
29
|
-
|
30
|
-
it "should be settable" do
|
31
|
-
|
32
|
-
class SomeModelWithDefinedThreshold < ActiveRecord::Base
|
33
|
-
set_table_name 'some_models'
|
34
|
-
validate_with_despamilator :attributes => [:some_field], :threshold => 9
|
35
|
-
end
|
36
|
-
|
37
|
-
some_model = SomeModelWithDefinedThreshold.new
|
38
|
-
some_model.despamilator_threshold.should == 9
|
39
|
-
|
40
|
-
end
|
41
|
-
|
42
|
-
end
|
43
|
-
|
44
|
-
describe "attributes" do
|
45
|
-
|
46
|
-
it "should cause an exception when an empty array is passed" do
|
47
|
-
|
48
|
-
->{
|
49
|
-
class SomeModelWithMissingAttributes < ActiveRecord::Base
|
50
|
-
validate_with_despamilator :attributes => []
|
51
|
-
end
|
52
|
-
}.should raise_error('At least one attribute must be defined')
|
53
|
-
|
54
|
-
end
|
55
|
-
|
56
|
-
it "should cause an exception when an empty string is passed" do
|
57
|
-
|
58
|
-
-> {
|
59
|
-
class SomeModelWithEmptyAttributes < ActiveRecord::Base
|
60
|
-
validate_with_despamilator :attributes => ['']
|
61
|
-
end
|
62
|
-
}.should raise_error('At least one attribute must be defined')
|
63
|
-
|
64
|
-
end
|
65
|
-
|
66
|
-
end
|
67
|
-
|
68
|
-
it "should allow a block to be specified" do
|
69
|
-
|
70
|
-
class SomeModelWithABlock < ActiveRecord::Base
|
71
|
-
set_table_name 'some_models'
|
72
|
-
|
73
|
-
def do_something field, value, despamilator
|
74
|
-
end
|
75
|
-
|
76
|
-
validate_with_despamilator :attributes => [:some_field] do |field, value, despamilator|
|
77
|
-
do_something(field, value, despamilator)
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
|
-
fake_despamilator = mock('despamilator')
|
82
|
-
Despamilator.should_receive(:new).and_return(fake_despamilator)
|
83
|
-
fake_despamilator.should_receive(:score).and_return(10000)
|
84
|
-
|
85
|
-
some_model = SomeModelWithABlock.new
|
86
|
-
some_model.should_receive(:do_something).with(:some_field, 'blah', fake_despamilator)
|
87
|
-
some_model.some_field = 'blah'
|
88
|
-
some_model.save
|
89
|
-
|
90
|
-
end
|
91
|
-
|
92
|
-
it "should work nicely with other validate methods" do
|
93
|
-
class SomeModelWithAnotherValidate < ActiveRecord::Base
|
94
|
-
set_table_name 'some_models'
|
95
|
-
|
96
|
-
validate_with_despamilator :attributes => [:some_field] do |field, value, despamilator|
|
97
|
-
do_something
|
98
|
-
end
|
99
|
-
|
100
|
-
def do_something
|
101
|
-
end
|
102
|
-
|
103
|
-
def do_something_else
|
104
|
-
end
|
105
|
-
|
106
|
-
def validate
|
107
|
-
do_something_else
|
108
|
-
end
|
109
|
-
|
110
|
-
end
|
111
|
-
|
112
|
-
some_model = SomeModelWithAnotherValidate.new
|
113
|
-
some_model.should_receive(:do_something)
|
114
|
-
some_model.should_receive(:do_something_else)
|
115
|
-
some_model.some_field = Despamilator.gtubs_test_string
|
116
|
-
some_model.save
|
117
|
-
|
118
|
-
end
|
119
|
-
|
120
|
-
end
|