<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array">
    <added>
      <filename>test/builders.rb</filename>
    </added>
    <added>
      <filename>vendor/plugins/activerecord_cache_validators/MIT-LICENSE</filename>
    </added>
    <added>
      <filename>vendor/plugins/activerecord_cache_validators/README</filename>
    </added>
    <added>
      <filename>vendor/plugins/activerecord_cache_validators/Rakefile</filename>
    </added>
    <added>
      <filename>vendor/plugins/activerecord_cache_validators/init.rb</filename>
    </added>
    <added>
      <filename>vendor/plugins/activerecord_cache_validators/install.rb</filename>
    </added>
    <added>
      <filename>vendor/plugins/activerecord_cache_validators/lib/active_record/cache_validators.rb</filename>
    </added>
    <added>
      <filename>vendor/plugins/activerecord_cache_validators/tasks/activerecord_cache_validators_tasks.rake</filename>
    </added>
    <added>
      <filename>vendor/plugins/activerecord_cache_validators/test/activerecord_cache_validators_test.rb</filename>
    </added>
    <added>
      <filename>vendor/plugins/activerecord_cache_validators/test/test_helper.rb</filename>
    </added>
    <added>
      <filename>vendor/plugins/activerecord_cache_validators/uninstall.rb</filename>
    </added>
  </added>
  <modified type="array">
    <modified>
      <diff>@@ -76,7 +76,7 @@ class Admin::PostsController &lt; ApplicationController
         format.js   { render :json =&gt; @post }
         format.xml  { head :ok }        
       else
-        format.html { render :action =&gt; &quot;edit&quot; }
+        format.html { render :template =&gt; 'admin/posts/edit.html.erb' }
         format.js   { render :text =&gt; 'fail', :status =&gt; :unprocessable_entity }
         format.xml  { render :xml =&gt; @post.errors, :status =&gt; :unprocessable_entity }
       end</diff>
      <filename>app/controllers/admin/posts_controller.rb</filename>
    </modified>
    <modified>
      <diff>@@ -12,7 +12,14 @@ class PostsController &lt; ApplicationController
   # GET /posts
   # GET /posts.xml
   def index
+    if fresh_when \
+      :etag =&gt; (post_repo.etag || 'empty'),
+      :last_modified =&gt; post_repo.last_modified.utc
+      return
+    end
+    
     @posts = post_repo.paginate_index(:page =&gt; params[:page])
+    
     respond_to do |format|
       format.html { render :template =&gt; 'posts/index.html.erb' }
       format.rss  { render :template =&gt; 'posts/index.rss.builder' }</diff>
      <filename>app/controllers/posts_controller.rb</filename>
    </modified>
    <modified>
      <diff>@@ -7,8 +7,7 @@ class Post &lt; ActiveRecord::Base
   has_many :comments, :as =&gt; :commentable, :conditions =&gt; ['comments.spam = ?', false]
 
   validates_uniqueness_of :permalink, :scope =&gt; :type
-  validates_presence_of :user_id, :unless =&gt; :feed_id
-  validates_presence_of :feed_id, :unless =&gt; :user_id
+  validates_presence_of :source
   
   before_save :mark_uncommentable, :if =&gt; :from_feed?
   
@@ -19,13 +18,25 @@ class Post &lt; ActiveRecord::Base
   end
   
   def self.per_page; 10; end
+  
+  def source
+    @source ||= user || feed
+  end
+  
+  def source=(new_source)
+    self.user = self.feed = nil
+    @source = case new_source
+    when User then self.user = new_source
+    when Feed then self.feed = new_source
+    end
+  end
 
   def name
     header
   end
   
   def from_feed?
-    !!feed_id &amp;&amp; (feed_id != 0)
+    !feed.nil?
   end
   
   def type
@@ -55,7 +66,11 @@ class Post &lt; ActiveRecord::Base
     else RedCloth.new(content, [:filter_styles, :no_span_caps]).to_html
     end
   end
