<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array">
    <added>
      <filename>test/integration/login_test.rb</filename>
    </added>
  </added>
  <modified type="array">
    <modified>
      <diff>@@ -89,6 +89,8 @@ Rails::Initializer.run do |config|
   config.gem 'tzinfo', :version =&gt; '&gt;= 0.3.12'
   config.gem 'emk-safe_erb', :version =&gt; '&gt;= 0.1.2', :lib =&gt; 'safe_erb',
              :source =&gt; 'http://gems.github.com'
+  config.gem 'nokogiri', :version =&gt; '&gt;= 1.1.0' # Used by webrat.
+  config.gem 'webrat', :version =&gt; '&gt;= 0.3.2'
 end
 
 # Don't update this file, make custom tweaks in config/initializers/custom.rb, </diff>
      <filename>config/environment.rb</filename>
    </modified>
    <modified>
      <diff>@@ -27,8 +27,8 @@ User.blueprint do
   email            { Sham.email }
   token            { 'quentintoken' }
   admin            { false }
-  salt             { '7e3041ebc2fc05a40c60028e2c4901a81035d3cd' }
-  crypted_password { '00742970dc9e6319f8019fd54864d3ea740f04b1' } # test
+  password         { 'password' }
+  password_confirmation { 'password' }
 end
 
 Membership.blueprint do</diff>
      <filename>spec/blueprints.rb</filename>
    </modified>
    <modified>
      <diff>@@ -22,7 +22,7 @@ class Admin::OverviewControllerTest &lt; ActionController::TestCase
   def test_should_allow_site_admins_to_access_site
     @user = User.make
     Membership.make :user =&gt; @user, :site =&gt; @site, :admin =&gt; true
-    @request.session[:user] = User.authenticate_for(@site, @user.login, 'test')
+    @request.session[:user] = User.authenticate_for(@site, @user.login, 'password')
 
     get :index
     assert_response :success
@@ -31,7 +31,7 @@ class Admin::OverviewControllerTest &lt; ActionController::TestCase
   def test_should_allow_site_members_to_acces_overview
     @user = User.make
     Membership.make :user =&gt; @user, :site =&gt; @site, :admin =&gt; false
-    @request.session[:user] = User.authenticate_for(@site, @user.login, 'test')
+    @request.session[:user] = User.authenticate_for(@site, @user.login, 'password')
 
     get :index
     assert_response :success
@@ -45,7 +45,7 @@ class Admin::OverviewControllerTest &lt; ActionController::TestCase
   def test_should_allow_http_auth_on_feed
     @user = User.make
     Membership.make :user =&gt; @user, :site =&gt; @site, :admin =&gt; true
-    @request.env['HTTP_AUTHORIZATION'] = &quot;Basic #{Base64.encode64(&quot;#{@user.login}:test&quot;)}&quot;
+    @request.env['HTTP_AUTHORIZATION'] = &quot;Basic #{Base64.encode64(&quot;#{@user.login}:password&quot;)}&quot;
     get :feed
     assert_response :success
   end
@@ -72,7 +72,7 @@ class Admin::OverviewControllerTest &lt; ActionController::TestCase
       Membership.make :user =&gt; @admin, :site =&gt; @site, :admin =&gt; true
     end
 
-    @request.session[:user] = User.authenticate_for(@site, @admin.login, 'test')
+    @request.session[:user] = User.authenticate_for(@site, @admin.login, 'password')
     get :index
     assert assigns(:todays_events).include?(@event1),    &quot;#{assigns(:todays_events).collect(&amp;:id).inspect}&quot;
     assert assigns(:todays_events).include?(@event2),  &quot;#{assigns(:todays_events).collect(&amp;:id).inspect}&quot;</diff>
      <filename>test/functional/admin/overview_controller_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,4 +1,31 @@
 require File.dirname(__FILE__) + '/../test_helper'
