pony-test 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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
+