/vendor/plugins/email-spec/lib/email_spec/helpers.rb
https://github.com/ganders/teambox · Ruby · 160 lines · 126 code · 32 blank · 2 comment · 6 complexity · ea0f2b48b1214d2a46b0261f7b65b95a MD5 · raw file
- require 'uri'
- require 'email_spec/deliveries'
- module EmailSpec
- module Helpers
- include Deliveries
- def visit_in_email(link_text)
- visit(parse_email_for_link(current_email, link_text))
- end
- def click_email_link_matching(regex, email = current_email)
- url = links_in_email(email).detect { |link| link =~ regex }
- raise "No link found matching #{regex.inspect} in #{email.default_part_body}" unless url
- request_uri = URI::parse(url).request_uri
- visit request_uri
- end
- def click_first_link_in_email(email = current_email)
- link = links_in_email(email).first
- request_uri = URI::parse(link).request_uri
- visit request_uri
- end
- def open_email(address, opts={})
- set_current_email(find_email!(address, opts))
- end
- alias_method :open_email_for, :open_email
- def open_last_email
- set_current_email(last_email_sent)
- end
- def open_last_email_for(address)
- set_current_email(mailbox_for(address).last)
- end
- def current_email(address=nil)
- address = convert_address(address)
- email = address ? email_spec_hash[:current_emails][address] : email_spec_hash[:current_email]
- raise RSpec::Expectations::ExpectationNotMetError, "Expected an open email but none was found. Did you forget to call open_email?" unless email
- email
- end
- def current_email_attachments(address=nil)
- current_email(address).attachments || Array.new
- end
- def unread_emails_for(address)
- mailbox_for(address) - read_emails_for(address)
- end
- def read_emails_for(address)
- email_spec_hash[:read_emails][convert_address(address)] ||= []
- end
- def find_email(address, opts={})
- address = convert_address(address)
- if opts[:with_subject]
- mailbox_for(address).find { |m| m.subject =~ Regexp.new(opts[:with_subject]) }
- elsif opts[:with_text]
- mailbox_for(address).find { |m| m.default_part_body =~ Regexp.new(opts[:with_text]) }
- else
- mailbox_for(address).first
- end
- end
- def links_in_email(email)
- URI.extract(email.default_part_body.to_s, ['http', 'https'])
- end
- private
- def email_spec_hash
- @email_spec_hash ||= {:read_emails => {}, :unread_emails => {}, :current_emails => {}, :current_email => nil}
- end
- def find_email!(address, opts={})
- email = find_email(address, opts)
- if email.nil?
- error = "#{opts.keys.first.to_s.humanize unless opts.empty?} #{('"' + opts.values.first.to_s.humanize + '"') unless opts.empty?}"
- raise RSpec::Expectations::ExpectationNotMetError, "Could not find email #{error}. \n Found the following emails:\n\n #{all_emails.to_s}"
- end
- email
- end
- def set_current_email(email)
- return unless email
- [email.to, email.cc, email.bcc].compact.flatten.each do |to|
- read_emails_for(to) << email
- email_spec_hash[:current_emails][to] = email
- end
- email_spec_hash[:current_email] = email
- end
- def parse_email_for_link(email, text_or_regex)
- email.should have_body_text(text_or_regex)
- url = parse_email_for_explicit_link(email, text_or_regex)
- url ||= parse_email_for_anchor_text_link(email, text_or_regex)
- raise "No link found matching #{text_or_regex.inspect} in #{email}" unless url
- url
- end
- # e.g. confirm in http://confirm
- def parse_email_for_explicit_link(email, regex)
- regex = /#{Regexp.escape(regex)}/ unless regex.is_a?(Regexp)
- url = links_in_email(email).detect { |link| link =~ regex }
- URI::parse(url).request_uri if url
- end
- # e.g. Click here in <a href="http://confirm">Click here</a>
- def parse_email_for_anchor_text_link(email, link_text)
- if textify_images(email.default_part_body) =~ %r{<a[^>]*href=['"]?([^'"]*)['"]?[^>]*?>[^<]*?#{link_text}[^<]*?</a>}
- URI.split($1)[5..-1].compact!.join("?").gsub("&", "&")
- # sub correct ampersand after rails switches it (http://dev.rubyonrails.org/ticket/4002)
- else
- return nil
- end
- end
- def textify_images(email_body)
- email_body.to_s.gsub(%r{<img[^>]*alt=['"]?([^'"]*)['"]?[^>]*?/>}) { $1 }
- end
- def parse_email_count(amount)
- case amount
- when "no"
- 0
- when "an"
- 1
- else
- amount.to_i
- end
- end
- attr_reader :last_email_address
- def convert_address(address)
- @last_email_address = (address || current_email_address)
- AddressConverter.instance.convert(@last_email_address)
- end
- def mailbox_for(address)
- super(convert_address(address)) # super resides in Deliveries
- end
- def email_spec_deprecate(text)
- puts ""
- puts "DEPRECATION: #{text.split.join(' ')}"
- puts ""
- end
- end
- end