-  
+
+  def has_user?
+    !!user
+  end
+
   private
   
   def mark_uncommentable</diff>
      <filename>app/models/post.rb</filename>
    </modified>
    <modified>
      <diff>@@ -2,7 +2,7 @@ class Article &lt; Post
   acts_as_defensio_article :fields =&gt; { :author =&gt; :source, :title =&gt; :header } if SITE_SETTINGS[:use_defensio]
   
   # We don't want to generate permalinks for imported posts
-  has_permalink :header, :if =&gt; :user_id
+  has_permalink :header, :unless =&gt; :from_feed?
 
   validates_presence_of :header, :content
   validates_uniqueness_of :permalink
@@ -17,10 +17,6 @@ class Article &lt; Post
     source.try(:email) || SITE_SETTINGS['user_email']
   end
   
-  def source
-    user || feed
-  end
-  
   def name
     header
   end</diff>
      <filename>app/models/posts/article.rb</filename>
    </modified>
    <modified>
      <diff>@@ -6,7 +6,7 @@ one:
   content: My _Italic_ Text
   cite: My String
   type: Article
-  user_id: 1
+  user: quentin
   comment_counter: 1
 
 two:
@@ -15,7 +15,7 @@ two:
   content: MyText
   cite: A link
   type: Link
-  user_id: 1
+  user: quentin
   lang: MyString
   comment_counter: 1
   
@@ -41,4 +41,4 @@ snippet:
   content: console.info('duh')
   lang: Javascript
   type: Snippet
-  user: quentin
\ No newline at end of file
+  user: quentin</diff>
      <filename>test/fixtures/posts.yml</filename>
    </modified>
    <modified>
      <diff>@@ -1,5 +1,4 @@
 quentin:
-  id: 1
   name: quentin
   email: quentin@example.com
   salt: 7e3041ebc2fc05a40c60028e2c4901a81035d3cd
@@ -9,7 +8,6 @@ quentin:
 
 
 aaron:
-  id: 2
   name: aaron
   email: aaron@example.com
   salt: 7e3041ebc2fc05a40c60028e2c4901a81035d3cd</diff>
      <filename>test/fixtures/users.yml</filename>
    </modified>
    <modified>
      <diff>@@ -10,12 +10,23 @@ class PostsControllerTest &lt; ActionController::TestCase
     assert_not_nil assigns(:posts)
   end
   
+  test &quot;should provide etag for index&quot; do
+    get :index
+    assert_not_nil @response.etag
+  end
+  
+  test &quot;should provide last_modified for index&quot; do
+    @newest = create_article
+    get :index
+    assert_equal @newest.updated_at.to_s, @response.last_modified.to_s
+  end
+  
   test &quot;should_get_show&quot; do
     get :show, :id =&gt; posts(:one).permalink
     assert_response :success
   end
   
-  test &quot;should provide etag&quot; do
+  test &quot;should provide etag for show&quot; do
     get :show, :id =&gt; posts(:one).permalink
     assert_not_nil @response.etag
   end</diff>
      <filename>test/functional/posts_controller_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -30,11 +30,14 @@ class UsersControllerTest &lt; ActionController::TestCase
       assert_redirected_to root_path
     end
   end
+  
+  def do_post
+    post :create, :user =&gt; { :name =&gt; 'q', :email =&gt; 'q@e.edu', :password =&gt; 'hello', :password_confirmation =&gt; 'hello' }
+  end
 
   def test_should_allow_signup
     assert_difference 'User.count' do
-      create_user
-      assert_response :redirect
+      do_post
       assert_redirected_to root_path
     end
   end
@@ -42,41 +45,9 @@ class UsersControllerTest &lt; ActionController::TestCase
   def test_should_allow_signup_when_relative_url
     set_relative_url do
       assert_difference 'User.count' do
-        create_user
-        assert_response :redirect
+        do_post
         assert_redirected_to root_path
       end
     end
   end
