obscenity2 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,18 @@
1
+ if defined?(ActiveModel)
2
+ module ActiveModel
3
+ module Validations
4
+ class ObscenityValidator < ActiveModel::EachValidator
5
+
6
+ def validate_each(record, attribute, value)
7
+ if options.present? && options.has_key?(:sanitize)
8
+ object = record.respond_to?(:[]) ? record[attribute] : record.send(attribute)
9
+ object = Obscenity.replacement(options[:replacement]).sanitize(object)
10
+ else
11
+ record.errors.add(attribute, options[:message] || 'cannot be profane') if Obscenity.profane?(value)
12
+ end
13
+ end
14
+
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,71 @@
1
+ module Obscenity
2
+ class Base
3
+ class << self
4
+
5
+ def blacklist
6
+ @blacklist ||= set_list_content(Obscenity.config.blacklist)
7
+ end
8
+
9
+ def blacklist=(value)
10
+ @blacklist = value == :default ? set_list_content(Obscenity::Config.new.blacklist) : value
11
+ end
12
+
13
+ def whitelist
14
+ @whitelist ||= set_list_content(Obscenity.config.whitelist)
15
+ end
16
+
17
+ def whitelist=(value)
18
+ @whitelist = value == :default ? set_list_content(Obscenity::Config.new.whitelist) : value
19
+ end
20
+
21
+ def profane?(text)
22
+ blacklist.any? do |foul|
23
+ text =~ /\b#{foul}\b/i && !whitelist.include?(foul)
24
+ end
25
+ end
26
+
27
+ def sanitize(text)
28
+ blacklist.each do |foul|
29
+ text.gsub!(/\b#{foul}\b/i, replace(foul)) unless whitelist.include?(foul)
30
+ end
31
+ @scoped_replacement = nil
32
+ text
33
+ end
34
+
35
+ def replacement(chars)
36
+ @scoped_replacement = chars
37
+ self
38
+ end
39
+
40
+ def offensive(text)
41
+ words = []
42
+ blacklist.each do |foul|
43
+ words << foul if text =~ /\b#{foul}\b/i && !whitelist.include?(foul)
44
+ end
45
+ words.uniq
46
+ end
47
+
48
+ def replace(word)
49
+ content = @scoped_replacement || Obscenity.config.replacement
50
+ case content
51
+ when :vowels then word.gsub(/[aeiou]/i, '*')
52
+ when :stars then '*' * word.size
53
+ when :nonconsonants then word.gsub(/[^bcdfghjklmnpqrstvwxyz]/i, '*')
54
+ when :default, :garbled then '$@!#%'
55
+ else content
56
+ end
57
+ end
58
+
59
+ private
60
+
61
+ def set_list_content(list)
62
+ case list
63
+ when Array then list
64
+ when String, Pathname then ::YAML.load_file( list.to_s )
65
+ else []
66
+ end
67
+ end
68
+
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,52 @@
1
+ module Obscenity
2
+ class Config
3
+
4
+ attr_accessor :replacement
5
+
6
+ DEFAULT_WHITELIST = []
7
+ DEFAULT_BLACKLIST = File.dirname(__FILE__) + "/../../config/blacklist.yml"
8
+
9
+ def initialize
10
+ yield(self) if block_given?
11
+ validate_config_options
12
+ end
13
+
14
+ def replacement
15
+ @replacement ||= :garbled
16
+ end
17
+
18
+ def blacklist
19
+ @blacklist ||= DEFAULT_BLACKLIST
20
+ end
21
+
22
+ def blacklist=(value)
23
+ @blacklist = value == :default ? DEFAULT_BLACKLIST : value
24
+ end
25
+
26
+ def whitelist
27
+ @whitelist ||= DEFAULT_WHITELIST
28
+ end
29
+
30
+ def whitelist=(value)
31
+ @whitelist = value == :default ? DEFAULT_WHITELIST : value
32
+ end
33
+
34
+ private
35
+
36
+ def validate_config_options
37
+ [@blacklist, @whitelist].each{ |content| validate_list_content(content) if content }
38
+ end
39
+
40
+ def validate_list_content(content)
41
+ case content
42
+ when Array then !content.empty? || raise(Obscenity::EmptyContentList.new('Content array is empty.'))
43
+ when String then File.exists?(content) || raise(Obscenity::UnkownContentFile.new("Content file can't be found."))
44
+ when Pathname then content.exist? || raise(Obscenity::UnkownContentFile.new("Content file can't be found."))
45
+ when Symbol then content == :default || raise(Obscenity::UnkownContent.new("The only accepted symbol is :default."))
46
+ else
47
+ raise Obscenity::UnkownContent.new("The content can be either an Array, Pathname, or String path to a .yml file.")
48
+ end
49
+ end
50
+
51
+ end
52
+ end
@@ -0,0 +1,7 @@
1
+ module Obscenity
2
+ class Error < RuntimeError; end
3
+
4
+ class UnkownContent < Error; end
5
+ class UnkownContentFile < Error; end
6
+ class EmptyContentList < Error; end
7
+ end
@@ -0,0 +1,91 @@
1
+ module Rack
2
+ class Obscenity
3
+
4
+ def initialize(app, options = {})
5
+ @app, @options = app, options
6
+ end
7
+
8
+ def call(env)
9
+ rejectable = false
10
+ post_params = Rack::Utils.parse_query(env['rack.input'].read, "&")
11
+ get_params = Rack::Utils.parse_query(env['QUERY_STRING'], "&")
12
+
13
+ if @options.has_key?(:reject)
14
+ rejactable = validate_rejectability_of( select_params(:reject, get_params.update(post_params)) )
15
+
16
+ elsif @options.has_key?(:sanitize)
17
+ get_params = sanitize_contents_of(get_params)
18
+ post_params = sanitize_contents_of(post_params)
19
+
20
+ env['QUERY_STRING'] = Rack::Utils.build_query(get_params)
21
+ env['rack.input'] = StringIO.new(Rack::Utils.build_query(post_params))
22
+ end
23
+
24
+ rejactable ? reject : continue(env)
25
+ end
26
+
27
+ private
28
+
29
+ def continue(env)
30
+ @app.call(env)
31
+ end
32
+
33
+ def reject
34
+ length, content = 0, ''
35
+ if @options[:reject].is_a?(Hash)
36
+ if (message = @options[:reject][:message]).present?
37
+ content = message
38
+ length = message.size
39
+ elsif (path = @options[:reject][:path]).present?
40
+ if (path = ::File.expand_path(path)) && ::File.exists?(path)
41
+ content = ::File.read(path)
42
+ length = content.size
43
+ end
44
+ end
45
+ end
46
+
47
+ [422, {'Content-Type' => 'text/html', 'Content-Length' => length.to_s}, [content]]
48
+ end
49
+
50
+ def validate_rejectability_of(params = {})
51
+ should_reject_request = false
52
+ params.each_pair do |param, value|
53
+ if value.is_a?(Hash)
54
+ validates_rejectability_of(value)
55
+ elsif value.is_a?(String)
56
+ next unless value.size >= 3
57
+ if ::Obscenity.profane?(value)
58
+ should_reject_request = true
59
+ break
60
+ end
61
+ else
62
+ next
63
+ end
64
+ end
65
+ should_reject_request
66
+ end
67
+
68
+ def sanitize_contents_of(params)
69
+ sanitized_params = {}
70
+ replacement_method = @options[:sanitize].is_a?(Hash) && @options[:sanitize][:replacement]
71
+ select_params(:sanitize, params).each{|param, value|
72
+ if value.is_a?(String)
73
+ next unless value.size >= 3
74
+ sanitized_params[param] = ::Obscenity.replacement(replacement_method).sanitize(value)
75
+ else
76
+ next
77
+ end
78
+ }
79
+ params.update(sanitized_params)
80
+ end
81
+
82
+ def select_params(key, params = {})
83
+ if @options[key].is_a?(Hash) && @options[key][:params].is_a?(Array)
84
+ params.select{ |param, vvalue| @options[key][:params].include?(param.to_sym) }
85
+ else
86
+ params
87
+ end
88
+ end
89
+
90
+ end
91
+ end
@@ -0,0 +1,9 @@
1
+ if defined?(RSpec::Matchers)
2
+ require 'rspec/expectations'
3
+
4
+ RSpec::Matchers.define :be_profane do |expected|
5
+ match do |actual|
6
+ Obscenity.profane?(actual) == expected
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,5 @@
1
+ module Obscenity
2
+
3
+ VERSION = '0.0.1'
4
+
5
+ end
data/lib/obscenity.rb ADDED
@@ -0,0 +1,38 @@
1
+ require 'obscenity/error'
2
+ require 'obscenity/config'
3
+ require 'obscenity/base'
4
+ require 'obscenity/version'
5
+
6
+ if defined?(::RSpec)
7
+ require 'obscenity/rspec_matcher'
8
+ end
9
+
10
+ module Obscenity extend self
11
+
12
+ attr_accessor :config
13
+
14
+ def configure(&block)
15
+ @config = Config.new(&block)
16
+ end
17
+
18
+ def config
19
+ @config ||= Config.new
20
+ end
21
+
22
+ def profane?(word)
23
+ Obscenity::Base.profane?(word)
24
+ end
25
+
26
+ def sanitize(text)
27
+ Obscenity::Base.sanitize(text)
28
+ end
29
+
30
+ def replacement(chars)
31
+ Obscenity::Base.replacement(chars)
32
+ end
33
+
34
+ def offensive(text)
35
+ Obscenity::Base.offensive(text)
36
+ end
37
+
38
+ end
data/obscenity.gemspec ADDED
@@ -0,0 +1,20 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'obscenity/version'
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = "obscenity2"
8
+ s.version = Obscenity::VERSION
9
+
10
+ s.authors = ["Thiago Jackiw"]
11
+ s.description = " Obscenity is a profanity filter gem for Ruby/Rubinius, Rails (through ActiveModel), and Rack middleware "
12
+ s.email = "tjackiw@gmail.com"
13
+ s.files = `git ls-files`.split($/)
14
+ s.homepage = "http://github.com/tjackiw/obscenity"
15
+ s.licenses = ["MIT"]
16
+ s.require_paths = ["lib"]
17
+ s.summary = "Obscenity is a profanity filter gem for Ruby/Rubinius, Rails (through ActiveModel), and Rack middleware"
18
+ s.test_files = s.files.grep(%r{^(test|spec|features)/})
19
+ end
20
+
data/test/helper.rb ADDED
@@ -0,0 +1,26 @@
1
+ require 'rubygems'
2
+ require 'yaml'
3
+ require 'test/unit'
4
+ require 'shoulda'
5
+
6
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
7
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
8
+
9
+ require 'active_model'
10
+ require 'obscenity'
11
+ require 'obscenity/active_model'
12
+
13
+ module Dummy
14
+ class BaseModel
15
+ include ActiveModel::Validations
16
+
17
+ attr_accessor :title
18
+
19
+ def initialize(attr_names)
20
+ attr_names.each{ |k,v| send("#{k}=", v) }
21
+ end
22
+ end
23
+ end
24
+
25
+ class Test::Unit::TestCase
26
+ end
@@ -0,0 +1 @@
1
+ We don't accept profanity
@@ -0,0 +1,69 @@
1
+ require 'helper'
2
+
3
+ class TestActiveModel < Test::Unit::TestCase
4
+
5
+ def generate_new_class(name, options = {})
6
+ Dummy.send(:remove_const, name) if Dummy.const_defined?(name)
7
+ klass = Class.new(Dummy::BaseModel) do
8
+ validates :title, options
9
+ end
10
+ Dummy.const_set(name, klass)
11
+ end
12
+
13
+ should "be invalid when title is profane" do
14
+ klass = generate_new_class("Post", obscenity: true)
15
+ post = klass.new(title: "He who poops, shits itself")
16
+ assert !post.valid?
17
+ assert post.errors.has_key?(:title)
18
+ assert_equal ['cannot be profane'], post.errors[:title]
19
+ end
20
+
21
+ should "be invalid when title is profane and should include a custom error message" do
22
+ klass = generate_new_class("Post", obscenity: { message: "can't be profane!" })
23
+ post = klass.new(title: "He who poops, shits itself")
24
+ assert !post.valid?
25
+ assert post.errors.has_key?(:title)
26
+ assert_equal ["can't be profane!"], post.errors[:title]
27
+ end
28
+
29
+ should "sanitize the title using the default replacement" do
30
+ klass = generate_new_class("Post", obscenity: { sanitize: true })
31
+ post = klass.new(title: "He who poops, shits itself")
32
+ assert post.valid?
33
+ assert !post.errors.has_key?(:title)
34
+ assert_equal "He who poops, $@!#% itself", post.title
35
+ end
36
+
37
+ should "sanitize the title using the :garbled replacement" do
38
+ klass = generate_new_class("Post", obscenity: { sanitize: true, replacement: :garbled })
39
+ post = klass.new(title: "He who poops, shits itself")
40
+ assert post.valid?
41
+ assert !post.errors.has_key?(:title)
42
+ assert_equal "He who poops, $@!#% itself", post.title
43
+ end
44
+
45
+ should "sanitize the title using the :stars replacement" do
46
+ klass = generate_new_class("Post", obscenity: { sanitize: true, replacement: :stars })
47
+ post = klass.new(title: "He who poops, shits itself")
48
+ assert post.valid?
49
+ assert !post.errors.has_key?(:title)
50
+ assert_equal "He who poops, ***** itself", post.title
51
+ end
52
+
53
+ should "sanitize the title using the :vowels replacement" do
54
+ klass = generate_new_class("Post", obscenity: { sanitize: true, replacement: :vowels })
55
+ post = klass.new(title: "He who poops, shits itself")
56
+ assert post.valid?
57
+ assert !post.errors.has_key?(:title)
58
+ assert_equal "He who poops, sh*ts itself", post.title
59
+ end
60
+
61
+ should "sanitize the title using a custom replacement" do
62
+ klass = generate_new_class("Post", obscenity: { sanitize: true, replacement: '[censored]' })
63
+ post = klass.new(title: "He who poops, shits itself")
64
+ assert post.valid?
65
+ assert !post.errors.has_key?(:title)
66
+ assert_equal "He who poops, [censored] itself", post.title
67
+ end
68
+
69
+ end
data/test/test_base.rb ADDED
@@ -0,0 +1,258 @@
1
+ require 'helper'
2
+
3
+ class TestBase < Test::Unit::TestCase
4
+
5
+ context "#respond_to?" do
6
+ should "respond to methods and attributes" do
7
+ [:blacklist, :whitelist, :profane?, :sanitize, :replacement, :offensive, :replace].each do |field|
8
+ assert Obscenity::Base.respond_to?(field)
9
+ end
10
+ end
11
+ end
12
+
13
+ context "#blacklist" do
14
+ context "without custom config" do
15
+ setup { Obscenity::Base.blacklist = :default }
16
+ should "use the default content file when no config is found" do
17
+ assert Obscenity::Base.blacklist.is_a?(Array)
18
+ assert_equal 565, Obscenity::Base.blacklist.size
19
+ end
20
+ end
21
+ context "with custom config" do
22
+ setup { Obscenity::Base.blacklist = ['bad', 'word'] }
23
+ should "respect the config options" do
24
+ assert_equal ['bad', 'word'], Obscenity::Base.blacklist
25
+ end
26
+ end
27
+ end
28
+
29
+ context "#whitelist" do
30
+ context "without custom config" do
31
+ setup { Obscenity::Base.whitelist = :default }
32
+ should "use the default content file when no config is found" do
33
+ assert Obscenity::Base.whitelist.is_a?(Array)
34
+ assert Obscenity::Base.whitelist.empty?
35
+ end
36
+ end
37
+ context "with custom config" do
38
+ setup { Obscenity::Base.whitelist = ['safe', 'word'] }
39
+ should "respect the config options" do
40
+ assert_equal ['safe', 'word'], Obscenity::Base.whitelist
41
+ end
42
+ end
43
+ end
44
+
45
+ context "#profane?" do
46
+ context "without whitelist" do
47
+ context "without custom config" do
48
+ setup {
49
+ Obscenity::Base.blacklist = :default
50
+ Obscenity::Base.whitelist = :default
51
+ }
52
+ should "validate the profanity of a word based on the default list" do
53
+ assert Obscenity::Base.profane?('ass')
54
+ assert Obscenity::Base.profane?('biatch')
55
+ assert !Obscenity::Base.profane?('hello')
56
+ end
57
+ end
58
+ context "with custom blacklist config" do
59
+ setup { Obscenity::Base.blacklist = ['ass', 'word'] }
60
+ should "validate the profanity of a word based on the custom list" do
61
+ assert Obscenity::Base.profane?('ass')
62
+ assert Obscenity::Base.profane?('word')
63
+ assert !Obscenity::Base.profane?('biatch')
64
+ end
65
+ end
66
+ end
67
+ context "with whitelist" do
68
+ context "without custom blacklist config" do
69
+ setup {
70
+ Obscenity::Base.blacklist = :default
71
+ Obscenity::Base.whitelist = ['biatch']
72
+ }
73
+ should "validate the profanity of a word based on the default list" do
74
+ assert Obscenity::Base.profane?('ass')
75
+ assert !Obscenity::Base.profane?('biatch')
76
+ assert !Obscenity::Base.profane?('hello')
77
+ end
78
+ end
79
+ context "with custom blacklist/whitelist config" do
80
+ setup {
81
+ Obscenity::Base.blacklist = ['ass', 'word']
82
+ Obscenity::Base.whitelist = ['word']
83
+ }
84
+ should "validate the profanity of a word based on the custom list" do
85
+ assert Obscenity::Base.profane?('ass')
86
+ assert !Obscenity::Base.profane?('word')
87
+ assert !Obscenity::Base.profane?('biatch')
88
+ end
89
+ end
90
+ end
91
+ end
92
+
93
+ context "#sanitize" do
94
+ context "without whitelist" do
95
+ context "without custom config" do
96
+ setup {
97
+ Obscenity::Base.blacklist = :default
98
+ Obscenity::Base.whitelist = :default
99
+ }
100
+ should "sanitize and return a clean text based on the default list" do
101
+ assert_equal "Yo $@!#%, sup", Obscenity::Base.sanitize('Yo assclown, sup')
102
+ assert_equal "Hello world", Obscenity::Base.sanitize('Hello world')
103
+ end
104
+ end
105
+ context "with custom blacklist config" do
106
+ setup { Obscenity::Base.blacklist = ['ass', 'word'] }
107
+ should "sanitize and return a clean text based on a custom list" do
108
+ assert_equal "Yo $@!#%, sup", Obscenity::Base.sanitize('Yo word, sup')
109
+ assert_equal "Hello world", Obscenity::Base.sanitize('Hello world')
110
+ end
111
+ end
112
+ end
113
+ context "with whitelist" do
114
+ context "without custom blacklist config" do
115
+ setup {
116
+ Obscenity::Base.blacklist = :default
117
+ Obscenity::Base.whitelist = ['biatch']
118
+ }
119
+ should "sanitize and return a clean text based on the default blacklist and custom whitelist" do
120
+ assert_equal "Yo $@!#%, sup", Obscenity::Base.sanitize('Yo assclown, sup')
121
+ assert_equal "Yo biatch, sup", Obscenity::Base.sanitize('Yo biatch, sup')
122
+ end
123
+ end
124
+ context "with custom blacklist/whitelist config" do
125
+ setup {
126
+ Obscenity::Base.blacklist = ['clown', 'biatch']
127
+ Obscenity::Base.whitelist = ['biatch']
128
+ }
129
+ should "validate the profanity of a word based on the custom list" do
130
+ assert_equal "Yo $@!#%, sup", Obscenity::Base.sanitize('Yo clown, sup')
131
+ assert_equal "Yo biatch, sup", Obscenity::Base.sanitize('Yo biatch, sup')
132
+ end
133
+ end
134
+ end
135
+ end
136
+
137
+ context "#replacement" do
138
+ context "without whitelist" do
139
+ context "without custom config" do
140
+ setup {
141
+ Obscenity::Base.blacklist = :default
142
+ Obscenity::Base.whitelist = :default
143
+ }
144
+ should "sanitize and return a clean text based on the default list" do
145
+ assert_equal "Yo ********, sup", Obscenity::Base.replacement(:stars).sanitize('Yo assclown, sup')
146
+ assert_equal "Yo $@!#%, sup", Obscenity::Base.replacement(:garbled).sanitize('Yo assclown, sup')
147
+ assert_equal "Yo *sscl*wn, sup", Obscenity::Base.replacement(:vowels).sanitize('Yo assclown, sup')
148
+ assert_equal "Oh, *h*t!", Obscenity::Base.replacement(:nonconsonants).sanitize('Oh, 5hit!')
149
+ assert_equal "Yo [censored], sup", Obscenity::Base.replacement('[censored]').sanitize('Yo assclown, sup')
150
+ assert_equal "Hello World", Obscenity::Base.replacement(:default).sanitize('Hello World')
151
+ end
152
+ end
153
+ context "with custom blacklist config" do
154
+ setup { Obscenity::Base.blacklist = ['ass', 'word', 'w0rd'] }
155
+ should "sanitize and return a clean text based on a custom list" do
156
+ assert_equal "Yo ****, sup", Obscenity::Base.replacement(:stars).sanitize('Yo word, sup')
157
+ assert_equal "Yo $@!#%, sup", Obscenity::Base.replacement(:garbled).sanitize('Yo word, sup')
158
+ assert_equal "Yo w*rd, sup", Obscenity::Base.replacement(:vowels).sanitize('Yo word, sup')
159
+ assert_equal "Yo w*rd, sup", Obscenity::Base.replacement(:nonconsonants).sanitize('Yo w0rd, sup')
160
+ assert_equal "Yo [censored], sup", Obscenity::Base.replacement('[censored]').sanitize('Yo word, sup')
161
+ assert_equal "Hello World", Obscenity::Base.replacement(:default).sanitize('Hello World')
162
+ end
163
+ end
164
+ end
165
+ context "with whitelist" do
166
+ context "without custom blacklist config" do
167
+ setup {
168
+ Obscenity::Base.blacklist = :default
169
+ Obscenity::Base.whitelist = ['biatch']
170
+ }
171
+ should "sanitize and return a clean text based on the default blacklist and custom whitelist" do
172
+ assert_equal "Yo ********, sup", Obscenity::Base.replacement(:stars).sanitize('Yo assclown, sup')
173
+ assert_equal "Yo $@!#%, sup", Obscenity::Base.replacement(:garbled).sanitize('Yo assclown, sup')
174
+ assert_equal "Yo *sscl*wn, sup", Obscenity::Base.replacement(:vowels).sanitize('Yo assclown, sup')
175
+ assert_equal "What an *r**", Obscenity::Base.replacement(:nonconsonants).sanitize('What an ar5e')
176
+ assert_equal "Yo [censored], sup", Obscenity::Base.replacement('[censored]').sanitize('Yo assclown, sup')
177
+ assert_equal "Yo biatch, sup", Obscenity::Base.replacement(:default).sanitize('Yo biatch, sup')
178
+ end
179
+ end
180
+ context "with custom blacklist/whitelist config" do
181
+ setup {
182
+ Obscenity::Base.blacklist = ['clown', 'biatch']
183
+ Obscenity::Base.whitelist = ['biatch']
184
+ }
185
+ should "validate the profanity of a word based on the custom list" do
186
+ assert_equal "Yo *****, sup", Obscenity::Base.replacement(:stars).sanitize('Yo clown, sup')
187
+ assert_equal "Yo $@!#%, sup", Obscenity::Base.replacement(:garbled).sanitize('Yo clown, sup')
188
+ assert_equal "Yo cl*wn, sup", Obscenity::Base.replacement(:vowels).sanitize('Yo clown, sup')
189
+ assert_equal "Yo cl*wn, sup", Obscenity::Base.replacement(:nonconsonants).sanitize('Yo clown, sup')
190
+ assert_equal "Yo [censored], sup", Obscenity::Base.replacement('[censored]').sanitize('Yo clown, sup')
191
+ assert_equal "Yo biatch, sup", Obscenity::Base.replacement(:default).sanitize('Yo biatch, sup')
192
+ assert_equal "Yo assclown, sup", Obscenity::Base.replacement(:default).sanitize('Yo assclown, sup')
193
+ end
194
+ end
195
+ end
196
+ end
197
+
198
+ context "#offensive" do
199
+ context "without whitelist" do
200
+ context "without custom config" do
201
+ setup {
202
+ Obscenity::Base.blacklist = :default
203
+ Obscenity::Base.whitelist = :default
204
+ }
205
+ should "return an array with the offensive words based on the default list" do
206
+ assert_equal ['assclown'], Obscenity::Base.offensive('Yo assclown, sup')
207
+ assert_equal [], Obscenity::Base.offensive('Hello world')
208
+ end
209
+ end
210
+ context "with custom blacklist config" do
211
+ setup { Obscenity::Base.blacklist = ['yo', 'word'] }
212
+ should "return an array with the offensive words based on a custom list" do
213
+ assert_equal ['yo', 'word'], Obscenity::Base.offensive('Yo word, sup')
214
+ assert_equal [], Obscenity::Base.offensive('Hello world')
215
+ end
216
+ end
217
+ end
218
+ context "with whitelist" do
219
+ context "without custom blacklist config" do
220
+ setup {
221
+ Obscenity::Base.blacklist = :default
222
+ Obscenity::Base.whitelist = ['biatch']
223
+ }
224
+ should "return an array with the offensive words based on the default blacklist and custom whitelist" do
225
+ assert_equal ['assclown'], Obscenity::Base.offensive('Yo assclown, sup')
226
+ assert_equal [], Obscenity::Base.offensive('Yo biatch, sup')
227
+ end
228
+ end
229
+ context "with custom blacklist/whitelist config" do
230
+ setup {
231
+ Obscenity::Base.blacklist = ['clown', 'biatch']
232
+ Obscenity::Base.whitelist = ['biatch']
233
+ }
234
+ should "return an array with the offensive words based on the custom list" do
235
+ assert_equal ['clown'], Obscenity::Base.offensive('Yo clown, sup')
236
+ assert_equal [], Obscenity::Base.offensive('Yo biatch, sup')
237
+ end
238
+ end
239
+ end
240
+ end
241
+
242
+ context "#replace" do
243
+ should "replace the given word by the given replacement method" do
244
+ [
245
+ [:vowels, {original: "Oh 5hit", clean: "Oh 5h*t"}],
246
+ [:nonconsonants, {original: "Oh 5hit", clean: "Oh *h*t"}],
247
+ [:stars, {original: "Oh 5hit", clean: "Oh ****"}],
248
+ [:garbled, {original: "Oh 5hit", clean: "Oh $@!#%"}],
249
+ [:default, {original: "Oh 5hit", clean: "Oh $@!#%"}],
250
+ ["[censored]", {original: "Oh 5hit", clean: "Oh [censored]"}],
251
+ [nil, {original: "Oh 5hit", clean: "Oh $@!#%"}]
252
+ ].each do |replacement_method, content|
253
+ assert_equal content[:clean], Obscenity::Base.replacement(replacement_method).sanitize(content[:original]), "(replacement should match for #{replacement_method})"
254
+ end
255
+ end
256
+ end
257
+
258
+ end