sanitize_email 1.0.0.rc3 → 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG CHANGED
@@ -1,3 +1,16 @@
1
+ Version 1.0.0.rc4 - AUG.11.2012
2
+ - Massive improvement to spec suite, and found bleeding
3
+ - needed to unregister the interceptors:
4
+ - Mail.class_variable_get(:@@delivery_interceptors).pop
5
+ - Added SanitizeEmail.deprecate_in_silence
6
+ - Added SanitizeEmail.sanitary &block
7
+ - Local overrides to SanitizeEmail config for specific local purpose
8
+ - Force Sanitization On for a block
9
+ - Added SanitizeEmail.unsanitary &block
10
+ - Force Sanitization Off for a block
11
+ - Added SanitizeEmail.force_sanitize = true # or false
12
+ - Force Sanitization On or Off
13
+
1
14
  Version 1.0.0.rc3 - AUG.08.2012
2
15
  - Forgot to switch from jeweler to gem-release, so making appropriate changes and bumping again
3
16
  - Aligning closer to bundler gem defaults
@@ -5,7 +18,6 @@ Version 1.0.0.rc3 - AUG.08.2012
5
18
  - Added facets dependency to get cattr functionality (and hopefully other cool stuff)
6
19
  - Gem dependencies in gemspec
7
20
 
8
-
9
21
  Version 1.0.0.rc2 - AUG.08.2012 - botched
10
22
  - Bug: loading the gem in a rails app broke mailer specs in the app - Fixed
11
23
  - https://github.com/pboling/sanitize_email/issues/4
data/Gemfile CHANGED
@@ -1,4 +1,4 @@
1
1
  source "http://rubygems.org"
2
2
 
3
- # Specify your gem's dependencies in mygem.gemspec
3
+ # Specify your gem's dependencies in sanitize_email.gemspec
4
4
  gemspec
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- sanitize_email (1.0.0.rc2)
4
+ sanitize_email (1.0.0.rc3)
5
5
  facets (> 0)
6
6
 
7
7
  GEM