+
+# This file is much older than our other integration tests, and it predates
+# our decision to use Webrat.  So we want to keep the code and techniques
+# in this file as isolated as possible from our other integration tests.
+
+class ActionController::Integration::Session
+  def login_as(login)
+    post 'http://test.host/account/login', :login =&gt; login, :password =&gt; 'test'
+    assert request.session[:user]
+    assert redirect?
+  end
+
+  def get_with_basic(url, options = {})
+    get url, nil, 'authorization' =&gt; &quot;Basic #{Base64.encode64(&quot;#{options[:login]}:test&quot;)}&quot;
+  end
+
+  def assert_redirected_to(url)
+    assert redirect?
+    assert_equal url, interpret_uri(headers[&quot;location&quot;].first)
+  end
+
+  def assert_redirected_to!(url)
+    assert_redirected_to(url)
+    follow_redirect!
+  end
+end
+
 class CachingTest &lt; ActionController::IntegrationTest
   fixtures :contents, :users, :sections, :assigned_sections, :sites
 
@@ -8,7 +35,7 @@ class CachingTest &lt; ActionController::IntegrationTest
   end
 
   def test_should_expire_necessary_feeds_and_sections_when_publishing_article
-    visitor = visit
+    visitor = visit_with_session
     writer  = login_as :quentin
     
     visit_sections_and_feeds_with visitor
@@ -25,7 +52,7 @@ class CachingTest &lt; ActionController::IntegrationTest
   end
 
   def test_should_expire_feeds_and_sections_when_publishing_article
-    visitor = visit
+    visitor = visit_with_session
     writer  = login_as :quentin
     
     visit_sections_and_feeds_with visitor
@@ -39,7 +66,7 @@ class CachingTest &lt; ActionController::IntegrationTest
   end
 
   def test_should_only_expire_overview_when_creating_draft
-    visitor = visit
+    visitor = visit_with_session
     writer  = login_as :quentin
     
     visit_sections_and_feeds_with visitor
@@ -61,7 +88,7 @@ class CachingTest &lt; ActionController::IntegrationTest
   end
 
   def test_should_only_expire_overview_when_revising_draft
-    visitor = visit
+    visitor = visit_with_session
     writer  = login_as :quentin
     
     visit_sections_and_feeds_with visitor
@@ -82,7 +109,7 @@ class CachingTest &lt; ActionController::IntegrationTest
 
   def test_should_expire_sections_when_publishing_draft
     AssignedSection.delete_all 'id &gt; 9'
-    visitor = visit
+    visitor = visit_with_session
     writer  = login_as :quentin
     
     visit_sections_and_feeds_with visitor
@@ -100,7 +127,7 @@ class CachingTest &lt; ActionController::IntegrationTest
   end
 
   def test_should_expire_articles_after_editing
-    visitor = visit
+    visitor = visit_with_session
     writer  = login_as :quentin
     
     assert_caches_page contents(:welcome).full_permalink do
@@ -128,7 +155,7 @@ class CachingTest &lt; ActionController::IntegrationTest
   end
 
   def test_should_cache_and_expire_overview_feed_on_edited_article
-    rss     = visit
+    rss     = visit_with_session
     writer  = login_as :quentin
 
     assert_caches_page overview_path do
@@ -141,7 +168,7 @@ class CachingTest &lt; ActionController::IntegrationTest
   end
 
   def test_should_not_expire_cache_on_new_comment
-    visitor = visit
+    visitor = visit_with_session
     assert_caches_page contents(:welcome).full_permalink do
       visitor.read contents(:welcome)
     end
@@ -152,14 +179,14 @@ class CachingTest &lt; ActionController::IntegrationTest
   end
 
   def test_should_not_cache_comment_post
-    visitor = visit
+    visitor = visit_with_session
     assert_expires_pages &quot;#{contents(:welcome).full_permalink}/comments&quot; do
       visitor.comment_on contents(:welcome), :author =&gt; 'bob', :body =&gt; 'what a wonderful post.'
     end
   end
 
   def test_should_not_cache_comment_post_on_article_with_closed_comments