-
-  def test_should_require_password_on_signup
-    assert_no_difference 'User.count' do
-      create_user(:password =&gt; nil)
-      assert assigns(:user).errors.on(:password)
-      assert_response :success
-    end
-  end
-
-  def test_should_require_password_confirmation_on_signup
-    assert_no_difference 'User.count' do
-      create_user(:password_confirmation =&gt; nil)
-      assert assigns(:user).errors.on(:password_confirmation)
-      assert_response :success
-    end
-  end
-
-  def test_should_require_email_on_signup
-    assert_no_difference 'User.count' do
-      create_user(:email =&gt; nil)
-      assert assigns(:user).errors.on(:email)
-      assert_response :success
-    end
-  end
-  
-
-  protected
-    def create_user(options = {})
-      post :create, :user =&gt; { :email =&gt; 'quire@example.com', :name =&gt; 'quire',
-        :password =&gt; 'quire', :password_confirmation =&gt; 'quire' }.merge(options)
-    end
 end</diff>
      <filename>test/functional/users_controller_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -3,6 +3,8 @@ ENV[&quot;RAILS_ENV&quot;] = &quot;test&quot;
 require File.expand_path(File.dirname(__FILE__) + &quot;/../config/environment&quot;)
 require 'test_help'
 require 'mocha'
+require 'fixjour'
+require File.join(File.dirname(__FILE__), *%w[builders])
 begin
   require 'redgreen'
 rescue LoadError
@@ -10,38 +12,12 @@ rescue LoadError
 end
 
 class ActiveSupport::TestCase
-  # Transactional fixtures accelerate your tests by wrapping each test method
-  # in a transaction that's rolled back on completion.  This ensures that the
-  # test database remains unchanged so your fixtures don't have to be reloaded
-  # between every test method.  Fewer database queries means faster tests.
-  #
-  # Read Mike Clark's excellent walkthrough at
-  #   http://clarkware.com/cgi/blosxom/2005/10/24#Rails10FastTesting
-  #
-  # Every Active Record database supports transactions except MyISAM tables
-  # in MySQL.  Turn off transactional fixtures in this case; however, if you
-  # don't care one way or the other, switching from MyISAM to InnoDB tables
-  # is recommended.
-  #
-  # The only drawback to using transactional fixtures is when you actually 
-  # need to test transactions.  Since your test is bracketed by a transaction,
-  # any transactions started in your code will be automatically rolled back.
   self.use_transactional_fixtures = true
-
-  # Instantiated fixtures are slow, but give you @david where otherwise you
-  # would need people(:david).  If you don't want to migrate your existing
-  # test cases which use the @david style and don't mind the speed hit (each
-  # instantiated fixtures translates to a database query per test method),
-  # then set this back to true.
   self.use_instantiated_fixtures  = false
 
-  # Setup all fixtures in test/fixtures/*.(yml|csv) for all tests in alphabetical order.
-  #
-  # Note: You'll currently still have to declare fixtures explicitly in integration tests
-  # -- they do not yet inherit this setting
   fixtures :all
-  
-  # Add more helper methods to be used by all tests here...
+
+  include Fixjour
   include AuthenticatedTestHelper
 
   #</diff>
      <filename>test/test_helper.rb</filename>
    </modified>
    <modified>
      <diff>@@ -9,37 +9,23 @@ class ArticleTest &lt; ActiveSupport::TestCase
   end
   
   def test_should_require_header
-    assert_no_difference 'Article.count' do
-      article = create_article( :header =&gt; nil )
-      assert ! article.valid?, article.to_yaml
-    end
+    article = new_article(:header =&gt; nil)
+    assert ! article.valid?
+    assert_not_nil article.errors.on(:header)
   end
   
   def test_should_require_content
-    assert_no_difference 'Article.count' do
-      article = create_article( :content =&gt; nil )
-      assert ! article.valid?, article.to_yaml
-    end
+    article = new_article(:content =&gt; nil)
+    assert ! article.valid?
+    assert_not_nil article.errors.on(:content)
   end
   
   def test_should_generate_permalink