data/README.rdoc CHANGED
@@ -1,25 +1,23 @@
1
- = sanitize_email {<img src="https://codeclimate.com/badge.png" />}[https://codeclimate.com/github/pboling/sanitize_email]
1
+ = sanitize_email {<img src="https://codeclimate.com/badge.png" />}[https://codeclimate.com/github/pboling/sanitize_email] {<img src="https://secure.travis-ci.org/pboling/sanitize_email.png?branch=master" alt="Build Status" />}[http://travis-ci.org/pboling/sanitize_email]
2
2
 
3
3
  This gem allows you to globally override your mail delivery settings. It's particularly helpful when you want to omit the delivery of email (e.g. in development/test environments) or alter the to/cc/bcc (e.g. in staging or demo environments) of all email generated from your application.
4
4
 
5
- It is a "configure it and forget it" type gem that requires very little setup. It includes some very innocuous monkey patching of ActionMailer::Base to work its magic.
5
+ It is a "configure it and forget it" type gem that requires very little setup. It uses the 'register_interceptor' API of ActionMailer or the Mail gem. It should work with Rails >3 or any Ruby app that is using Mail or ActionMailer gems.
6
6
 
7
- It currently solves five (3!) common problems in ruby web applications that use ActionMailer, or the Mail gem, or anything that follows Mailer's register_interceptor pattern:
7
+ It currently solves five (3!) common problems in ruby web applications that use email:
8
8
 
9
- === Working Locally with Production Data
10
-
11
- Peter described this common problem in his original plugin implementation as such:
9
+ === #1 Working Locally with Production Data
12
10
 
13
11
  * I have a production site with live data.
14
12
  * I dump the live data and securely transfer it to another machine (rync -e ssh), and import it using a few rake tasks here: http://github.com/pboling/sir-du-bob
15
13
  * On this separate machine (staging, or development) I run tests, and test various features which often send out email (registration/signup, order placement, etc.)
16
14
  * I usually want the emails to get sent from these non-production environments so I can verify what they look like when sent, but I don't ever want to risk them getting sent to addresses that are not mine.
17
15
 
18
- === Re-routing Email on a Staging or QA Server
16
+ === #2 Re-routing Email on a Staging or QA Server
19
17
 
20
18
  Another very important use case for me is to transparently re-route email generated from a staging or QA server to an appropriate person. For example, it's common for us to set up a staging server for a client to use to view our progress and test out new features. It's important for any email that is generated from our web application be delivered to the client's inbox so that they can review the content and ensure that it's acceptable. Similarly, we set up QA instances for our own QA team and we use {rails-caddy}[http://github.com/jtrupiano/rails-caddy] to allow each QA person to configure it specifically for them.
21
19
 
22
- === Testing Email from a Hot Production Server
20
+ === #3 Testing Email from a Hot Production Server
23
21
 
24
22
  If you install this gem on a production server (which I don't always do), you can load up script/console and override the to/cc/bcc on all emails for the duration of your console session. This allows you to poke and prod a live production instance, and route all email to your own inbox for inspection. The best part is that this can all be accomplished without changing a single line of your application code.
25
23
 
@@ -33,9 +31,10 @@ Customize and add to an initializer:
33
31
 
34
32
  SanitizeEmail::Config.configure do |config|
35
33
  config[:sanitized_recipients] = 'to@sanitize_email.org'
36
- config[:sanitized_bcc] = 'bcc@sanitize_email.org'
37
34
  config[:sanitized_cc] = 'cc@sanitize_email.org'
38
- config[:local_environment_proc] = Proc.new { %w(development test).include?(Rails.env) }
35
+ config[:sanitized_bcc] = 'bcc@sanitize_email.org'
36
+ # sanitize emails from development and test, or set whatever logic should turn sanitize_email on and off here:
37
+ config[:activation_proc] = Proc.new { %w(development test).include?(Rails.env) }
39
38
  config[:use_actual_email_prepended_to_subject] = true # or false
40
39
  config[:use_actual_email_as_sanitized_user_name] = true # or false
41
40
  end
@@ -46,64 +45,16 @@ But wait there's more:
46
45
 
47
46
  Let's say you have a method in your model that you can call to test the signup email. You want to be able to test sending it to any user at any time... but you don't want the user to ACTUALLY get the email, even in production. A dilemma, yes? Not anymore!
48
47
 
49
- To override the environment based switch use force_sanitize, which is nil, and ignored by default. When set to true or false it will turn sanitization on or off:
50
-
51
- SanitizeEmail::Config.configure do |config|
52
- config[:force_sanitize] = true
53
- end
54
-
55
- == Example
56
-
57
- So here's how you can use force_sanitize to override the override.
58
-
59
- Even if you set:
60
-
61
- ActionMailer::Base.local_environments = %w( development )
62
-
63
- and are in the development environment, you can override the override anywhere in your code.
64
-
65
- class User < ActiveRecord::Base
66
- def test_signup_email_me_only
67
- SanitizeEmail::Config.configure do |config|
68
- config[:force_sanitize] = true
69
- end
70
- UserMailer.deliver_signup_notification(self)
71
- UserMailer.force_sanitize = nil
72
- end
73
-
74
- def test_signup_email_user_only
75
- SanitizeEmail::Config.configure do |config|
76
- config[:force_sanitize] = false
77
- end
78
- UserMailer.deliver_signup_notification(self)
79
- UserMailer.force_sanitize = nil
80
- end
81
-
82
- # this third method would conditionally use the overridden recipients based on inclusion of current Rails environment in the local_environments configuration option.
83
- def test_signup_email_environment
84
- UserMailer.deliver_signup_notification(self)
85
- end
86
- end
87
-
88
- Load the console with ruby script/console and regardless of what environment you are in:
89
-
90
- > User.find(4).test_signup_email_me_only
91
-
92
- and the email will have it's recipients, bcc, and cc overridden to be whatever you set the sanitized values to be.
93
- Then if you want to send it to the actual user, instead of yourself
94
-
95
- > User.find(4).test_signup_email_user_only
48
+ To override the environment based switch use force_sanitize, which is normally nil, and ignored by default. When set to true or false it will turn sanitization on or off:
96
49
 
97
- == Install as a Plugin
50
+ SanitizeEmail.force_sanitize = true
98
51
 
99
- Plugin using Git:
52
+ == Deprecations
100
53
 
101
- # Installation as plugin works too! (let me know if you find any bugs, as I don't ever run it this way.)
102
- ./script/plugin install git://github.com/pboling/sanitize_email.git
54
+ Sometimes things get deprecated (meaning they still work, but are noisy about it). If this happens to you, and you like your head in the sand, call this number:
103
55
 
104
- == Install as a Git Submodule (plugin)
56
+ SanitizeEmail::Deprecation.deprecate_in_silence = true
105
57
 
106
- git submodule add git://github.com/pboling/sanitize_email.git vendor/plugins/sanitize_email
107
58
 
108
59
  == Authors
109
60
 
data/init.rb CHANGED
@@ -1,3 +1,2 @@
1
- require 'action_mailer'
2
1
  require 'sanitize_email'
3
2
 
@@ -5,6 +5,7 @@ module SanitizeEmail
5
5
  require 'sanitize_email/version'
6
6
  require 'sanitize_email/config'
7
7
  require 'sanitize_email/bleach'
8
+ require 'sanitize_email/email_matchers'
8
9
  require 'sanitize_email/deprecation'
9
10
 
10
11
  # Allow non-rails implementations to use this gem
@@ -29,17 +30,74 @@ module SanitizeEmail
29
30
  SanitizeEmail[name]
30
31
  end
31
32
 
33
+ # NOTE: Deprecated method
34
+ # We have to actually define because we can't deprecate methods that are hooked up via method_missing
32
35
  def self.sanitized_recipients
33
36
  SanitizeEmail[:sanitized_recipients]
34
37
  end
35
38
 
39
+ # NOTE: Deprecated method
40
+ # We have to actually define because we can't deprecate methods that are hooked up via method_missing
36
41
  def self.local_environments
37
42
  SanitizeEmail[:local_environments]
38
43
  end
39
44
 
45
+ mattr_reader :force_sanitize
46
+ mattr_writer :force_sanitize
47
+ self.force_sanitize = nil
48
+
49
+ # Regardless of the Config settings of SanitizeEmail you can do a local override to send sanitary email in any environment.
50
+ # You have access to all the same configuration options in the parameter hash as you can set in the actual
51
+ # SanitizeEmail.configure block.
52
+ #
53
+ # SanitizeEmail.sanitary(config_options = {}) do
54
+ # Mail.deliver do
55
+ # from 'from@example.org'
56
+ # to 'to@example.org' # Will actually be sent to the override addresses setup in Config
57
+ # reply_to 'reply_to@example.org'
58
+ # subject 'subject'
59
+ # end
60
+ # end
61
+ #
62
+ def self.sanitary(config_options = {}, &block)
63
+ janitor({:forcing => true}) do
64
+ original = SanitizeEmail::Config.config.dup
65
+ SanitizeEmail::Config.config.merge!(config_options)
66
+ yield
67
+ SanitizeEmail::Config.config = original
68
+ end
69
+ end
70
+
71
+ # Regardless of the Config settings of SanitizeEmail you can do a local override to force unsanitary email in any environment.
72
+ #
73
+ # SanitizeEmail.unsanitary do
74
+ # Mail.deliver do
75
+ # from 'from@example.org'
76
+ # to 'to@example.org'
77
+ # reply_to 'reply_to@example.org'
78
+ # subject 'subject'
79
+ # end
80
+ # end
81
+ #
82
+ def self.unsanitary &block
83
+ janitor({:forcing => false}) do
84
+ yield
85
+ end
86
+ end
87
+
88
+ def self.janitor(options, &block)
89
+ return false unless block_given?
90
+ original = SanitizeEmail.force_sanitize
91
+ SanitizeEmail.force_sanitize = options[:forcing]
92
+ yield
93
+ SanitizeEmail.force_sanitize = original
94
+ end
95
+
96
+ # Setup Deprecations!
40
97
  class << self
41
98
  extend SanitizeEmail::Deprecation
42
99
  deprecated_alias :sanitized_recipients, :sanitized_to
43
- deprecated :local_environments, :local_environment_proc
100
+ deprecated :local_environments, :activation_proc
44
101
  end
102
+
45
103
  end
@@ -4,6 +4,10 @@
4
4
  module SanitizeEmail
5
5
  class Bleach
6
6
 
7
+ mattr_reader :deprecate_in_silence
8
+ mattr_writer :deprecate_in_silence
9
+ self.deprecate_in_silence = false
10
+
7
11
  class MissingTo < StandardError; end
8
12
  class UnknownOverride < StandardError; end
9
13
 
@@ -15,7 +19,7 @@ module SanitizeEmail
15
19
  :injected # Track whether or not the subject has been injected with usernames
16
20
 
17
21
  def initialize(args = {})
18
- # Not using extract_options! because no-rails compatibility is a goal
22
+ # Not using extract_options! because non-rails compatibility is a goal
19
23
  @sanitized_to = args[:sanitized_to] || SanitizeEmail[:sanitized_to]
20
24
  @sanitized_cc = args[:sanitized_cc] || SanitizeEmail[:sanitized_cc]
21
25
  @sanitized_bcc = args[:sanitized_bcc] || SanitizeEmail[:sanitized_bcc]
@@ -35,14 +39,36 @@ module SanitizeEmail
35
39
  end
36
40
  end
37
41
 
38
- # Only relevant
39
- def consider_local?
40
- SanitizeEmail.local_environment_proc.call if SanitizeEmail.local_environment_proc.respond_to?(:call)
42
+ def activate?
43
+ SanitizeEmail.activation_proc.call if SanitizeEmail.activation_proc.respond_to?(:call)
41
44
  end
42
45
 
43
46
  # This method will be called by the Hook to determine if an override should occur
47
+ # There are three ways SanitizeEmail can be turned on; in order of precedence they are:
48
+ #
49
+ # 1. SanitizeEmail.force_sanitize = true # by default it is nil
50
+ # 2. Mail.register_interceptor(SanitizeEmail::Bleach.new(:engage => true)) # by default it is nil
51
+ # 3. SanitizeEmail::Config.configure {|config| config[:activation_proc] = Proc.new { true } } be default it is false
52
+ #
53
+ # Note: Number 1 is the method used by the SanitizeEmail.sanitary block
54
+ # Note: Number 2 would not be used unless you setup your own register_interceptor)
55
+ # If installed but not configured, sanitize email DOES NOTHING. Until configured the defaults leave it turned off.
44
56
  def sanitize_engaged?
45
- !SanitizeEmail.force_sanitize.nil? ? SanitizeEmail.force_sanitize : self.consider_local?
57
+
58
+ # Has it been forced via the force_sanitize mattr?
59
+ forced = !SanitizeEmail.force_sanitize.nil?
60
+ #puts "forced: #{SanitizeEmail.force_sanitize.inspect}" if forced
61
+ return SanitizeEmail.force_sanitize if forced
62
+
63
+ # Is this particular instance of Bleach engaged
64
+ engaged = !self.engage.nil?
65
+ #puts "engaged: #{self.engage.inspect}" if engaged
66
+ return self.engage if engaged
67
+
68
+ # Should we sanitize due to the activation_proc?
69
+ #puts "activated: #{self.activate?}"
70
+ return self.activate?
71
+
46
72
  end
47
73
 
48
74
  def subject_override(real_subject, actual_addresses)
@@ -7,9 +7,6 @@ module SanitizeEmail
7
7
  cattr_writer :config
8
8
 
9
9
  self.config ||= {
10
- # Adds the following class attributes to the classes that include NinthBit::SanitizeEmail
11
- :force_sanitize => nil,
12
-
13
10
  # Specify the BCC addresses for the messages that go out in 'local' environments
14
11
  :sanitized_bcc => nil,
15
12
 
@@ -34,18 +31,21 @@ module SanitizeEmail
34
31
  # e.g. "real@example.com rest of subject"
35
32
  :use_actual_email_prepended_to_subject => false,
36
33
 
37
- :local_environment_proc => Proc.new { true }
34
+ :activation_proc => Proc.new { false }
38
35
  }
39
36
  def self.configure &block
40
- yield self.config
37
+ yield @@config
41
38
 
42
39
  # Gracefully handle deprecated config values.
43
40
  # Actual deprecation warnings are thrown in the top SanitizeEmail module thanks to our use of dynamic methods.
44
- if config[:local_environments] && defined?(Rails)
45
- config[:local_environment_proc] = Proc.new { SanitizeEmail.local_environments.include?(Rails.env) }
41
+ if @@config[:local_environments] && defined?(Rails)
42
+ @@config[:activation_proc] = Proc.new { SanitizeEmail.local_environments.include?(Rails.env) }
46
43
  end
47
- if config[:sanitize_recipients]
48
- config[:sanitize_to] = SanitizeEmail.sanitized_recipients
44
+ if @@config[:sanitized_recipients]
45
+ SanitizeEmail.sanitized_recipients # calling it to trigger the deprecation warning.
46
+ #Won't actually be set with any value,
47
+ # because we are still inside the configure block.
48
+ @@config[:sanitized_to] = @@config[:sanitized_recipients]
49
49
  end
50
50
  end
51
51
 
@@ -1,15 +1,20 @@
1
1
  # See http://www.seejohncode.com/2012/01/09/deprecating-methods-in-ruby/
2
+ require 'facets/module/mattr' # gives cattr
2
3
 
3
4
  module SanitizeEmail
4
5
  module Deprecation
5
6
 
7
+ mattr_reader :deprecate_in_silence
8
+ mattr_writer :deprecate_in_silence
9
+ self.deprecate_in_silence = false
10
+
6
11
  # Define a deprecated alias for a method
7
12
  # @param [Symbol] name - name of method to define
8
13
  # @param [Symbol] replacement - name of method to (alias)
9
14
  def deprecated_alias(name, replacement)
10
15
  # Create a wrapped version
11
16
  define_method(name) do |*args, &block|
12
- warn "SanitizeEmail: ##{name} deprecated (please use ##{replacement})"
17
+ warn "SanitizeEmail: ##{name} deprecated (please use ##{replacement})" unless @@deprecate_in_silence
13
18
  send replacement, *args, &block
14
19
  end
15
20
  end
@@ -23,10 +28,12 @@ module SanitizeEmail
23
28
  alias_method old_name, name
24
29
  # And replace it with a wrapped version
25
30
  define_method(name) do |*args, &block|
26
- if replacement
27
- warn "SanitizeEmail: ##{name} deprecated (please use ##{replacement})"
28
- else
29
- warn "SanitizeEmail: ##{name} deprecated"
31
+ unless @@deprecate_in_silence
32
+ if replacement
33
+ warn "SanitizeEmail: ##{name} deprecated (please use ##{replacement})"
34
+ else
35
+ warn "SanitizeEmail: ##{name} deprecated"
36
+ end
30
37
  end
31
38
  send old_name, *args, &block
32
39
  end
@@ -0,0 +1,51 @@
1
+ module SanitizeEmail
2
+ module EmailMatchers
3
+ class UnexpectedMailType < StandardError; end
4
+
5
+ def string_matching(matcher, part, mail_or_part)
6
+ if mail_or_part.respond_to?(:=~) # Can we match a regex against it?
7
+ mail_or_part =~ Regexp.new(Regexp.escape(matcher))
8
+ else
9
+ raise UnexpectedMailType, "Cannot match #{matcher} for #{part}"
10
+ end
11
+ end
12
+
13
+ # Normalize arrays to strings
14
+ def array_matching(matcher, part, mail_or_part)
15
+ mail_or_part = mail_or_part.join(', ') if mail_or_part.respond_to?(:join)
16
+ string_matching(matcher, part, mail_or_part)
17
+ end
18
+
19
+ def email_matching(matcher, part, mail_or_part)
20
+ array_matching(matcher, part, mail_or_part.send(part))
21
+ end
22
+
23
+ if defined?(Rspec)
24
+ [:from, :to, :cc, :bcc, :subject, :reply_to].each do |attribute|
25
+ RSpec::Matchers.define "have_#{attribute}" do |matcher|
26
+ match do |actual|
27
+ email_matching(matcher, attribute, actual)
28
+ end
29
+ end
30
+ end
31
+
32
+ [:from, :to, :cc, :bcc, :subject, :reply_to].each do |attribute|
33
+ RSpec::Matchers.define "be_#{attribute}" do |matcher|
34
+ match do |actual|
35
+ string_matching(matcher, attribute, actual)
36
+ end
37
+ end
38
+ end
39
+
40
+ RSpec::Matchers.define "have_to_username" do |matcher|
41
+ def get_username(email_message)
42
+ email_message.header.fields[3].value
43
+ end
44
+ match do |actual|
45
+ string_matching(matcher, :to_username, get_username(actual))
46
+ end
47
+ end
48
+ end
49
+
50
+ end
51
+ end
@@ -1,5 +1,5 @@
1
1
  #Copyright (c) 2008-12 Peter H. Boling of 9thBit LLC
2
2
  #Released under the MIT license
3
3
  module SanitizeEmail
4
- VERSION = '1.0.0.rc3'
4
+ VERSION = '1.0.2'
5
5
  end
@@ -8,10 +8,11 @@ Gem::Specification.new do |s|
8
8
  s.required_rubygems_version = Gem::Requirement.new("> 1.3.1") if s.respond_to? :required_rubygems_version=
9
9
  s.authors = ["Peter Boling", "John Trupiano", "George Anderson"]
10
10
  s.date = "2012-08-08"
11
- s.summary = "In Rails, Sinatra, or any framework using a Mail-like API: Test an application's email abilities without ever sending a message to actual live addresses"
12
- s.description = "In Rails, Sinatra, or any framework using a Mail-like API: Aids in development, testing, qa, and production troubleshooting of email issues without worrying that emails will get sent to actual live addresses."
11
+ s.summary = "Rails/Sinatra/Mail gem: Test email abilities without ever sending a message to actual live addresses"
12
+ s.description = "In Rails, Sinatra, or simply the mail gem: Aids in development, testing, qa, and production troubleshooting of email issues without worrying that emails will get sent to actual live addresses."
13
13
  s.email = ["peter.boling@gmail.com", "jtrupiano@gmail.com", "george@benevolentcode.com"]
14
14
  s.extra_rdoc_files = [
15
+ "CHANGELOG",
15
16
  "LICENSE",
16
17
  "README.rdoc"
17
18
  ]
@@ -23,46 +24,20 @@ Gem::Specification.new do |s|
23
24
  s.require_paths = ["lib"]
24
25
  s.rubygems_version = "1.8.24"
25
26
 
26
- if s.respond_to? :specification_version then
27
- s.specification_version = 3
27
+ # Runtime Dependencies
28
+ # to replace the cattr_accessor method we lost when removing rails from run time dependencies
29
+ s.add_runtime_dependency(%q<facets>, ["> 0"])
28
30
 
29
- if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
30
- s.add_runtime_dependency(%q<facets>, ["> 0"]) # to replace the cattr_accessor method we lost when removing rails
31
- s.add_development_dependency(%q<rails>, ["> 3"])
32
- s.add_development_dependency(%q<actionmailer>, ["> 3"])
33
- s.add_development_dependency(%q<jeweler>, [">= 0"])
34
- s.add_development_dependency(%q<letter_opener>, [">= 0"])
35
- s.add_development_dependency(%q<launchy>, [">= 0"])
36
- s.add_development_dependency(%q<rspec>, [">= 0"])
37
- s.add_development_dependency(%q<mail>, [">= 0"])
38
- s.add_development_dependency(%q<rdoc>, [">= 3.12"])
39
- s.add_development_dependency(%q<reek>, [">= 1.2.8"])
40
- s.add_development_dependency(%q<roodi>, [">= 2.1.0"])
41
- else
42
- s.add_dependency(%q<facets>, ["> 0"]) # to replace the cattr_accessor method we lost when removing rails
43
- s.add_dependency(%q<rails>, ["> 3"])
44
- s.add_dependency(%q<actionmailer>, ["> 3"])
45
- s.add_dependency(%q<jeweler>, [">= 0"])
46
- s.add_dependency(%q<letter_opener>, [">= 0"])
47
- s.add_dependency(%q<launchy>, [">= 0"])
48
- s.add_dependency(%q<rspec>, [">= 0"])
49
- s.add_dependency(%q<mail>, [">= 0"])
50
- s.add_dependency(%q<rdoc>, [">= 3.12"])
51
- s.add_dependency(%q<reek>, [">= 1.2.8"])
52
- s.add_dependency(%q<roodi>, [">= 2.1.0"])
53
- end
54
- else
55
- s.add_dependency(%q<facets>, ["> 0"]) # to replace the cattr_accessor method we lost when removing rails
56
- s.add_dependency(%q<rails>, ["> 3"])
57
- s.add_dependency(%q<actionmailer>, ["> 3"])
58
- s.add_dependency(%q<jeweler>, [">= 0"])
59
- s.add_dependency(%q<letter_opener>, [">= 0"])
60
- s.add_dependency(%q<launchy>, [">= 0"])
61
- s.add_dependency(%q<rspec>, [">= 0"])
62
- s.add_dependency(%q<mail>, [">= 0"])
63
- s.add_dependency(%q<rdoc>, [">= 3.12"])
64
- s.add_dependency(%q<reek>, [">= 1.2.8"])
65
- s.add_dependency(%q<roodi>, [">= 2.1.0"])
66
- end
31
+ # Development Dependencies
32
+ s.add_development_dependency(%q<rails>, ["> 3"])
33
+ s.add_development_dependency(%q<actionmailer>, ["> 3"])
34
+ s.add_development_dependency(%q<jeweler>, [">= 0"])
35
+ s.add_development_dependency(%q<letter_opener>, [">= 0"])
36
+ s.add_development_dependency(%q<launchy>, [">= 0"])
37
+ s.add_development_dependency(%q<rspec>, [">= 0"])
38
+ s.add_development_dependency(%q<mail>, [">= 0"])
39
+ s.add_development_dependency(%q<rdoc>, [">= 3.12"])
40
+ s.add_development_dependency(%q<reek>, [">= 1.2.8"])
41
+ s.add_development_dependency(%q<roodi>, [">= 2.1.0"])
67
42
  end
68
43
 
@@ -3,63 +3,67 @@ require 'spec_helper'
3
3
  #
4
4
  # TODO: Letter Opener should *not* be required, but setting the delivery method to :file was causing connection errors... WTF?
5
5
  #
6
- # Letter Opener won't let us test the to when the to has a 'user name'
7
- # @email_file.should have_to("~to at example.org~ <to@sanitize_email.org>")
8
- # TODO: Also not sure how to test the user name part of the To: header via the mail object
9
- #
10
- # Letter Opener won't let us test the bcc
11
- # @email_file.should have_cc("cc@sanitize_email.org")
12
- # Fortunately we can still test the mail object returned by the deliver call
13
- #
14
-
15
6
  describe SanitizeEmail do
16
7
 
8
+ DEFAULT_TEST_CONFIG = {
9
+ :sanitized_cc => 'cc@sanitize_email.org',
10
+ :sanitized_bcc => 'bcc@sanitize_email.org',
11
+ :use_actual_email_prepended_to_subject => false,
12
+ :use_actual_email_as_sanitized_user_name => false
13
+ }
14
+
15
+ before(:all) do
16
+ SanitizeEmail::Deprecation.deprecate_in_silence = true
17
+ end
18
+
19
+ # Cleanup, so tests don't bleed
17
20
  after(:each) do
18
21
  SanitizeEmail::Config.config = {}
22
+ SanitizeEmail.force_sanitize = nil
23
+ Mail.class_variable_get(:@@delivery_interceptors).pop
19
24
  end
20
25
 
21
26
  def sanitize_spec_dryer(rails_env = 'test')
22
27
  Launchy.stub(:open)
28
+ Launchy.should_receive(:open)
23
29
  location = File.expand_path('../tmp/mail_dump', __FILE__)
24
30
  FileUtils.rm_rf(location)
25
31
  Mail.defaults do
26
32
  delivery_method LetterOpener::DeliveryMethod, :location => location
27
33
  end
28
-
29
34
  Rails.stub(:env).and_return(rails_env)
30
- @location = location
31
35
  end
32
36
 
33
37
  def configure_sanitize_email(sanitize_hash = {})
34
- defaults = {
35
- :sanitized_to => 'to@sanitize_email.org',
36
- :sanitized_cc => 'cc@sanitize_email.org',
37
- :sanitized_bcc => 'bcc@sanitize_email.org',
38
- :use_actual_email_prepended_to_subject => true,
39
- :use_actual_email_as_sanitized_user_name => true
40
- }
41
- sanitize_hash = defaults.merge(sanitize_hash)
38
+ options = DEFAULT_TEST_CONFIG.merge(sanitize_hash)
39
+ options.reverse_merge!({ :sanitized_to => 'to@sanitize_email.org' }) unless sanitize_hash.has_key?(:sanitized_recipients)
42
40
  SanitizeEmail::Config.configure do |config|
43
- config[:sanitized_to] = sanitize_hash[:sanitized_to]
44
- config[:sanitized_cc] = sanitize_hash[:sanitized_cc]
45
- config[:sanitized_bcc] = sanitize_hash[:sanitized_bcc]
46
- config[:use_actual_email_prepended_to_subject] = sanitize_hash[:use_actual_email_prepended_to_subject]
47
- config[:use_actual_email_as_sanitized_user_name] = sanitize_hash[:use_actual_email_as_sanitized_user_name]
41
+ config[:sanitized_to] = options[:sanitized_to]
42
+ config[:sanitized_cc] = options[:sanitized_cc]
43
+ config[:sanitized_bcc] = options[:sanitized_bcc]
44
+ config[:use_actual_email_prepended_to_subject] = options[:use_actual_email_prepended_to_subject]
45
+ config[:use_actual_email_as_sanitized_user_name] = options[:use_actual_email_as_sanitized_user_name]
48
46
  # For testing deprecated configuration options:
49
- config[:local_environments] = sanitize_hash[:local_environments] if sanitize_hash[:local_environments]
50
- config[:sanitized_to] ||= sanitize_hash[:sanitized_recipients] if sanitize_hash[:sanitized_recipients]
47
+ config[:local_environments] = options[:local_environments] if options[:local_environments]
48
+ config[:sanitized_recipients] = options[:sanitized_recipients] if options[:sanitized_recipients]
51
49
  end
52
50
  Mail.register_interceptor(SanitizeEmail::Bleach.new)
53
51
  end
54
52
 
55
- def sanitized_mail_delivery(options = {})
56
- unless options.has_key?(:force_sanitize)
57
- options[:force_sanitize] = false
53
+ def sanitary_mail_delivery(config_options = {})
54
+ SanitizeEmail.sanitary(config_options) do
55
+ mail_delivery
58
56
  end
59
- # Ensure that localish? will return sanitization_switch if true or false, and use proc when nil
60
- SanitizeEmail::Config.config[:force_sanitize] = options[:force_sanitize]
61
- Launchy.should_receive(:open)
62
- @mail_message = Mail.deliver do
57
+ end
58
+
59
+ def unsanitary_mail_delivery
60
+ SanitizeEmail.unsanitary do
61
+ mail_delivery
62
+ end
63
+ end
64
+
65
+ def mail_delivery
66
+ @email_message = Mail.deliver do
63
67
  from 'from@example.org'
64
68
  to 'to@example.org'
65
69
  cc 'cc@example.org'
@@ -67,75 +71,200 @@ describe SanitizeEmail do
67
71
  reply_to 'reply_to@example.org'
68
72
  subject 'original subject'
69
73
  end
70
- # All the email gets dumped to file once for each type of recipient (:to, :cc, :bcc)
71
- # Each file is identical, so we only need to check one of them:
72
- @email_file = File.read(Dir["#{@location}/*/plain.html"].first)
73
74
  end
74
75
 
75
- context "localish?" do
76
- before(:each) do
77
- sanitize_spec_dryer
78
- configure_sanitize_email
79
- end
76
+ context "en email" do
77
+ context "engaged" do
78
+ before(:each) do
79
+ sanitize_spec_dryer
80
+ configure_sanitize_email
81
+ end
80
82
 
81
- context "false" do
82
- it "alters nothing" do
83
- sanitized_mail_delivery(:force_sanitize => false)
84
- @email_file.should have_from("from@example.org")
85
- @email_file.should have_to("to@example.org")
86
- @mail_message.header.fields[3].value.should_not have_to("to at example.org")
87
- @mail_message.should have_cc("cc@example.org")
88
- @mail_message.should have_bcc("bcc@example.org")
89
- @email_file.should have_subject("original subject")
83
+ context "false" do
84
+ before(:each) do
85
+ unsanitary_mail_delivery
86
+ end
87
+ it "should not alter non-sanitized attributes" do
88
+ @email_message.should have_from('from@example.org')
89
+ @email_message.should have_reply_to('reply_to@example.org')
90
+ end
91
+ it "should not prepend overrides" do
92
+ @email_message.should_not have_to_username("to at sanitize_email.org")
93
+ @email_message.should_not have_subject("(to at sanitize_email.org)")
94
+ end
95
+ it "alters nothing" do
96
+ @email_message.should have_from('from@example.org')
97
+ @email_message.should have_reply_to('reply_to@example.org')
98
+ @email_message.should have_from("from@example.org")
99
+ @email_message.should have_to("to@example.org")
100
+ @email_message.should_not have_to_username("to at")
101
+ @email_message.should have_cc("cc@example.org")
102
+ @email_message.should have_bcc("bcc@example.org")
103
+ @email_message.should have_subject("original subject")
104
+ end
90
105
  end
91
- end
92
106
 
93
- context "true" do
94
- it "should override" do
95
- sanitized_mail_delivery(:force_sanitize => true)
96
- @email_file.should have_from("from@example.org")
97
- #puts "@mail_message.header.fields[3]: #{@mail_message.header.fields[3]}"
98
- #@mail_message.header.fields[3].value.should have_to("to at example.org")
99
- @mail_message.should have_cc("cc@sanitize_email.org")
100
- @mail_message.should have_bcc("bcc@sanitize_email.org")
101
- @email_file.should have_subject("(to at example.org) original subject")
107
+ context "true" do
108
+ before(:each) do
109
+ sanitary_mail_delivery
110
+ end
111
+ it "should not alter non-sanitized attributes" do
112
+ @email_message.should have_from('from@example.org')
113
+ @email_message.should have_reply_to('reply_to@example.org')
114
+ end
115
+ it "should not prepend overrides" do
116
+ @email_message.should_not have_to_username("to at sanitize_email.org")
117
+ @email_message.should_not have_subject("(to at sanitize_email.org)")
118
+ end
119
+ it "should override" do
120
+ @email_message.should have_to("to@sanitize_email.org")
121
+ @email_message.should have_cc("cc@sanitize_email.org")
122
+ @email_message.should have_bcc("bcc@sanitize_email.org")
123
+ end
124
+ it "should not prepend originals by default" do
125
+ @email_message.should_not have_to_username("to at example.org <to@sanitize_email.org>")
126
+ @email_message.should_not have_subject("(to at example.org) original subject")
127
+ end
102
128
  end
103
129
  end
104
- end
105
130
 
106
- context "deprecated config options" do
107
- context "local_environments" do
108
- it "should use local_environment_proc for matching environment" do
109
- sanitize_spec_dryer('test')
110
- configure_sanitize_email({:local_environments => ['test']})
111
- SanitizeEmail[:local_environment_proc].call.should == true
112
- sanitized_mail_delivery(:force_sanitize => nil)
113
- @email_file.should have_to("to@sanitize_email.org")
114
- @email_file.should have_subject("(to at example.org) original subject")
115
- end
116
- it "should use local_environment_proc for non-matching environment" do
117
- sanitize_spec_dryer('production')
118
- configure_sanitize_email({:local_environments => ['development']}) # Won't match!
119
- SanitizeEmail[:local_environment_proc].call.should == false
120
- sanitized_mail_delivery(:force_sanitize => nil)
121
- @mail_message.should_not have_subject("to at example.org")
131
+ context "config options" do
132
+ context ":use_actual_email_prepended_to_subject" do
133
+ context "true" do
134
+ before(:each) do
135
+ sanitize_spec_dryer
136
+ configure_sanitize_email({:use_actual_email_prepended_to_subject => true})
137
+ sanitary_mail_delivery
138
+ end
139
+ it "original to is prepended" do
140
+ @email_message.should have_subject("(to at example.org) original subject")
141
+ end
142
+ it "should not alter non-sanitized attributes" do
143
+ @email_message.should have_from('from@example.org')
144
+ @email_message.should have_reply_to('reply_to@example.org')
145
+ end
146
+ it "should not prepend overrides" do
147
+ @email_message.should_not have_to_username("to at sanitize_email.org")
148
+ @email_message.should_not have_subject("(to at sanitize_email.org)")
149
+ end
150
+ end
151
+ context "false" do
152
+ before(:each) do
153
+ sanitize_spec_dryer
154
+ configure_sanitize_email({:use_actual_email_prepended_to_subject => false})
155
+ sanitary_mail_delivery
156
+ end
157
+ it "original to is not prepended" do
158
+ @email_message.should_not have_subject("(to at example.org) original subject")
159
+ end
160
+ it "should not alter non-sanitized attributes" do
161
+ @email_message.should have_from('from@example.org')
162
+ @email_message.should have_reply_to('reply_to@example.org')
163
+ end
164
+ it "should not prepend overrides" do
165
+ @email_message.should_not have_to_username("to at sanitize_email.org")
166
+ @email_message.should_not have_subject("(to at sanitize_email.org)")
167
+ end
168
+ end
122
169
  end
123
- end
124
170
 
125
- context "sanitized_recipients is set" do
126
- before(:each) do
127
- sanitize_spec_dryer
128
- configure_sanitize_email({:sanitized_recipients => 'barney@sanitize_email.org'})
171
+ context ":use_actual_email_as_sanitized_user_name" do
172
+ context "true" do
173
+ before(:each) do
174
+ sanitize_spec_dryer
175
+ configure_sanitize_email({:use_actual_email_as_sanitized_user_name => true})
176
+ sanitary_mail_delivery
177
+ end
178
+ it "original to is munged and prepended" do
179
+ @email_message.should have_to_username("to at example.org <to@sanitize_email.org>")
180
+ end
181
+ it "should not alter non-sanitized attributes" do
182
+ @email_message.should have_from('from@example.org')
183
+ @email_message.should have_reply_to('reply_to@example.org')
184
+ end
185
+ it "should not prepend overrides" do
186
+ @email_message.should_not have_to_username("to at sanitize_email.org")
187
+ @email_message.should_not have_subject("(to at sanitize_email.org)")
188
+ end
189
+ end
190
+ context "false" do
191
+ before(:each) do
192
+ sanitize_spec_dryer
193
+ configure_sanitize_email({:use_actual_email_as_sanitized_user_name => false})
194
+ sanitary_mail_delivery
195
+ end
196
+ it "original to is not prepended" do
197
+ @email_message.should_not have_to_username("to at example.org <to@sanitize_email.org>")
198
+ end
199
+ it "should not alter non-sanitized attributes" do
200
+ @email_message.should have_from('from@example.org')
201
+ @email_message.should have_reply_to('reply_to@example.org')
202
+ end
203
+ it "should not prepend overrides" do
204
+ @email_message.should_not have_to_username("to at sanitize_email.org")
205
+ @email_message.should_not have_subject("(to at sanitize_email.org)")
206
+ end
207
+ end
129
208
  end
130
- it "used as sanitized_to" do
131
- sanitized_mail_delivery(:force_sanitize => true)
132
- @email_file.should have_from("from@example.org")
133
- @mail_message.should have_to("to@sanitize_email.org")
134
- @email_file.should have_subject("(to at example.org) original subject")
209
+
210
+ context "deprecated" do
211
+ #before(:each) do
212
+ # SanitizeEmail::Deprecation.deprecate_in_silence = false
213
+ #end
214
+ context ":local_environments" do
215
+ context "matching" do
216
+ before(:each) do
217
+ sanitize_spec_dryer('test')
218
+ configure_sanitize_email({:local_environments => ['test']})
219
+ SanitizeEmail[:activation_proc].call.should == true
220
+ mail_delivery
221
+ end
222
+ it "should not alter non-sanitized attributes" do
223
+ @email_message.should have_from('from@example.org')
224
+ @email_message.should have_reply_to('reply_to@example.org')
225
+ end
226
+ it "should use activation_proc for matching environment" do
227
+ @email_message.should have_to("to@sanitize_email.org")
228
+ @email_message.should have_cc("cc@sanitize_email.org")
229
+ @email_message.should have_bcc("bcc@sanitize_email.org")
230
+ end
231
+ end
232
+ context "non-matching" do
233
+ before(:each) do
234
+ sanitize_spec_dryer('production')
235
+ configure_sanitize_email({:local_environments => ['development']}) # Won't match!
236
+ SanitizeEmail[:activation_proc].call.should == false
237
+ mail_delivery
238
+ end
239
+ it "should not alter non-sanitized attributes" do
240
+ @email_message.should have_from('from@example.org')
241
+ @email_message.should have_reply_to('reply_to@example.org')
242
+ end
243
+ it "should use activation_proc for non-matching environment" do
244
+ @email_message.should have_to("to@example.org")
245
+ @email_message.should have_cc("cc@example.org")
246
+ @email_message.should have_bcc("bcc@example.org")
247
+ end
248
+ end
249
+ end
250
+
251
+ context ":sanitized_recipients" do
252
+ before(:each) do
253
+ sanitize_spec_dryer
254
+ configure_sanitize_email({:sanitized_recipients => 'barney@sanitize_email.org'})
255
+ sanitary_mail_delivery
256
+ end
257
+ it "should not alter non-sanitized attributes" do
258
+ @email_message.should have_from('from@example.org')
259
+ @email_message.should have_reply_to('reply_to@example.org')
260
+ end
261
+ it "used as sanitized_to" do
262
+ @email_message.should have_to("barney@sanitize_email.org")
263
+ end
264
+ end
135
265
  end
136
266
  end
137
267
  end
138
-
139
268
  end
140
269
 
141
270
  #TODO: test good_list
data/spec/spec_helper.rb CHANGED
@@ -4,80 +4,16 @@ require 'mail'
4
4
  require 'rails'
5
5
  require 'letter_opener'
6
6
 
7
+ # Requires supporting files with custom matchers and macros, etc,
8
+ # in ./support/ and its subdirectories.
9
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
10
+
7
11
  # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
8
12
  RSpec.configure do |config|
9
13
  config.treat_symbols_as_metadata_keys_with_true_values = true
10
14
  config.run_all_when_everything_filtered = true
11
15
  #config.filter_run :focus
12
- end
13
-
14
- module EmailMatcherHelpers
15
- class UnexpectedMailType < StandardError; end
16
-
17
- # Sweet, nourishing recursion
18
- def email_matching(matcher, part, mail_or_part)
19
- if mail_or_part.respond_to?(part)
20
- # within rspec objects sometimes respond_to all sorts of odd methods they don't really have,
21
- # raising an argument error when called
22
- # Need to write a failing spec for rspec I think to figure out where this is stemming from
23
- begin
24
- email_matching(matcher, part, mail_or_part.send(part))
25
- rescue ArgumentError
26
- if mail_or_part.respond_to?(:=~)
27
- mail_or_part =~ Regexp.new(Regexp.escape(matcher))
28
- else
29
- raise UnexpectedMailType, "Cannot match #{matcher} for #{part}"
30
- end
31
- end
32
- elsif mail_or_part.respond_to?(:join)
33
- email_matching(matcher, part, mail_or_part.join(', '))
34
- elsif mail_or_part.respond_to?(:=~) # Can we match a regex against it?
35
- mail_or_part =~ Regexp.new(Regexp.escape(matcher))
36
- else
37
- raise UnexpectedMailType, "Cannot match #{matcher} for #{part}"
38
- end
39
- end
40
-
41
- end
42
16
 
43
- RSpec::Matchers.define :have_from do |from|
44
- include EmailMatcherHelpers
45
- match do |container|
46
- #puts "container: #{container}"
47
- email_matching(from, :from, container)
48
- end
49
- end
50
- RSpec::Matchers.define :have_to do |to|
51
- include EmailMatcherHelpers
52
- match do |container|
53
- email_matching(to, :to, container)
54
- end
55
- end
56
- RSpec::Matchers.define :have_cc do |cc|
57
- include EmailMatcherHelpers
58
- match do |container|
59
- email_matching(cc, :cc, container)
60
- end
61
- end
62
- # The ActionMailer :file delivery method never prints bcc recipients...
63
- # Neither does LetterOpener :(
64
- # But the mail object itself can be tested!
65
- RSpec::Matchers.define :have_bcc do |bcc|
66
- include EmailMatcherHelpers
67
- match do |container|
68
- email_matching(bcc, :bcc, container)
69
- end
70
- end
71
- RSpec::Matchers.define :have_subject do |subject|
72
- include EmailMatcherHelpers
73
- match do |container|
74
- email_matching(subject, :subject, container)
75
- end
17
+ config.include SanitizeEmail::EmailMatchers
76
18
  end
77
19
 
78
- #RSpec::Matchers.define :have_to_username do |to|
79
- # include EmailMatcherHelpers
80
- # match do |container|
81
- # email_matching(to, :, container)
82
- # end
83
- #end
metadata CHANGED
@@ -1,8 +1,8 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sanitize_email
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0.rc3
5
- prerelease: 6
4
+ version: 1.0.2
5
+ prerelease:
6
6
  platform: ruby
7
7
  authors:
8
8
  - Peter Boling
@@ -189,9 +189,9 @@ dependencies:
189
189
  - - ! '>='
190
190
  - !ruby/object:Gem::Version
191
191
  version: 2.1.0
192
- description: ! 'In Rails, Sinatra, or any framework using a Mail-like API: Aids in
193
- development, testing, qa, and production troubleshooting of email issues without
194
- worrying that emails will get sent to actual live addresses.'
192
+ description: ! 'In Rails, Sinatra, or simply the mail gem: Aids in development, testing,
193
+ qa, and production troubleshooting of email issues without worrying that emails
194
+ will get sent to actual live addresses.'
195
195
  email:
196
196
  - peter.boling@gmail.com
197
197
  - jtrupiano@gmail.com
@@ -199,6 +199,7 @@ email:
199
199
  executables: []
200
200
  extensions: []
201
201
  extra_rdoc_files:
202
+ - CHANGELOG
202
203
  - LICENSE
203
204
  - README.rdoc
204
205
  files:
@@ -216,6 +217,7 @@ files:
216
217
  - lib/sanitize_email/bleach.rb
217
218
  - lib/sanitize_email/config.rb
218
219
  - lib/sanitize_email/deprecation.rb
220
+ - lib/sanitize_email/email_matchers.rb
219
221
  - lib/sanitize_email/engine.rb
220
222
  - lib/sanitize_email/railtie.rb
221
223
  - lib/sanitize_email/version.rb
@@ -246,8 +248,8 @@ rubyforge_project:
246
248
  rubygems_version: 1.8.24
247
249
  signing_key:
248
250
  specification_version: 3
249
- summary: ! 'In Rails, Sinatra, or any framework using a Mail-like API: Test an application''s
250
- email abilities without ever sending a message to actual live addresses'
251
+ summary: ! 'Rails/Sinatra/Mail gem: Test email abilities without ever sending a message
252
+ to actual live addresses'
251
253
  test_files:
252
254
  - spec/sanitize_email_spec.rb
253
255
  - spec/spec_helper.rb