-    visitor = visit
+    visitor = visit_with_session
     contents(:welcome).update_attribute :comment_age, -1
     assert_expires_pages &quot;#{contents(:welcome).full_permalink}/comments&quot; do
       visitor.comment_on contents(:welcome), :author =&gt; 'bob', :body =&gt; 'what a wonderful post.'
@@ -167,7 +194,7 @@ class CachingTest &lt; ActionController::IntegrationTest
   end
 
   def test_should_not_cache_comment_post_on_article_with_invalid_comment
-    visitor = visit
+    visitor = visit_with_session
     assert_expires_pages &quot;#{contents(:welcome).full_permalink}/comments&quot; do
       assert_no_difference Comment, :count do
         visitor.comment_on contents(:welcome), {}
@@ -176,14 +203,14 @@ class CachingTest &lt; ActionController::IntegrationTest
   end
 
   def test_should_not_cache_comments_page_on_get
-    visitor = visit
+    visitor = visit_with_session
     assert_expires_pages &quot;#{contents(:welcome).full_permalink}/comments&quot; do
       visitor.get &quot;#{contents(:welcome).full_permalink}/comments&quot;
     end
   end
 
   def test_should_expire_cache_on_new_comment_if_approved
-    visitor = visit
+    visitor = visit_with_session
     assert_caches_page contents(:welcome).full_permalink do
       visitor.read contents(:welcome)
     end
@@ -198,7 +225,7 @@ class CachingTest &lt; ActionController::IntegrationTest
   end
 
   def test_should_expire_cache_when_comment_is_approved
-    visitor = visit
+    visitor = visit_with_session
     assert_caches_page contents(:welcome).full_permalink do
       visitor.read contents(:welcome)
     end
@@ -212,7 +239,7 @@ class CachingTest &lt; ActionController::IntegrationTest
   end
 
   def test_should_expire_cache_when_comment_is_unapproved
-    visitor = visit
+    visitor = visit_with_session
     assert_caches_page contents(:welcome).full_permalink do
       visitor.read contents(:welcome)
     end
@@ -226,8 +253,8 @@ class CachingTest &lt; ActionController::IntegrationTest
   end
 
   def test_should_expire_cache_when_approved_comment_is_deleted
-    visitor = visit
-    rss     = visit
+    visitor = visit_with_session
+    rss     = visit_with_session
     writer  = login_as :quentin
     assert_caches_page contents(:welcome).full_permalink do
       visitor.read contents(:welcome)
@@ -243,8 +270,8 @@ class CachingTest &lt; ActionController::IntegrationTest
   end
 
   def test_should_only_expire_overview_when_unapproved_comment_is_deleted
-    visitor = visit
-    rss     = visit
+    visitor = visit_with_session
+    rss     = visit_with_session
     writer  = login_as :quentin
     assert_caches_page contents(:welcome).full_permalink do
       visitor.read contents(:welcome)
@@ -263,7 +290,7 @@ class CachingTest &lt; ActionController::IntegrationTest
   end
 
   def test_should_not_cache_bad_urls
-    visitor = visit
+    visitor = visit_with_session
     pages   = ['/about/blah', '/foo/bar', '2006/1/2/fasd']
     assert_no_difference CachedPage, :count do
       assert_expires_pages *pages do
@@ -273,7 +300,7 @@ class CachingTest &lt; ActionController::IntegrationTest
   end
 
   def test_should_expire_section_cache_when_updating_section
-    visitor = visit
+    visitor = visit_with_session
     assert_caches_page section_url_for(:about) do
       visitor.read sections(:about)
     end
@@ -294,7 +321,7 @@ class CachingTest &lt; ActionController::IntegrationTest
   end
 
   def test_should_expire_cache_when_updating_template
-    visit_sections_and_feeds_with visit
+    visit_sections_and_feeds_with visit_with_session
     assert_expires_pages section_url_for(:home), section_url_for(:about), feed_url_for(:home), feed_url_for(:about) do
       login_as :quentin do |writer|
         writer.update_template sites(:first).templates[:error], '&lt;p&gt;error!&lt;/p&gt;'