-    article = create_article
+    article = new_article(:source =&gt; new_user)
+    assert article.valid?
     assert_not_nil article.permalink
   end
   
-  def test_should_have_from_feed_boolean_helper
-    article = create_article
-    assert ! article.from_feed?
-    article.user_id = nil
-    article.feed_id = feeds(:one).id
-    assert article.from_feed?
-  end
-  
-  def test_should_disallow_comments
-    article = create_article :allow_comments =&gt; '0'
-    assert ! article.allow_comments?, &quot;Allowed comments&quot;
-  end
-  
   def test_should_provide_proper_link
     article = posts(:article).becomes(Article)
     assert_equal &quot;/articles/#{article.permalink}&quot;, article.link
@@ -51,10 +37,4 @@ class ArticleTest &lt; ActiveSupport::TestCase
       assert_equal &quot;/relative/articles/#{article.permalink}&quot;, article.link
     end
   end
-  
-protected
-
-  def create_article(options={})
-    users(:quentin).articles.create({ :header =&gt; 'A Title', :content =&gt; 'Some content' }.merge(options))
-  end
 end</diff>
      <filename>test/unit/article_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -9,15 +9,15 @@ class FeedTest &lt; ActiveSupport::TestCase
   end
   
   def test_should_require_uri
-    assert_no_difference 'Feed.count' do
-      feed = create_feed( :uri =&gt; nil )
-    end
+    feed = new_feed(:uri =&gt; nil)
+    assert ! feed.valid?
+    assert_not_nil feed.errors.on(:uri)
   end
   
   def test_should_require_valid_uri
-    assert_no_difference 'Feed.count' do
-      feed = create_feed( :uri =&gt; 'well this cant work' )
-    end
+    feed = new_feed(:uri =&gt; 'bliggety')
+    assert ! feed.valid?
+    assert_not_nil feed.errors.on(:uri)
   end
   
   def test_should_learn_title
@@ -51,10 +51,6 @@ class FeedTest &lt; ActiveSupport::TestCase
   end
 
 protected
