Skip to content

Instantly share code, notes, and snippets.

@Ken-g6
Created February 20, 2012 17:19
Show Gist options
  • Save Ken-g6/1870180 to your computer and use it in GitHub Desktop.
Save Ken-g6/1870180 to your computer and use it in GitHub Desktop.
A RubySlim FitNesse fixture to test mail from a GMail account.
require 'rubygems'
require 'gmail'
# A RubySlim FitNesse fixture to test mail from a GMail account.
class TestGmail
# Log in to the gmail account of your choice.
def initialize(username, password)
ObjectSpace.define_finalizer(self, proc { @gmail.logout if @gmail })
@gmail = Gmail.new(username, password)
@email = nil
@error_msg = "No email is open!"
end
# Get the last, presumably newest, email matching the params.
def get_last_email(params)
@email = nil
return false unless @gmail
if(params['subject'])
# Search for an email with that subject manually.
email_list = @gmail.inbox.emails(params).to_a
@email = email_list.pop;
@email = email_list.pop while(@email != nil && @email.subject != nil && !@email.subject.to_s.include?(params['subject']))
else
@email = @gmail.inbox.emails(params).to_a.last
end
return false if @email == nil
return true
end
# Get the lone email matching the params, or fail.
def get_email(params)
@email = nil
return false unless @gmail
emails = @gmail.inbox.emails(params)
@error_msg = "No email is open!"
@error_msg = "#{emails.count} matching emails found!" if emails.count > 1
return false unless emails.count == 1
@email = emails.first
return false if @email == nil
return true
end
# Wait for the lone email matching the params, or fail.
def get_email_within_minutes_after(params, minutes, time)
@email = nil
return false unless @gmail
endtime = Time.parse(time) + Integer(minutes)*60
@error_msg = "No email is open!"
loop do
begin
emails = @gmail.inbox.emails(params)
break if(emails.count > 1)
if(emails.count == 1)
@email = emails.first
break
end
rescue
end
break if Time.now > endtime
sleep 60
end
@error_msg = "#{emails.count} matching emails found!" if emails.count > 1
return false if @email == nil
return true
end
# Methods to verify the body field specifically, as it can take some decoding.
[:body].each do |name|
# Literal name returns a string:
define_method(name) do
return @error_msg unless @email
begin
return @email.parts[0].body.decoded.to_s
rescue
return @email.body.decoded.to_s
end
end
# Name with _contains verifies a match in the string, with a regexpi?: if requested.
define_method("#{name}_contains") do |expected|
return false unless @email
begin
mybody = @email.parts[0].body.decoded.to_s
rescue
mybody = @email.body.decoded.to_s
end
mybody.gsub!(/[\s\r\n]+/, ' ')
if expected.sub!(/^regexp:/, '')
return /#{expected}/ === mybody
elsif expected.sub!(/^regexpi:/, '')
return /#{expected}/i === mybody
else
return mybody.include? expected
end
end
# Name with _matching returns a match to a regex from the given string.
# If the regex has capturing group(s), the first capturing group's contents are returned instead of the full match.
define_method("#{name}_matching") do |expected|
return @error_msg unless @email
begin
m = /#{expected}/.match(@email.parts[0].body.decoded.to_s)
rescue
m = /#{expected}/.match(@email.body.decoded.to_s)
end
return (m.length>1)?m[1]:m[0]
end
end
# Create generic methods to verify the following fields:
[:envelope_from, :envelope_date, :from, :to, :cc, :subject, :date, :message_id, :preamble, :epilogue].each do |name|
# Literal name returns a string:
define_method(name) do
return @error_msg unless @email
return @email.send(name).to_s
end
# Name with _contains verifies a match in the string, with a regexpi?: if requested.
define_method("#{name}_contains") do |expected|
return false unless @email
if expected.sub!(/^regexp:/, '')
return /#{expected}/ === @email.send(name).to_s
elsif expected.sub!(/^regexpi:/, '')
return /#{expected}/i === @email.send(name).to_s
else
return @email.send(name).to_s.include? expected
end
end
# Name with _matching returns a match to a regex from the given string.
# If the regex has capturing group(s), the first capturing group's contents are returned instead of the full match.
define_method("#{name}_matching") do |expected|
return @error_msg unless @email
m = /#{expected}/.match(@email.send(name).to_s)
return (m.length>1)?m[1]:m[0]
end
end
end
# The MIT License
#
# Copyright (c) 2012 Automation Excellence
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment