From 05bcde80045b43c0d00de17505e89858cb93029a Mon Sep 17 00:00:00 2001 From: Michael Moen Date: Mon, 22 Feb 2010 15:26:32 -0600 Subject: [PATCH] implement link following from email_spec --- lib/pickle/email.rb | 38 ++++++++++++++++++- .../pickle/templates/email_steps.rb | 8 ++++ spec/lib/pickle_email_spec.rb | 22 +++++++++++ 3 files changed, 67 insertions(+), 1 deletion(-) diff --git a/lib/pickle/email.rb b/lib/pickle/email.rb index af88b193..55b4f8d0 100644 --- a/lib/pickle/email.rb +++ b/lib/pickle/email.rb @@ -18,7 +18,17 @@ def email_has_fields?(email, fields) end true end - + + def visit_in_email(email, link_text) + visit(parse_email_for_link(email, link_text)) + end + + def click_first_link_in_email(email) + link = links_in_email(email).first + request_uri = URI::parse(link).request_uri + visit request_uri + end + protected # Saves the emails out to RAILS_ROOT/tmp/ and opens it in the default # web browser if on OS X. (depends on webrat) @@ -32,5 +42,31 @@ def save_and_open_emails end open_in_browser(filename) end + + def parse_email_for_link(email, 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 Click here + def parse_email_for_anchor_text_link(email, link_text) + email.body =~ %r{]*href=['"]?([^'"]*)['"]?[^>]*?>[^<]*?#{link_text}[^<]*?} + URI.split($~[1])[5..-1].compact!.join("?").gsub("&", "&") + # sub correct ampersand after rails switches it (http://dev.rubyonrails.org/ticket/4002) + end + + def links_in_email(email, protos=['http', 'https']) + URI.extract(email.body, protos) + end + end end \ No newline at end of file diff --git a/rails_generators/pickle/templates/email_steps.rb b/rails_generators/pickle/templates/email_steps.rb index 82cfee5f..172d4a3d 100755 --- a/rails_generators/pickle/templates/email_steps.rb +++ b/rails_generators/pickle/templates/email_steps.rb @@ -18,6 +18,14 @@ emails.size.should == count.to_i end +When(/^(?:I|they) follow "([^"]*?)" in #{capture_email}$/) do |link, email_ref| + visit_in_email(email(email_ref), link) +end + +When(/^(?:I|they) click the first link in #{capture_email}$/) do + click_first_link_in_email(email(email_ref)) +end + Then(/^(\d)+ emails? should be delivered to (.*)$/) do |count, to| emails("to: \"#{email_for(to)}\"").size.should == count.to_i end diff --git a/spec/lib/pickle_email_spec.rb b/spec/lib/pickle_email_spec.rb index cd8c575f..656a9345 100644 --- a/spec/lib/pickle_email_spec.rb +++ b/spec/lib/pickle_email_spec.rb @@ -128,4 +128,26 @@ save_and_open_emails end end + + describe "following links in emails" do + before do + stub!(:open_in_browser) + @email1.stub!(:body).and_return('some text example page more text') + end + + it "should find a link for http://example.com/page" do + should_receive(:visit).with('/page') + visit_in_email(@email1, 'http://example.com/page') + end + + it "should find a link for \"example page\"" do + should_receive(:visit).with('/page') + visit_in_email(@email1, 'example page') + end + + it "should follow the first link in an email" do + should_receive(:visit).with('/page') + click_first_link_in_email(@email1) + end + end end \ No newline at end of file