@@ -303,7 +330,7 @@ class CachingTest &lt; ActionController::IntegrationTest
   end
 
   def test_should_expire_new_assigned_section_to_article
-    visitor = visit
+    visitor = visit_with_session
     writer  = login_as :quentin
     visit_sections_and_feeds_with visitor
     assert_expires_pages feed_url_for(:about), section_url_for(:about) do
@@ -319,7 +346,7 @@ class CachingTest &lt; ActionController::IntegrationTest
   end
 
   def test_should_expire_section_when_removing_from_article
-    visit_sections_and_feeds_with visit
+    visit_sections_and_feeds_with visit_with_session
     assert_expires_pages section_url_for(:home), section_url_for(:about), feed_url_for(:home), feed_url_for(:about) do
       login_as :quentin do |writer|
         writer.revise contents(:site_map), :sections =&gt; [sections(:home)]
@@ -328,7 +355,7 @@ class CachingTest &lt; ActionController::IntegrationTest
   end
 
   def test_should_expire_section_and_article_cache_when_deleting_article
-    visitor = visit
+    visitor = visit_with_session
     
     visit_sections_and_feeds_with visitor
     visitor.read contents(:site_map)
@@ -344,7 +371,7 @@ class CachingTest &lt; ActionController::IntegrationTest
   end
 
   def test_should_expire_resource_when_updating_resource
-    visitor = visit
+    visitor = visit_with_session
     assert_caches_page '/images/rails-logo.png' do
       visitor.read '/images/rails-logo.png'
     end
@@ -357,7 +384,7 @@ class CachingTest &lt; ActionController::IntegrationTest
   end
 
   def test_should_expire_resource_when_removing_resource
-    visitor = visit
+    visitor = visit_with_session
     assert_caches_page '/images/rails-logo.png' do
       visitor.read '/images/rails-logo.png'
     end
@@ -372,7 +399,7 @@ class CachingTest &lt; ActionController::IntegrationTest
   # TODO test_should_expire_resource_when_uploading_resource
 
   def test_should_not_cache_searches
-    visitor = visit
+    visitor = visit_with_session
     assert_expires_page &quot;/search&quot; do
       visitor.get  '/search'
       visitor.get  '/search', :q =&gt; 'foo'
@@ -382,7 +409,7 @@ class CachingTest &lt; ActionController::IntegrationTest
 
   def test_should_not_cache_denied_route
     assert_expires_page '/limited_deny' do
-      visit { |v| v.get '/limited_deny' }
+      visit_with_session { |v| v.get '/limited_deny' }
     end
     
     assert_not_cached '/limited_deny'
@@ -390,7 +417,7 @@ class CachingTest &lt; ActionController::IntegrationTest
 
   def test_should_not_cache_redirected_route
     assert_expires_page '/redirect/external' do
-      visit do |v| 
+      visit_with_session do |v| 
         v.get '/redirect/external'
         assert v.redirect?
         assert_equal 'http://external', v.headers[&quot;location&quot;].first
@@ -399,6 +426,33 @@ class CachingTest &lt; ActionController::IntegrationTest
   end
 
   protected
+    include Mephisto::Caching::ReferencedCachingTestHelper
+  
+    # creates a session as a logged on user
+    def login_as(login)
+      visit_with_session do |sess|
+        sess.login_as login
+        yield sess if block_given?
+      end
+    end
+
+    # creates an anonymous session
+    def visit_with_session
+      open_session do |sess|
+        sess.host = 'test.host'
+        sess.extend Mephisto::Integration::Actor
+        yield sess if block_given?
+      end
+    end
+
+    def section_url_for(section, article = nil)
+      (article ? sections(section).to_page_url(contents(article)) : sections(section).to_url) * '/'
+    end
+
+    def feed_url_for(section)
+      &quot;/feed/#{sections(section).to_feed_url * '/'}&quot;
+    end
+
     def visit_sections_and_feeds_with(visitor)
       assert_difference CachedPage, :count, 4 do
         assert_caches_page section_url_for(:home) do</diff>
      <filename>test/integration/caching_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -250,57 +250,6 @@ class Test::Unit::TestCase
   end
 end
 