-
-  def create_feed(options={})
-    Feed.create({ :uri =&gt; &quot;file://#{MOCK_ROOT}/daringfireball.xml&quot; }.merge(options))
-  end
   
   def teach_feed(feed)
     feed.learn_attributes!</diff>
      <filename>test/unit/feed_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -8,36 +8,32 @@ class PostTest &lt; ActiveSupport::TestCase
     end
   end
   
-  def test_should_require_user_id_sans_feed_id
-    assert_no_difference 'Post.count' do
-      post = create_post({ :user_id =&gt; nil, :feed_id =&gt; nil })
-    end
+  def test_should_require_source
+    post = new_post(:user =&gt; nil, :feed =&gt; nil)
+    assert ! post.valid?
+    assert_not_nil post.errors.on(:source)
   end
   
-  def test_should_create_with_only_user_id
-    assert_difference 'Post.count' do
-      post = create_post( :feed_id =&gt; nil )
-    end
+  def test_should_create_with_only_user
+    assert new_post(:user =&gt; new_user).valid?
   end
   
   def test_should_create_with_only_feed_id
-    assert_difference 'Post.count' do
-      post = create_post( :user_id =&gt; nil )
-    end
+    assert new_post(:feed =&gt; new_feed).valid?
   end
   
   def test_should_override_to_param_as_permalink_for_non_feeds
-    post = create_post :feed_id =&gt; nil
+    post = create_post :feed =&gt; nil, :user =&gt; new_user
     assert_equal post.permalink, post.to_param
   end
   
   def test_should_override_to_param_as_id_for_feeds
-    post = create_post :feed_id =&gt; 1
+    post = create_post :feed =&gt; new_feed
     assert_equal post.id.to_s, post.to_param
   end
   
   def test_not_allow_comments_if_from_feed
-    post = create_post :feed_id =&gt; 1
+    post = create_post :feed =&gt; new_feed
     assert ! post.allow_comments?
   end
 
@@ -75,15 +71,9 @@ really a problem?
     assert_equal 1, h.search('h1').size
     assert_equal 2, h.search('p').size
 
-    assert post = create_post(:content =&gt; content, :format =&gt; 'RedCloth')
+    assert post = create_article(:content =&gt; content, :format =&gt; 'RedCloth')
     assert h = Hpricot.parse(post.to_html)
     assert_equal 1, h.search('h1').size
     assert_equal 2, h.search('p').size
   end
-
-protected
-
-  def create_post(options={})
-    Post.create({ :header =&gt; 'A name', :content =&gt; 'Some content', :user_id =&gt; users(:quentin).id, :feed_id =&gt; feeds(:one).id, :permalink =&gt; 'ok' }.merge(options))
-  end
 end</diff>
      <filename>test/unit/post_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -3,10 +3,9 @@ require File.dirname(__FILE__) + '/../test_helper'
 class UserTest &lt; ActiveSupport::TestCase
 
   def test_should_require_name
-    assert_no_difference 'User.count' do
-      u = create_user(:name =&gt; nil)
-      assert u.errors.on(:name)
-    end
+    user = new_user(:name =&gt; nil)
+    assert ! user.valid?
+    assert_not_nil user.errors.on(:name)
   end
 
   # Plugin tests
@@ -19,24 +18,21 @@ class UserTest &lt; ActiveSupport::TestCase
   end
 
   def test_should_require_password
-    assert_no_difference 'User.count' do
-      u = create_user(:password =&gt; nil)
-      assert u.errors.on(:password)
-    end
+    user = new_user(:password =&gt; nil)
+    assert ! user.valid?
+    assert_not_nil user.errors.on(:password)
   end
 
   def test_should_require_password_confirmation
-    assert_no_difference 'User.count' do
-      u = create_user(:password_confirmation =&gt; nil)
-      assert u.errors.on(:password_confirmation)
-    end
+    user = new_user(:password_confirmation =&gt; nil)
+    assert ! user.valid?
+    assert_not_nil user.errors.on(:password_confirmation)
   end
 
   def test_should_require_email
-    assert_no_difference 'User.count' do
-      u = create_user(:email =&gt; nil)
-      assert u.errors.on(:email)
-    end
+    user = new_user(:email =&gt; nil)
+    assert ! user.valid?
+    assert_not_nil user.errors.on(:email)
   end
 
   def test_should_reset_password
@@ -91,9 +87,4 @@ class UserTest &lt; ActiveSupport::TestCase
     assert_not_nil users(:quentin).remember_token_expires_at
     assert users(:quentin).remember_token_expires_at.between?(before, after)
   end
-
-protected
-  def create_user(options = {})
-    User.create({ :name =&gt; 'quire', :email =&gt; 'quire@example.com', :password =&gt; 'quire', :password_confirmation =&gt; 'quire' }.merge(options))
-  end
 end</diff>
      <filename>test/unit/user_test.rb</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>b4554abaf727f7ae8bf63b19c977a5d8f2549689</id>
    </parent>
  </parents>
  <author>
    <name>Pat Nakajima</name>
    <email>patnakajima@gmail.com</email>
  </author>
  <url>http://github.com/nakajima/aintablog/commit/c5e2a849ca9c2521851d6fe8184aca93679fdab9</url>
  <id>c5e2a849ca9c2521851d6fe8184aca93679fdab9</id>
  <committed-date>2009-02-08T11:06:06-08:00</committed-date>
  <authored-date>2009-02-08T11:06:06-08:00</authored-date>
  <message>Big commit.

- Added etag for PostsController #index and #show actions
- Added last_modified for PostsController#index
- Introduced Fixjour into the tests
- Cleaned up a lot of logic
- Added a cache_validators plugin to simplify things</message>
  <tree>6d2fe37d12916e16c0253bbd761d30c1e94ac6d7</tree>
  <committer>
    <name>Pat Nakajima</name>
    <email>patnakajima@gmail.com</email>
  </committer>
</commit>
