pony-test 0.1.0

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.
Files changed (5) hide show
  1. data/README.rdoc +101 -0
  2. data/Rakefile +118 -0
  3. data/lib/email_steps.rb +111 -0
  4. data/lib/pony-test.rb +115 -0
  5. metadata +108 -0
data/README.rdoc ADDED
@@ -0,0 +1,101 @@
1
+ = Pony-Test
2
+
3
+ A collection of helper methods and Cucumber steps to make testing email with Pony a piece of cake.
4
+ It works simply by overwriting the Pony mail method with one that stores the email in an array instead of sending it.
5
+ You can access this email with the helper methods and perform whatever checks you want.
6
+
7
+ == Usage
8
+
9
+ === Helper methods
10
+
11
+ <tt>deliveries</tt>, <tt>all_email</tt> returns the whole array of emails
12
+
13
+ <tt>current_email</tt> returns either the last email sent, or the last email "opened"
14
+
15
+ <tt>current_email_address</tt> returns the last address used in a lookup operation
16
+
17
+ <tt>reset_mailer</tt> clears everything
18
+
19
+ <tt>last_email_sent</tt> "opens" the last email sent
20
+
21
+ <tt>inbox</tt>, <tt>inbox_for</tt> returns all emails, filterable by address, pass the option <tt>:address => 'foo@example.com'</tt>
22
+
23
+ <tt>open_email</tt>, <tt>open_email_for</tt> "opens" the first email matching all criteria, accepts options <tt>:address</tt>, <tt>:with_subject</tt>, and <tt>:with_body</tt>
24
+
25
+ <tt>find_email</tt>, <tt>find_email_for</tt> returns all email matching all criteria, accepts options <tt>:address</tt>, <tt>:with_subject</tt>, and <tt>:with_body</tt>
26
+
27
+ <tt>email_links</tt> returns all links in an email body, searching <tt>current_email</tt> by default
28
+
29
+ <tt>email_links_matching</tt> returns all links matching a pattern
30
+
31
+ === Cucumber
32
+
33
+ Scenario: A new person signs up
34
+ Given I am at "/"
35
+ When I fill in "Email" with "quentin@example.com"
36
+ And I press "Sign up"
37
+ Then I should have an email
38
+ And I should see "confirm" in the email body
39
+
40
+ When I visit "confirm" in the email
41
+ Then I should see "Confirm your new account"
42
+
43
+ Please read <tt>lib/email_steps.rb</tt> for the other steps. For more examples, check out the <tt>examples</tt> folder for a small example app that implements the steps.
44
+
45
+ == Setup
46
+
47
+ For now, I am including this project into others with a symlink. If you clone this project next to your current working project, run this inside you current project:
48
+
49
+ ln -s ../pony-test pony-test
50
+
51
+ To require files from this folder, you may first want to add the <tt>lib</tt> dir to the load path. For example, from the file <tt>spec/spec_helper.rb</tt> you could add:
52
+
53
+ $: << File.join(File.expand_path(File.dirname(__FILE__)), %w{ .. pony-test lib })
54
+
55
+ ...
56
+ require 'pony-test'
57
+
58
+ A gem for this project is coming soon.
59
+
60
+ === Cucumber
61
+
62
+ To use pony-test in Cucumber include the helpers in <tt>features/support/env.rb</tt>:
63
+
64
+ World do
65
+ ...
66
+ include Pony::TestHelpers
67
+ end
68
+
69
+ This will load all the helpers that the steps rely on. You probably want all emails to be cleared for each scenario:
70
+
71
+ Before do
72
+ reset_mailer
73
+ end
74
+
75
+ Also, copy <tt>email_steps.rb</tt> to <tt>features/step_definitions</tt> to get access to many predifined steps.
76
+
77
+ === RSpec
78
+
79
+ You will need to include Pony::TestHelpers in your example groups.
80
+ If you want to have access to the helpers in all of your examples you can do the following in your <tt>spec_helper.rb</tt>:
81
+
82
+ Spec::Runner.configure do |config|
83
+ config.include(Pony::TestHelpers)
84
+ end
85
+
86
+ Otherwise, you will need to include them in the example groups you wish to use them:
87
+
88
+ describe "Signup Email" do
89
+ include Pony::TestHelpers
90
+ ...
91
+ end
92
+
93
+ Remember to call <tt>reset_mailer</tt> in a <tt>before</tt> block or whenever you want the emails to be reset.
94
+
95
+ == Acknowledgements
96
+
97
+ This project is a major simplification and rewrite of the Email-Spec project:
98
+
99
+ http://github.com/bmabey/email-spec
100
+
101
+ If you are a Rails/ActionMailer user, you may want to check it out.
data/Rakefile ADDED
@@ -0,0 +1,118 @@
1
+ require "rubygems"
2
+ require "rake/gempackagetask"
3
+ require "rake/rdoctask"
4
+
5
+ task :default => :spec
6
+
7
+ require "spec"
8
+ require "spec/rake/spectask"
9
+ Spec::Rake::SpecTask.new do |t|
10
+ t.spec_opts = %w(--format specdoc --colour)
11
+ t.libs = ["spec"]
12
+ end
13
+
14
+ # This builds the actual gem. For details of what all these options
15
+ # mean, and other ones you can add, check the documentation here:
16
+ #
17
+ # http://rubygems.org/read/chapter/20
18
+ #
19
+ spec = Gem::Specification.new do |s|
20
+
21
+ # Change these as appropriate
22
+ s.name = "pony-test"
23
+ s.version = "0.1.0"
24
+ s.summary = "Collection of helper methods and Cucumber steps for testing email through Pony"
25
+ s.author = "John Mendonca"
26
+ s.email = "joaosihno@gmail.com"
27
+ s.homepage = "http://github.com/johnmendonca/pony-test"
28
+
29
+ s.has_rdoc = true
30
+ s.extra_rdoc_files = %w(README.rdoc)
31
+ s.rdoc_options = %w(--main README.rdoc)
32
+
33
+ # Add any extra files to include in the gem
34
+ s.files = %w(Rakefile README.rdoc) + Dir.glob("{spec,lib/**/*}")
35
+ s.require_paths = ["lib"]
36
+
37
+ # If you want to depend on other gems, add them here, along with any
38
+ # relevant versions
39
+ # s.add_dependency("")
40
+
41
+ # If your tests use any gems, include them here
42
+ s.add_development_dependency("pony", "~> 0.6.0")
43
+ s.add_development_dependency("rspec")
44
+ s.add_development_dependency("cucumber")
45
+ s.add_development_dependency("webrat")
46
+ s.add_development_dependency("rack-test")
47
+
48
+ # If you want to publish automatically to rubyforge, you'll may need
49
+ # to tweak this, and the publishing task below too.
50
+ s.rubyforge_project = "pony-test"
51
+ end
52
+
53
+ # This task actually builds the gem. We also regenerate a static
54
+ # .gemspec file, which is useful if something (i.e. GitHub) will
55
+ # be automatically building a gem for this project. If you're not
56
+ # using GitHub, edit as appropriate.
57
+ Rake::GemPackageTask.new(spec) do |pkg|
58
+ pkg.gem_spec = spec
59
+
60
+ # Generate the gemspec file for github.
61
+ file = File.dirname(__FILE__) + "/#{spec.name}.gemspec"
62
+ File.open(file, "w") {|f| f << spec.to_ruby }
63
+ end
64
+
65
+ # Generate documentation
66
+ Rake::RDocTask.new do |rd|
67
+ rd.main = "README.rdoc"
68
+ rd.rdoc_files.include("README.rdoc", "lib/**/*.rb")
69
+ rd.rdoc_dir = "rdoc"
70
+ end
71
+
72
+ desc 'Clear out RDoc and generated packages'
73
+ task :clean => [:clobber_rdoc, :clobber_package] do
74
+ rm "#{spec.name}.gemspec"
75
+ end
76
+
77
+ # If you want to publish to RubyForge automatically, here's a simple
78
+ # task to help do that. If you don't, just get rid of this.
79
+ # Be sure to set up your Rubyforge account details with the Rubyforge
80
+ # gem; you'll need to run `rubyforge setup` and `rubyforge config` at
81
+ # the very least.
82
+ begin
83
+ require "rake/contrib/sshpublisher"
84
+ namespace :rubyforge do
85
+
86
+ desc "Release gem and RDoc documentation to RubyForge"
87
+ task :release => ["rubyforge:release:gem", "rubyforge:release:docs"]
88
+
89
+ namespace :release do
90
+ desc "Release a new version of this gem"
91
+ task :gem => [:package] do
92
+ require 'rubyforge'
93
+ rubyforge = RubyForge.new
94
+ rubyforge.configure
95
+ rubyforge.login
96
+ rubyforge.userconfig['release_notes'] = spec.summary
97
+ path_to_gem = File.join(File.dirname(__FILE__), "pkg", "#{spec.name}-#{spec.version}.gem")
98
+ puts "Publishing #{spec.name}-#{spec.version.to_s} to Rubyforge..."
99
+ rubyforge.add_release(spec.rubyforge_project, spec.name, spec.version.to_s, path_to_gem)
100
+ end
101
+
102
+ desc "Publish RDoc to RubyForge."
103
+ task :docs => [:rdoc] do
104
+ config = YAML.load(
105
+ File.read(File.expand_path('~/.rubyforge/user-config.yml'))
106
+ )
107
+
108
+ host = "#{config['username']}@rubyforge.org"
109
+ remote_dir = "/var/www/gforge-projects/pony-test/" # Should be the same as the rubyforge project name
110
+ local_dir = 'rdoc'
111
+
112
+ Rake::SshDirPublisher.new(host, remote_dir, local_dir).upload
113
+ end
114
+ end
115
+ end
116
+ rescue LoadError
117
+ puts "Rake SshDirPublisher is unavailable or your rubyforge environment is not configured."
118
+ end
@@ -0,0 +1,111 @@
1
+ # Commonly used email steps
2
+ #
3
+ # The available methods are:
4
+ #
5
+ # deliveries, all_email
6
+ # current_email
7
+ # current_email_address
8
+ # reset_mailer
9
+ # last_email_sent
10
+ # inbox, inbox_for
11
+ # open_email, open_email_for
12
+ # find_email, find_email_for
13
+ # email_links
14
+ # email_links_matching
15
+ #
16
+
17
+ #
18
+ # A couple methods to handle some words in these steps
19
+ #
20
+
21
+ module EmailStepsWordHelpers
22
+ def get_address(word)
23
+ return nil if word == "I" || word == "they"
24
+ word
25
+ end
26
+
27
+ def get_amount(word)
28
+ return 0 if word == "no"
29
+ return 1 if word == "a" || word == "an"
30
+ word.to_i
31
+ end
32
+ end
33
+
34
+ World(EmailStepsWordHelpers)
35
+
36
+ #
37
+ # Reset the e-mail queue within a scenario.
38
+ #
39
+
40
+ Given /^(?:a clear email queue|no emails have been sent)$/ do
41
+ reset_mailer
42
+ end
43
+
44
+ #
45
+ # Check how many emails have been sent/received
46
+ #
47
+
48
+ Then /^(?:I|they|"([^"]*?)") should have (an|no|\d+) emails?$/ do |person, amount|
49
+ inbox_for(:address => get_address(person)).size.should == get_amount(amount)
50
+ end
51
+
52
+ #
53
+ # Accessing email
54
+ #
55
+
56
+ When /^(?:I|they|"([^"]*?)") opens? the email$/ do |person|
57
+ open_email(:address => get_address(person))
58
+ end
59
+
60
+ When /^(?:I|they|"([^"]*?)") opens? the email with subject "([^"]*?)"$/ do |person, subject|
61
+ open_email(:address => get_address(person), :with_subject => subject)
62
+ end
63
+
64
+ When /^(?:I|they|"([^"]*?)") opens? the email with body "([^"]*?)"$/ do |person, body|
65
+ open_email(:address => get_address(person), :with_body => body)
66
+ end
67
+
68
+ #
69
+ # Inspect the Email Contents
70
+ #
71
+
72
+ Then /^(?:I|they) should see "([^"]*?)" in the email subject$/ do |text|
73
+ current_email.subject.should include(text)
74
+ end
75
+
76
+ Then /^(?:I|they) should see \/([^"]*?)\/ in the email subject$/ do |text|
77
+ current_email.subject.should =~ Regexp.new(text)
78
+ end
79
+
80
+ Then /^(?:I|they) should see "([^"]*?)" in the email body$/ do |text|
81
+ current_email.body.should include(text)
82
+ end
83
+
84
+ Then /^(?:I|they) should see \/([^"]*?)\/ in the email body$/ do |text|
85
+ current_email.body.should =~ Regexp.new(text)
86
+ end
87
+
88
+ Then /^(?:I|they) should see the email is delivered from "([^"]*?)"$/ do |text|
89
+ current_email.from.should include(text)
90
+ end
91
+
92
+ Then /^(?:I|they) should see "([^\"]*)" in the email "([^"]*?)" header$/ do |text, name|
93
+ current_email.header[name].should include(text)
94
+ end
95
+
96
+ Then /^(?:I|they) should see \/([^\"]*)\/ in the email "([^"]*?)" header$/ do |text, name|
97
+ current_email.header[name].should include(Regexp.new(text))
98
+ end
99
+
100
+ #
101
+ # Interact with Email Contents
102
+ #
103
+
104
+ When /^(?:I|they) visit "([^"]*?)" in the email$/ do |text|
105
+ visit email_links_matching(text).first
106
+ end
107
+
108
+ When /^(?:I|they) visit the first link in the email$/ do
109
+ visit email_links.first
110
+ end
111
+
data/lib/pony-test.rb ADDED
@@ -0,0 +1,115 @@
1
+ require 'uri'
2
+
3
+ unless defined?(Pony)
4
+ raise("pony-test requires Pony")
5
+ end
6
+
7
+ #reopen Pony module and replace mail method
8
+ module Pony
9
+ def self.mail(options)
10
+ TestHelpers.deliver(build_tmail(options))
11
+ end
12
+
13
+ module TestHelpers
14
+ @@deliveries = []
15
+ @@current_email = nil
16
+ @@current_email_address = nil
17
+
18
+ def self.deliver(email)
19
+ @@deliveries << email
20
+ @@current_email = email
21
+ end
22
+
23
+ def deliveries
24
+ @@deliveries
25
+ end
26
+ alias_method :all_email, :deliveries
27
+
28
+ def current_email
29
+ @@current_email || raise('No current email')
30
+ end
31
+
32
+ def current_email=(email)
33
+ @@current_email = email
34
+ end
35
+
36
+ def current_email_address
37
+ @@current_email_address
38
+ end
39
+
40
+ def current_email_address=(address)
41
+ @@current_email_address = address
42
+ end
43
+
44
+ def reset_mailer
45
+ self.deliveries.clear
46
+ self.current_email_address = nil
47
+ self.current_email = nil
48
+ end
49
+
50
+ def last_email_sent
51
+ self.current_email = deliveries.last
52
+ self.current_email
53
+ end
54
+
55
+ def inbox_for(opts = {})
56
+ address = opts[:address]
57
+ if address.nil? || address.empty?
58
+ address = self.current_email_address
59
+ end
60
+
61
+ unless address.nil? || address.empty?
62
+ self.current_email_address = address
63
+ end
64
+
65
+ #current_email_address should either be nil or have a specific address
66
+ if current_email_address.nil?
67
+ deliveries
68
+ else
69
+ deliveries.select do |email|
70
+ (email.to && email.to.include?(address)) ||
71
+ (email.bcc && email.bcc.include?(address)) ||
72
+ (email.cc && email.cc.include?(address))
73
+ end
74
+ end
75
+ end
76
+ alias_method :inbox, :inbox_for
77
+
78
+ def open_email_for(opts = {})
79
+ self.current_email = find_email(opts).first
80
+ end
81
+ alias_method :open_email, :open_email_for
82
+
83
+ def find_email_for(opts = {})
84
+ email = inbox_for(opts)
85
+
86
+ if opts[:with_subject]
87
+ email = email.select { |m| m.subject =~ Regexp.new(opts[:with_subject]) }
88
+ end
89
+
90
+ if opts[:with_body]
91
+ email = email.select { |m| m.body =~ Regexp.new(opts[:with_body]) }
92
+ end
93
+
94
+ if email.empty?
95
+ raise "Could not find email. \n Found the following email:\n\n #{deliveries.to_s}"
96
+ end
97
+
98
+ email
99
+ end
100
+ alias_method :find_email, :find_email_for
101
+
102
+ def email_links(email = current_email)
103
+ links = URI.extract(email.body, ['http', 'https'])
104
+ raise "No links found in #{email.body}" if links.nil? || links.empty?
105
+ links
106
+ end
107
+
108
+ def email_links_matching(pattern, email = current_email)
109
+ pattern = /#{Regexp.escape(pattern)}/ unless pattern.is_a?(Regexp)
110
+ links = email_links(email).select { |link| link =~ pattern }
111
+ raise "No link found matching #{pattern.inspect} in #{email.body}" if links.nil? || links.empty?
112
+ links
113
+ end
114
+ end
115
+ end
metadata ADDED
@@ -0,0 +1,108 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: pony-test
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - John Mendonca
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2010-01-03 00:00:00 -08:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: pony
17
+ type: :development
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ~>
22
+ - !ruby/object:Gem::Version
23
+ version: 0.6.0
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: rspec
27
+ type: :development
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: "0"
34
+ version:
35
+ - !ruby/object:Gem::Dependency
36
+ name: cucumber
37
+ type: :development
38
+ version_requirement:
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: "0"
44
+ version:
45
+ - !ruby/object:Gem::Dependency
46
+ name: webrat
47
+ type: :development
48
+ version_requirement:
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: "0"
54
+ version:
55
+ - !ruby/object:Gem::Dependency
56
+ name: rack-test
57
+ type: :development
58
+ version_requirement:
59
+ version_requirements: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ version: "0"
64
+ version:
65
+ description:
66
+ email: joaosihno@gmail.com
67
+ executables: []
68
+
69
+ extensions: []
70
+
71
+ extra_rdoc_files:
72
+ - README.rdoc
73
+ files:
74
+ - Rakefile
75
+ - README.rdoc
76
+ - lib/email_steps.rb
77
+ - lib/pony-test.rb
78
+ has_rdoc: true
79
+ homepage: http://github.com/johnmendonca/pony-test
80
+ licenses: []
81
+
82
+ post_install_message:
83
+ rdoc_options:
84
+ - --main
85
+ - README.rdoc
86
+ require_paths:
87
+ - lib
88
+ required_ruby_version: !ruby/object:Gem::Requirement
89
+ requirements:
90
+ - - ">="
91
+ - !ruby/object:Gem::Version
92
+ version: "0"
93
+ version:
94
+ required_rubygems_version: !ruby/object:Gem::Requirement
95
+ requirements:
96
+ - - ">="
97
+ - !ruby/object:Gem::Version
98
+ version: "0"
99
+ version:
100
+ requirements: []
101
+
102
+ rubyforge_project: pony-test
103
+ rubygems_version: 1.3.5
104
+ signing_key:
105
+ specification_version: 3
106
+ summary: Collection of helper methods and Cucumber steps for testing email through Pony
107
+ test_files: []
108
+