-class ActionController::IntegrationTest
-  include Mephisto::Caching::ReferencedCachingTestHelper
-  
-  # creates a session as a logged on user
-  def login_as(login)
-    visit do |sess|
-      sess.login_as login
-      yield sess if block_given?
-    end
-  end
-
-  # creates an anonymous session
-  def visit
-    open_session do |sess|
-      sess.host = 'test.host'
-      sess.extend Mephisto::Integration::Actor
-      yield sess if block_given?
-    end
-  end
-
-  def section_url_for(section, article = nil)
-    (article ? sections(section).to_page_url(contents(article)) : sections(section).to_url) * '/'
-  end
-
-  def feed_url_for(section)
-    &quot;/feed/#{sections(section).to_feed_url * '/'}&quot;
-  end
-end
-
-class ActionController::Integration::Session
-  def login_as(login)
-    post 'http://test.host/account/login', :login =&gt; login, :password =&gt; 'test'
-    assert request.session[:user]
-    assert redirect?
-  end
-
-  def get_with_basic(url, options = {})
-    get url, nil, 'authorization' =&gt; &quot;Basic #{Base64.encode64(&quot;#{options[:login]}:test&quot;)}&quot;
-  end
-
-  def assert_redirected_to(url)
-    assert redirect?
-    assert_equal url, interpret_uri(headers[&quot;location&quot;].first)
-  end
-
-  def assert_redirected_to!(url)
-    assert_redirected_to(url)
-    follow_redirect!
-  end
-end
-
 class BaseLoginProxy
   attr_reader :controller
   attr_reader :options</diff>
      <filename>test/test_helper.rb</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>959f82884ee0e40641ca6ae83cc1d6cd6f0edfdb</id>
    </parent>
  </parents>
  <author>
    <name>Eric Kidd</name>
    <email>git@randomhacks.net</email>
  </author>
  <url>http://github.com/halorgium/mephisto/commit/d40725ed3da1b17ea5db51197d9f520bbde62bbb</url>
  <id>d40725ed3da1b17ea5db51197d9f520bbde62bbb</id>
  <committed-date>2008-12-27T06:08:38-08:00</committed-date>
  <authored-date>2008-12-27T06:08:19-08:00</authored-date>
  <message>Write login integration tests using Webrat

Why do we need integration tests? We've been suffering a lot of
regressions in the Mephisto UI, because our functional tests don't reach
high enough up towards the browser, and whole classes of bugs manage to
slip through.

What is Webrat? Webrat is a &quot;browser simulator&quot; written in Ruby.  It
generates a DOM and allows us to fill in forms as though an actual user
were interacting with the site.

Why Webrat, and not Selenium, Watir, etc?  Webrat is recommended by the
Cucumber project as the default way to write user stories; it's very
fast; and it has a reasonable API.  Plus, Webrat actively maintained,
and very recent versions of Webrat can be used as a front-end to
Selenium.

Why Rails integration tests, and not Cucumber stories?  Since the people
contributing to Mephisto will largely be programmers, I decided to write
integration tests using a Ruby-based DSL.  Cucumber stories look really
interesting, but with no actual clients in the loop, the text-based format
is slightly less useful and has a steeper learning curve for programmers.

Since we're switching to a new integration testing tool, I moved a bunch of
code out of test_helper.rb and put it into our only existing integration
test, caching_test.rb.  I also switched blueprints.rb to set up user
passwords using 'password' and 'password_confirm' (instead of crypted and
salted values) to make it easier for tests to override</message>
  <tree>fcb88ae106f916a1f4f1b871ae22885e44519b33</tree>
  <committer>
    <name>Eric Kidd</name>
    <email>git@randomhacks.net</email>
  </committer>
</commit>
