<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array">
    <added>
      <filename>spec/controllers/admin/articles_spec.rb</filename>
    </added>
    <added>
      <filename>spec/controllers/admin/plugins_spec.rb</filename>
    </added>
    <added>
      <filename>spec/controllers/admin/sessions_spec.rb</filename>
    </added>
    <added>
      <filename>spec/controllers/admin/users_spec.rb</filename>
    </added>
    <added>
      <filename>spec/helpers/admin/articles_helper_spec.rb</filename>
    </added>
    <added>
      <filename>spec/helpers/admin/plugins_helper_spec.rb</filename>
    </added>
    <added>
      <filename>spec/helpers/admin/sessions_helper_spec.rb</filename>
    </added>
    <added>
      <filename>spec/helpers/admin/users_helper_spec.rb</filename>
    </added>
  </added>
  <modified type="array">
    <modified>
      <diff>@@ -14,7 +14,7 @@ $RAKE_ENV = true
 
 init_file = File.join(File.dirname(__FILE__) / &quot;config&quot; / &quot;init&quot;)
 
-Merb.load_dependencies(init_file)
+#Merb.load_dependencies(init_file)
 
 include FileUtils
 # # # Get Merb plugins and dependencies</diff>
      <filename>Rakefile</filename>
    </modified>
    <modified>
      <diff>@@ -1,10 +1,9 @@
 module Admin
   class Articles &lt; Base
-
     before :find_article, :only =&gt; %w(edit update delete show)
 
     def index
-      @articles = Article.all(:order =&gt; 'created_at DESC')
+      @articles = Article.all(:order =&gt; &quot;created_at DESC&quot;)
       display @articles
     end
     
@@ -21,8 +20,13 @@ module Admin
       @article = Article.new(article)
       @article.user_id = self.current_user.id
       if @article.save
+        # Expire the article index to reflect the newly published article
         expire_index if @article.published
-        redirect url(:admin_articles)
+        render_then_call(redirect(url(:admin_articles))) do
+          # Call events after the redirect
+          Hooks::Events.after_publish_article_request(@article, request) if @article.is_published?
+          Hooks::Events.after_create_article_request(@article, request)
+        end
       else
         render :new
       end
@@ -34,9 +38,14 @@ module Admin
     
     def update(article)
       if @article.update_attributes(article)
+        # Expire the index and article to reflect the updated article
         expire_index
         expire_article(@article)
-        redirect url(:admin_article, @article)
+        render_then_call(redirect(url(:admin_article, @article))) do
+          # Call events after the redirect
+          Hooks::Events.after_publish_article_request(@article, request) if @article.is_published?
+          Hooks::Events.after_update_article_request(@article, request)
+        end
       else
         render :edit
       end
@@ -44,6 +53,7 @@ module Admin
     
     def delete
       @article.destroy!
+      # Expire the index and article to reflect the removal of the article
       expire_index
       expire_article(@article)
       redirect url(:admin_articles)
@@ -54,5 +64,4 @@ module Admin
         @article = Article[params[:id]]
       end
   end
-  
 end
\ No newline at end of file</diff>
      <filename>app/controllers/admin/articles.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,22 +1,25 @@
 module Admin
-  class Configurations &lt; Base    
+  class Configurations &lt; Base
+    before :find_configuration
+    
     def show
-      @configuration = Configuration.current
       display @configuration
     end
     
     def update
-      # The merb-action-args stuff doesn't seem to be working with an ajax call. So we're using 
-      # the nasty dirty params hash here.
-      @configuration = Configuration.current
       @configuration.title = params[:title] unless params[:title].nil?
       @configuration.tag_line = params[:tag_line] unless params[:tag_line].nil?
       @configuration.about = params[:about] unless params[:about].nil?
       @configuration.about_formatter = params[:about_formatter] unless params[:about_formatter].nil?
       @configuration.save
-      # Expire everything! 
+      # Expire all pages as the configuration settings affect the overall template
       expire_all_pages
       render_js
     end
+    
+    private
+      def find_configuration
+        @configuration = Configuration.current
+      end
   end
 end
\ No newline at end of file</diff>
      <filename>app/controllers/admin/configurations.rb</filename>
    </modified>
    <modified>
      <diff>@@ -10,11 +10,11 @@ module Admin
     
     private
       ##
-      # This checks to see if there are no users (such as when it's a fresh install) - if so,
-      # it creates a default user and redirects the user to login with those details
+      # This checks to see if there are no users (such as when it's a fresh install) - if so, it creates a default user and redirects the user to login with those details
       def check_for_user
         if User.count == 0
           User.create({:login =&gt; &quot;admin&quot;, :password =&gt; &quot;password&quot;, :password_confirmation =&gt; &quot;password&quot;, :name =&gt; 'blog owner', :email =&gt; &quot;none@none&quot;, :time_zone =&gt; &quot;Europe/London&quot;})
+          # Display the newly created users details
           notify &quot;No users found, so default user created: authenticate with login \&quot;admin\&quot;, password \&quot;password\&quot;, and then change your password.&quot;
         end
         login_required</diff>
      <filename>app/controllers/admin/dashboard.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,44 +1,49 @@
 module Admin
   class Plugins &lt; Base
+    before :find_plugin, :only =&gt; %w(update delete show)
+
     def index
       @plugins = Plugin.all
       display @plugins
     end
-    
+
     def show(id)
-      @plugin = Plugin[id]
       display @plugin
     end
-    
+
     def new
       @plugin = Plugin.new
       display @plugin
     end
-    
+
     def create(plugin)
       @plugin = Plugin.new
       @plugin.url = plugin[:url]
       if @plugin.save
+        # Check to see if the plugin has any views registered, if so we'll need to expire all pages to be safe
         expire_all_pages if Hooks::View.has_views_registered?(@plugin)
         redirect url(:admin_plugin, @plugin)
       else
         render :new
       end
     end
-    
+
     def update(id)
-      #merb-action-args doesn't appear to play nice with ajax calls, so we're using params for the plugin active flag
-      @plugin = Plugin[id]
       @plugin.active = (params[:active] == &quot;true&quot; ? true : false) if params[:active]
       @plugin.save
+      # Check to see if the plugin has any views registered, if so we'll need to expire all pages to be safe
       expire_all_pages if Hooks::View.has_views_registered?(@plugin)
       render_js
     end
-    
+
     def delete(id)
-      @plugin = Plugin[id]
       @plugin.destroy!
       redirect url(:admin_plugins)
     end
+
+    private
+      def find_plugin
+        @plugin = Plugin[params[:id]]
+      end
   end
 end
\ No newline at end of file</diff>
      <filename>app/controllers/admin/plugins.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,16 +1,16 @@
 module Admin
   class Users &lt; Base
+    before :find_user, :only =&gt; %w(edit update delete show)
 
     def index
       @users = User.all
       display @users
     end
-    
+
     def show
-      @user = User[params[:id]]
       display @user
     end
-    
+
     def new
       @user = User.new(params[:user] || {})
       display @user
@@ -18,7 +18,6 @@ module Admin
 
     def create
       cookies.delete :auth_token
-
       @user = User.new(params[:user])
       if @user.save
         redirect_back_or_default(url(:admin_users))
@@ -26,27 +25,27 @@ module Admin
         render :new
       end
     end
-    
+
     def edit
-      @user = User[params[:id]]
       display @user
     end
-    
+
     def update
-      @user = User[params[:id]]
       if @user.update_attributes(params[:user])
         redirect_back_or_default(url(:admin_users))
       else
         render :edit
       end
     end
-    
+
     def delete
-      @user = User[params[:id]]
       @user.destroy!
       redirect url(:admin_users)
     end
-    
+
+    private
+      def find_user
+        @user = User[params[:id]]
+      end    
   end
-  
 end
\ No newline at end of file</diff>
      <filename>app/controllers/admin/users.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,17 +1,17 @@
 class Application &lt; Merb::Controller
   include Merb::AssetsMixin
   include CacheHelper
-    
+
   before :get_settings
   before :load_plugins
   before :fire_before_event
-  
+
   ##
   # This grabs settings
   def get_settings
     @settings = Configuration.current
   end
-  
+
   ##
   # This ensures all plugins are loaded before any requests are dealt with - if one of the other server processes in a cluster adds one, it needs to be picked up
   def load_plugins
@@ -19,19 +19,19 @@ class Application &lt; Merb::Controller
       plugin.load unless plugin.loaded?
     end
   end
-  
+
   ##
-  # This fires the application before event with any subscribing plugins
+  # This fires the application before event for any subscribing plugins
   def fire_before_event
     Hooks::Events.application_before
   end
-  
+
   ##
   # This puts notification text in the session, to be rendered in any view
   def notify(text)
     session[:notifications] = text
   end
-  
+
   ##
   # This allows a view to expand its template roots to include its own custom views
   def self.include_plugin_views(plugin)</diff>
      <filename>app/controllers/application.rb</filename>
    </modified>
    <modified>
      <diff>@@ -13,15 +13,15 @@ class Articles &lt; Application
     else
       @articles = Article.find_recent
     end
-    # Can't use this with caching, meaning post-process events are tricky...
-    #render_then_call(display(@articles)) { Hooks::Events.after_article_index(@articles) }
+    # Can't use this with caching at the minute, meaning post-process events are tricky...
+    #render_then_call(display(@articles)) { Hooks::Events.after_index_article_request(@articles, request) }
     display @articles
   end
 
   def show(id)
     @article = Article[id]
-    # Can't use this with caching, meaning post-process events are tricky...
-    #render_then_call(display(@article)) { Hooks::Events.after_article_show(@article) }
+    # Can't use this with caching at the minute, meaning post-process events are tricky...
+    #render_then_call(display(@article)) { Hooks::Events.after_show_article_request(@article, request) }
     display @article
   end
 end
\ No newline at end of file</diff>
      <filename>app/controllers/articles.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,7 +1,6 @@
 module Merb
-module Admin
-module ConfigurationsHelper
-
-end
-end # Admin
+  module Admin
+    module ConfigurationsHelper
+    end
+  end
 end
\ No newline at end of file</diff>
      <filename>app/helpers/admin/configurations_helper.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,7 +1,6 @@
 module Merb
-module Admin
-module DashboardHelper
-
-end
-end # Admin
+  module Admin
+    module DashboardHelper
+    end
+  end
 end
\ No newline at end of file</diff>
      <filename>app/helpers/admin/dashboard_helper.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,21 +1,27 @@
 module Merb
   module GlobalHelpers
     def render_title
-      @settings.nil? ? &quot;My Cool Blog&quot; : @settings.title
+      @settings.title
     end
 
     def render_tag_line
-      @settings.nil? ? &quot;This blog rocks hard!&quot; : @settings.tag_line
+      @settings.tag_line
     end
-  
+
+    ##
+    # This formats the specified text using the specified formatter, returning the result
     def render_text(formatter, text)
       Hooks::Formatters.format_text(formatter, text)
     end
-    
+
+    ##
+    # This formats the specified article, using it's configured formatter, returning the result
     def render_article(article)
       Hooks::Formatters.format_article(article)
     end
-    
+
+    ##
+    # This builds the menu list from the menu items, returning the markup
     def render_menu
       menu = &quot;&quot;
       menu_items.each_with_index do |item, index|
@@ -23,8 +29,9 @@ module Merb
       end
       menu
     end
-    
-    # TODO: merb is supposed ot have a built in lib for this. Use it.
+
+    ##
+    # This returns the date as a relative date (today, yesterday etc)
     def render_relative_date(date)
       date = Date.parse(date, true) unless /Date.*/ =~ date.class.to_s
       days = (date - Date.today).to_i
@@ -40,20 +47,28 @@ module Merb
       return date.strftime('%A, %B %e, %Y')
     end
 
+    ##
+    # This returns the contents of the notifications in the session, clearing it at the same time
     def notifications
       notifications = session[:notifications]
       session[:notifications] = nil
       notifications
     end
-    
+
+    ##
+    # This returns the names of all possible timezones
     def get_timezones
       TZInfo::Timezone.all.collect { |tz| tz.name }
     end
-    
+
+    ##
+    # This returns the published at date for an article as a relative date (taking into account timezones)
     def render_relative_published_at(article)
       article.published_at.nil? ? &quot;Not yet&quot; : render_relative_date(TZInfo::Timezone.get(logged_in? ? self.current_user.time_zone : article.user.time_zone).utc_to_local(article.published_at))
     end
-    
+
+    ##
+    # This returns the markup for the about text in the sidebar
     def render_about_text
       unless @settings.nil? || @settings.about.blank?
         markup = &lt;&lt;-MARKUP
@@ -65,21 +80,27 @@ module Merb
       end
       markup
     end
-    
+
+    ##
+    # This returns the url for the year article index
     def year_url(year)
       url(:year, {:year =&gt; year})
     end
-    
+
+    ##
+    # This returns the url for the month article index
     def month_url(year, month)
       url(:month, {:year =&gt; year, :month =&gt; Padding::pad_single_digit(month)})
     end
-    
+
+    ##
+    # This returns the url for the day article index
     def day_url(year, month, day)
       url(:day, {:year =&gt; year, :month =&gt; Padding::pad_single_digit(month), :day =&gt; Padding::pad_single_digit(day)})
     end
 
     ##
-    # This returns all items, including those provided by plugins
+    # This returns all menu items, including those provided by plugins
     def menu_items
       items = []
       items &lt;&lt; {:text =&gt; &quot;Dashboard&quot;, :url =&gt; url(:admin_dashboard)}
@@ -95,11 +116,13 @@ module Merb
       Hooks::Menu.menu_items.each { |item| items &lt;&lt; item }
       items
     end
-    
+
+    ##
+    # This either adds the breaking &#8226; character unless we're at the end of the collection (based on index and size)
     def render_link_dot(index, collection_size)
       &quot;&amp;nbsp;&#8226;&quot; unless index == collection_size
     end
-    
+
     ##
     # This renders all plugin views for the specified hook
     def render_plugin_views(name, options = {})
@@ -107,32 +130,35 @@ module Merb
       Hooks::View.plugin_views.each do |view|
         if view[:name] == name
           if view[:partial]
+            # Set the template root, create the template method and call the partial
             _template_root = File.join(view[:plugin].path, &quot;views&quot;)
             template_location = _template_root / _template_location(&quot;_#{view[:partial]}&quot;, content_type, view[:name])
             template_method = Merb::Template.template_for(template_location)
             output &lt;&lt; send(template_method, options)
           else
+            # Render the specified text using ERB and the options
             output &lt;&lt; Proc.new { |args| ERB.new(view[:content]).result(binding) }.call(options[:with])
           end
         end
       end
+      # Return the view markup generated by plugins
       output
     end
-    
+
     ##
     # This returns the full url for an article
     def get_full_url(article)
       &quot;http://#{request.host}#{article.permalink}&quot;
     end
-    
+
     ##
     # This escapes the specified url
     def escape_url(url)
       CGI.escape(url)
     end
-    
+
     ##
-    # This returns true if the specified plugin is active, false if it isn't, or is unavailable
+    # This returns true if the specified plugin is active, false if it isn't or is unavailable
     def is_plugin_active(name)
       plugin = Plugin.first(:name =&gt; name)
       plugin &amp;&amp; plugin.active</diff>
      <filename>app/helpers/global_helpers.rb</filename>
    </modified>
    <modified>
      <diff>@@ -26,6 +26,8 @@ class Article &lt; DataMapper::Base
   after_update :fire_after_update_event
   after_save :fire_after_save_event
   
+  ##
+  # This sets the published date and permalink when an article is published
   def set_published_permalink
     # Check to see if we are publishing
     if self.is_published?
@@ -36,75 +38,77 @@ class Article &lt; DataMapper::Base
     end
     true
   end
-  
+
   def set_create_activity
     a = Activity.new
     a.message = &quot;Article \&quot;#{self.title}\&quot; created&quot;
     a.save
   end
-  
+
   def set_update_activity
     a = Activity.new
     a.message = &quot;Article \&quot;#{self.title}\&quot; updated&quot;
     a.save
   end
-  
+
   def fire_before_create_event
     Hooks::Events.before_create_article(self)
   end
-  
+
   def fire_before_update_event
     Hooks::Events.before_update_article(self)
   end
-  
+
   def fire_before_save_event
     Hooks::Events.before_save_article(self)
     Hooks::Events.before_publish_article(self) if self.is_published?
   end
-  
+
   def fire_after_create_event
     Hooks::Events.after_create_article(self)
   end
   
-  
   def fire_after_update_event
     Hooks::Events.after_update_article(self)
   end
-  
+
   def fire_after_save_event
     Hooks::Events.after_save_article(self)
     Hooks::Events.after_publish_article(self) if self.is_published?
   end
-  
+
   def is_published?
-    # We need this beacuse the values get populated from the params.
+    # We need this beacuse the values get populated from the params
     self.published == &quot;1&quot;
   end
-  
+
   class &lt;&lt; self
+    ##
+    # Custom finders
+
     def find_recent
       self.all(:published =&gt; true, :limit =&gt; 10, :order =&gt; &quot;published_at DESC&quot;)
     end
-  
+
     def find_by_year(year)
       self.all(:published_at.like =&gt; &quot;#{year}%&quot;, :published =&gt; true, :order =&gt; &quot;published_at DESC&quot;)
     end
-  
+
     def find_by_year_month(year, month)
       month = Padding::pad_single_digit(month)
       self.all(:published_at.like =&gt; &quot;#{year}-#{month}%&quot;, :published =&gt; true, :order =&gt; &quot;published_at DESC&quot;)
     end
-  
+
     def find_by_year_month_day(year, month, day)
       month = Padding::pad_single_digit(month)
       day = Padding::pad_single_digit(day)
       self.all(:published_at.like =&gt; &quot;#{year}-#{month}-#{day}%&quot;, :published =&gt; true, :order =&gt; &quot;published_at DESC&quot;)
     end
-  
+
     def find_by_permalink(permalink)
       self.first(:permalink =&gt; permalink)
     end
-    
+
     def get_archive_hash
       counts = self.find_by_sql(&quot;SELECT COUNT(*) as count, #{specific_date_function} FROM articles WHERE published_at IS NOT NULL AND published = 1 GROUP BY year, month ORDER BY year DESC, month DESC&quot;)
       archives = counts.map do |entry|
@@ -117,11 +121,10 @@ class Article &lt; DataMapper::Base
       end
       archives
     end
-    
+
     private 
       def specific_date_function
-        # This is pretty nasty loading up the db.yml to get at this, but I wasn't able to 
-        # find the method in merb just yet. Change it!
+        # This is pretty nasty loading up the db.yml to get at this, but I wasn't able to find the method in merb just yet. Change it!
         if YAML::load(File.read(&quot;config/database.yml&quot;))[Merb.environment.to_sym][:adapter] == 'sqlite3'
           &quot;strftime('%Y', published_at) as year, strftime('%m', published_at) as month&quot;
         else</diff>
      <filename>app/models/article.rb</filename>
    </modified>
    <modified>
      <diff>@@ -3,15 +3,16 @@ class Configuration &lt; DataMapper::Base
   property :tag_line, :string, :length =&gt; 255
   property :about, :text
   property :about_formatter, :string
-  
+
   after_save :set_activity
-  
+
   def set_activity
     a = Activity.new
     a.message = &quot;Configuration updated&quot;
     a.save
   end
-  
+
+  ##
   # This returns a shortened about for displaying on the settings screen, if the about is multiple lines
   def about_summary
     summary = self.about
@@ -22,12 +23,12 @@ class Configuration &lt; DataMapper::Base
     end
     summary
   end
-  
+
   ##
-  # This returns the current configuration, creating them if they aren't found
+  # This returns the current configuration, creating the record if it isn't found
   def self.current
     configuration = Configuration.first
-    configuration = Configuration.create(:title =&gt; &quot;My new blog&quot;, :tag_line =&gt; &quot;My blog rocks!&quot;, :about =&gt; &quot;I rock, and so does my blog&quot;, :about_formatter =&gt; &quot;default&quot;) if configuration.nil?
+    configuration = Configuration.create(:title =&gt; &quot;My new Feather blog&quot;, :tag_line =&gt; &quot;Feather rocks!&quot;, :about =&gt; &quot;I rock, and so does my Feather blog&quot;, :about_formatter =&gt; &quot;default&quot;) if configuration.nil?
     configuration    
   end
 end
\ No newline at end of file</diff>
      <filename>app/models/configuration.rb</filename>
    </modified>
    <modified>
      <diff>@@ -7,7 +7,7 @@ class Plugin &lt; DataMapper::Base
   property :homepage, :string, :length =&gt; 255
   property :about, :string, :length =&gt; 255
   property :active, :boolean
-  
+
   before_create :download
   after_create :install
   after_create :set_create_activity
@@ -38,7 +38,7 @@ class Plugin &lt; DataMapper::Base
     # Unpack any gems downloaded
     unpack_gems(manifest[&quot;plugin&quot;][&quot;contents&quot;][&quot;gems&quot;][&quot;.&quot;]) unless manifest[&quot;plugin&quot;][&quot;contents&quot;][&quot;gems&quot;].nil?
   end
-  
+
   ##
   # This loads and installs the plugin
   def install
@@ -51,7 +51,7 @@ class Plugin &lt; DataMapper::Base
     self.destroy!
     raise &quot;Error installing plugin: #{err.message}!&quot;
   end
-  
+
   ##
   # This adds the activity to show a plugin has been installed
   def set_create_activity
@@ -67,7 +67,7 @@ class Plugin &lt; DataMapper::Base
     a.message = &quot;Plugin \&quot;#{self.name}\&quot; #{self.active ? 'activated' : 'de-activated'}&quot;
     a.save
   end
-  
+
   ##
   # This removes the plugin, de-registers hooks, and adds an activity to show a plugin has been deleted
   def remove
@@ -77,7 +77,7 @@ class Plugin &lt; DataMapper::Base
     a.message = &quot;Plugin \&quot;#{self.name}\&quot; deleted&quot;
     a.save
   end
-  
+
   ##
   # This loads the plugin, first loading any gems it may have
   def load
@@ -88,13 +88,13 @@ class Plugin &lt; DataMapper::Base
     # Add the plugin to the array of loaded plugins
     @@loaded &lt;&lt; self.name
   end
-  
+
   ##
   # This returns true if the plugin has been loaded, false otherwise
   def loaded?
     @@loaded.include?(self.name)
   end
-  
+
   private
     ##
     # This recursively uses the yaml to download the files specified in the manifest
@@ -116,7 +116,7 @@ class Plugin &lt; DataMapper::Base
         end
       end
     end
-    
+
     ##
     # This recursively unpacks the gems used by the plugin
     def unpack_gems(gems)</diff>
      <filename>app/models/plugin.rb</filename>
    </modified>
    <modified>
      <diff>@@ -6,9 +6,9 @@ rescue
 end
 class User &lt; DataMapper::Base
   include AuthenticatedSystem::Model
-  
+
   attr_accessor :password, :password_confirmation
-  
+
   property :login,                      :string
   property :email,                      :string, :length =&gt; 255
   property :crypted_password,           :string
@@ -20,31 +20,32 @@ class User &lt; DataMapper::Base
   property :updated_at,                 :datetime
   property :name,                       :string
   property :default_formatter,          :string
-  
+
   validates_length_of         :login,                   :within =&gt; 3..40
   validates_uniqueness_of     :login
   validates_presence_of       :password,                :if =&gt; proc {password_required?}
   validates_presence_of       :password_confirmation,   :if =&gt; proc {password_required?}
   validates_length_of         :password,                :within =&gt; 4..40, :if =&gt; proc {password_required?}
   validates_confirmation_of   :password,                :groups =&gt; :create
-    
+  validates_presence_of       :email
+
   before_save :encrypt_password
-  
+
   after_create :set_create_activity
   after_update :set_update_activity
-  
+
   def set_create_activity
     a = Activity.new
     a.message = &quot;User \&quot;#{self.login}\&quot; created&quot;
     a.save
   end
-  
+
   def set_update_activity
     a = Activity.new
     a.message = &quot;User \&quot;#{self.login}\&quot; updated&quot;
     a.save
   end
-  
+
   def login=(value)
     @login = value.downcase unless value.nil?
   end</diff>
      <filename>app/models/user.rb</filename>
    </modified>
    <modified>
      <diff>@@ -3,4 +3,4 @@
 	&lt;td&gt;&lt;%= render_relative_published_at(article) %&gt;&lt;/td&gt;
 	&lt;td&gt;&lt;%= article.user.name %&gt;&lt;/td&gt;
 	&lt;td &lt;%= link_to &quot;Edit&quot;, url(:edit_admin_article, article) %&gt; | &lt;%= link_to 'Delete', url(:delete_admin_article, article), {:method =&gt; :delete, :onclick =&gt; &quot;return confirm('Are you sure?')&quot;} %&gt;&lt;/td&gt;
-&lt;/tr&gt;
+&lt;/tr&gt;
\ No newline at end of file</diff>
      <filename>app/views/admin/articles/_article.html.erb</filename>
    </modified>
    <modified>
      <diff>@@ -10,4 +10,4 @@
   &lt;%= select_control :formatter, :collection =&gt; Hooks::Formatters.available_formatters, :selected =&gt; (@article.new_record? ? (self.current_user.default_formatter || &quot;default&quot;) : @article.formatter) %&gt;
 &lt;/p&gt;
 
-&lt;%= render_plugin_views &quot;article_form_fields&quot; %&gt;
+&lt;%= render_plugin_views &quot;article_form_fields&quot; %&gt;
\ No newline at end of file</diff>
      <filename>app/views/admin/articles/_form.html.erb</filename>
    </modified>
    <modified>
      <diff>@@ -1,7 +1,7 @@
 &lt;% throw_content :right do %&gt;
   &lt;h4&gt;What is the Dashboard?&lt;/h4&gt;
   &lt;p&gt;
-    Your dashboard is a place where, oh I don't know what the deuce it does!
+    Your dashboard is a place where you can see recent activity, and access the rest of the admin area to manage your Feather blog.
   &lt;/p&gt;
 &lt;% end %&gt;
 </diff>
      <filename>app/views/admin/dashboard/index.html.erb</filename>
    </modified>
    <modified>
      <diff>@@ -5,10 +5,8 @@
 &lt;p&gt;&lt;label for=&quot;password&quot;&gt;Password&lt;/label&gt;&lt;br/&gt;
 &lt;%= password_field :name =&gt; &quot;password&quot; %&gt;&lt;/p&gt;
 
-&lt;!-- Uncomment this if you want this functionality
 &lt;p&gt;&lt;label for=&quot;remember_me&quot;&gt;Remember me:&lt;/label&gt;
 &lt;%= checkbox_field :name =&gt; 'remember_me' %&gt;&lt;/p&gt;
---&gt;
 
 &lt;p&gt;&lt;%= submit_button 'Log in' %&gt;&lt;/p&gt;
 &lt;% end -%&gt;
\ No newline at end of file</diff>
      <filename>app/views/admin/sessions/new.html.erb</filename>
    </modified>
    <modified>
      <diff>@@ -4,4 +4,4 @@
 	&lt;td&gt;&lt;%= user.email %&gt;&lt;/td&gt;
 	&lt;td&gt;&lt;%= user.time_zone %&gt;&lt;/td&gt;
 	&lt;td &lt;%= link_to &quot;Edit&quot;, url(:edit_admin_user, user) %&gt; | &lt;%= link_to 'Delete', url(:delete_admin_user, user), {:method =&gt; :delete, :onclick =&gt; &quot;return confirm('Are you sure?')&quot;} %&gt;&lt;/td&gt;
-&lt;/tr&gt;
+&lt;/tr&gt;
\ No newline at end of file</diff>
      <filename>app/views/admin/users/_user.html.erb</filename>
    </modified>
    <modified>
      <diff>@@ -1,7 +1,7 @@
 &lt;table&gt;
 	&lt;tr&gt;
 		&lt;th&gt;Login&lt;/th&gt;
-    &lt;th&gt;Name&lt;/th&gt;
+    	&lt;th&gt;Name&lt;/th&gt;
 		&lt;th&gt;E-mail&lt;/th&gt;
 		&lt;th&gt;Timezone&lt;/th&gt;
 		&lt;th&gt;&lt;/th&gt;</diff>
      <filename>app/views/admin/users/index.html.erb</filename>
    </modified>
    <modified>
      <diff>@@ -49,4 +49,4 @@
   &lt;/div&gt;
 &lt;/div&gt;
 &lt;/body&gt;
-&lt;/html&gt;
+&lt;/html&gt;
\ No newline at end of file</diff>
      <filename>app/views/layout/application.html.erb</filename>
    </modified>
    <modified>
      <diff>@@ -1 +1 @@
-&lt;li&gt;&lt;%= link_to archive[:name], month_url(archive[:year], archive[:month]) %&gt; (&lt;%= archive[:article_count] %&gt;)&lt;/li&gt;
+&lt;li&gt;&lt;%= link_to archive[:name], month_url(archive[:year], archive[:month]) %&gt; (&lt;%= archive[:article_count] %&gt;)&lt;/li&gt;
\ No newline at end of file</diff>
      <filename>app/views/shared/_archive.html.erb</filename>
    </modified>
    <modified>
      <diff>@@ -5,7 +5,6 @@ Gem.path.unshift(Merb.root / &quot;gems&quot;)
 # Make the app's &quot;lib&quot; directory a place where ruby files get &quot;require&quot;d from
 $LOAD_PATH.unshift(Merb.root / &quot;lib&quot;)
 
-
 Merb::Config.use do |c|
   
   ### Sets up a custom session id key, if you want to piggyback sessions of other applications
@@ -52,6 +51,7 @@ dependencies &quot;merb-assets&quot;
 dependencies &quot;merb-cache&quot;
 dependency &quot;merb-action-args&quot;
 dependency &quot;merb-mailer&quot;
+dependency &quot;merb_stories&quot; if Merb.environment == &quot;test&quot;
 # OR
 # OR
 # dependencies &quot;RedCloth&quot; =&gt; &quot;&gt; 3.0&quot;, &quot;ruby-aes-cext&quot; =&gt; &quot;= 1.0&quot;
@@ -79,7 +79,7 @@ Merb::BootLoader.after_app_loads do
   rescue Exception =&gt; e
     Merb.logger.info(&quot;Error loading plugins: #{e.message}&quot;)
   end
-  
+
   Merb::Mailer.delivery_method = :sendmail
 end
 
@@ -89,10 +89,8 @@ begin
 rescue LoadError
 end
 
-
 Merb::Plugins.config[:merb_cache] = {
    :cache_html_directory =&gt; Merb.dir_for(:public)  / &quot;cache&quot;,
-
    :store =&gt; &quot;file&quot;,
    :cache_directory =&gt; Merb.root_path(&quot;tmp/cache&quot;)
 }
\ No newline at end of file</diff>
      <filename>config/init.rb</filename>
    </modified>
    <modified>
      <diff>@@ -35,8 +35,6 @@ Merb::Router.prepare do |r|
     admin.resources :categories
     admin.resources :plugins
     admin.resources :articles
-    admin.resources :users
-    admin.resources :sessions
     admin.match(&quot;&quot;).to(:controller =&gt; &quot;dashboard&quot;, :action =&gt; &quot;index&quot;)
   end
   
@@ -44,11 +42,10 @@ Merb::Router.prepare do |r|
   r.match(&quot;/:year&quot;).to(:controller =&gt; &quot;articles&quot;, :action =&gt; &quot;index&quot;).name(:year)
   r.match(&quot;/:year/:month&quot;).to(:controller =&gt; &quot;articles&quot;, :action =&gt; &quot;index&quot;).name(:month)
   r.match(&quot;/:year/:month/:day&quot;).to(:controller =&gt; &quot;articles&quot;, :action =&gt; &quot;index&quot;).name(:day)
-  # Permalinks are handled with a Rack hook
-  
-  r.default_routes
   
+  # Default routes, and index
+  r.default_routes  
   r.match('/').to(:controller =&gt; 'articles', :action =&gt;'index')
 end
 
-AuthenticatedSystem.add_routes rescue nil
\ No newline at end of file
+AuthenticatedSystem.add_routes
\ No newline at end of file</diff>
      <filename>config/router.rb</filename>
    </modified>
    <modified>
      <diff>@@ -3,9 +3,12 @@ module AuthenticatedSystem
   def self.add_routes
     Merb::BootLoader.after_app_loads do
       Merb::Router.prepend do |r|
-        r.match(&quot;/login&quot;).to(:controller =&gt; &quot;Sessions&quot;, :action =&gt; &quot;create&quot;, :namespace =&gt; &quot;admin&quot;).name(:login)
-        r.match(&quot;/logout&quot;).to(:controller =&gt; &quot;Sessions&quot;, :action =&gt; &quot;destroy&quot;, :namespace =&gt; &quot;admin&quot;).name(:logout)
-        r.resources :users
+        r.match(&quot;/login&quot;).to(:controller =&gt; &quot;sessions&quot;, :action =&gt; &quot;create&quot;, :namespace =&gt; &quot;admin&quot;).name(:login)
+        r.match(&quot;/logout&quot;).to(:controller =&gt; &quot;sessions&quot;, :action =&gt; &quot;destroy&quot;, :namespace =&gt; &quot;admin&quot;).name(:logout)
+        r.namespace :admin do |admin|
+          admin.resources :users
+          admin.resources :sessions
+        end
       end
     end
   end</diff>
      <filename>lib/authenticated_system/authenticated_routes.rb</filename>
    </modified>
    <modified>
      <diff>@@ -2,10 +2,9 @@ module CacheHelper
   def expire_index
     expire_page(:controller =&gt; '/', :action =&gt; &quot;index&quot;)
   end
-  
+
   def expire_article(article)
-    # If an article is a draft, it
-    # will not have a permalink to split on.
+    # If an article is a draft, it will not have a permalink to split on
     unless article.permalink.nil?
       parts = article.permalink.split(&quot;/&quot;)
       # Expire the year. 
@@ -15,5 +14,4 @@ module CacheHelper
       expire_page(:controller =&gt; '/', :action =&gt; article.permalink)
     end
   end
-  
 end
\ No newline at end of file</diff>
      <filename>lib/cache_helper.rb</filename>
    </modified>
    <modified>
      <diff>@@ -11,30 +11,29 @@ module Hooks
       plugin = get_plugin(hook)
       !plugin.nil? &amp;&amp; plugin.active
     end
-    
+
     ##
     # This returns the plugin applicable for any given hook
     def get_plugin(hook)
-      get_plugin_by_caller eval(&quot;__FILE__&quot;, hook.binding)
+      get_plugin_by_caller(eval(&quot;__FILE__&quot;, hook.binding))
     end
-    
+
     ##
     # This returns the plugin applicable for the specified file
     def get_plugin_by_caller(file)
       Plugin.all.each do |plugin|
-        #TODO: more efficient way to do this?
         return plugin if file[0..plugin.path.length - 1] == plugin.path
       end
       nil
     end
-    
+
     ##
     # This removes all hooks for the specified plugin
     def remove_plugin_hooks(id)
       Hooks::Menu.remove_plugin_hooks(id)
       Hooks::View.remove_plugin_hooks(id)
     end
-    
+
     ##
     # This returns the calling file that called the method that then called this helper method
     def get_caller</diff>
      <filename>lib/hooks.rb</filename>
    </modified>
    <modified>
      <diff>@@ -2,6 +2,9 @@ module Hooks
   module Events
     class &lt;&lt; self
       ##
+      # Event registration
+
+      ##
       # This registers a block against an event
       def register_event(event, &amp;block)
         @events = {} if @events.nil?
@@ -10,82 +13,109 @@ module Hooks
       end
 
       ##
-      # This calls the event handlers for the specified event
+      # This calls the event handlers for the specified event (wrapping errors)
       def run_event(event, *args)
         unless @events.nil? || @events.empty? || @events[event].nil? || @events[event].empty?
           @events[event].each do |hook|
             if Hooks::is_hook_valid?(hook)
-              hook.call args
+              begin
+                hook.call args
+              rescue
+              end
             end
           end
         end
         true
       end
-      
+
       ##
-      # This calls any event handlers for the before_create_article event
+      # Model events
+
+      ##
+      # This gets called before article creation, and provides the article that is being created
       def before_create_article(article)
         run_event(:before_create_article, article)
       end
-      
+
       ##
-      # This calls any event handlers for the before_update_article event
+      # This gets called before article updating, and provides the article that is being updated
       def before_update_article(article)
         run_event(:before_update_article, article)
       end
-      
+
       ##
-      # This calls any event handlers for the before_save_article event
+      # This gets called before an article is saved (created or updated), and provides the article that is being saved
       def before_save_article(article)
         run_event(:before_save_article, article)
       end
-      
+
       ##
-      # This calls any event handlers for the before_publish_article event
+      # This gets called before an article is published, and provides the article that is being published
       def before_publish_article(article)
         run_event(:before_publish_article, article)
       end
-      
+
       ##
-      # This calls any event handlers for the after_create_article event
+      # This gets called after an article is created, and provides the article that was created
       def after_create_article(article)
         run_event(:after_create_article, article)
       end
 
       ##
-      # This calls any event handlers for the after_update_article event
+      # This gets called after an article is updated, and provides the article that was updated
       def after_update_article(article)
         run_event(:after_update_article, article)
       end
-      
+
       ##
-      # This calls any event handlers for the after_save_article event
+      # This gets called after an article is saved, and provides the article that was saved
       def after_save_article(article)
         run_event(:after_save_article, article)
       end
-      
+
       ##
-      # This calls any event handlers for the after_publish_article event
+      # This gets called after an article is published, and provides the article that was published
       def after_publish_article(article)
         run_event(:after_publish_article, article)
       end
-      
+
       ##
-      # This calls any event handlers for the application_before event
+      # Controller events
+
+      ##
+      # This gets called before any controller action
       def application_before
         run_event(:application_before)
       end
-      
+
+      ##
+      # This gets called after the article index request, providing the articles from the index, and the request
+      def after_index_article_request(articles, request)
+        run_event(:after_index_article_request, articles, request)
+      end
+
+      ##
+      # This gets called after the article show request, providing the article being shown, and the request
+      def after_show_article_request(article, request)
+        run_event(:after_show_article_request, article, request)
+      end
+
+      ##
+      # This gets called after a request to create an article, providing the article that was created, and the request
+      def after_create_article_request(article, request)
+        run_event(:after_create_article_request, article, request)
+      end
+
       ##
-      # This calls any event handlers for the after_article_index event
-      def after_article_index(articles)
-        run_event(:after_article_index, articles)
+      # This gets called after a request to update an article, providing the article that was updated, and the request
+      def after_update_article_request(article, request)
+        run_event(:after_update_article_request, article, request)
       end
-      
+
       ##
-      # This calls any event handlers for the after_article_show event
-      def after_article_show(article)
-        run_event(:after_article_show, article)
+      # This gets called after a request to publish an article (a create or update where the article is marked as published), providing the article that was published, and the request
+      def after_publish_article_request(article, request)
+        run_event(:after_publish_article_request, article, request)
       end
     end
   end</diff>
      <filename>lib/hooks/events.rb</filename>
    </modified>
    <modified>
      <diff>@@ -8,14 +8,14 @@ module Hooks
         raise &quot;Formatter `#{name}` already registered!&quot; unless @formatters[name].nil?
         @formatters[name] = block
       end
-      
+
       ##
       # This returns an array of available formatters that have been registered
       def available_formatters
         @formatters = {&quot;default&quot; =&gt; default_formatter} if @formatters.nil?
         @formatters.keys.select { |key| key == &quot;default&quot; || Hooks::is_hook_valid?(@formatters[key]) }
       end
-      
+
       ##
       # This returns a default formatter used for replacing line breaks within text
       # This is the only formatter included within feather-core
@@ -24,18 +24,18 @@ module Hooks
           text.gsub(&quot;\r\n&quot;, &quot;\n&quot;).gsub(&quot;\n&quot;, &quot;&lt;br /&gt;&quot;)
         end
       end
-      
+
       ##
       # This performs the relevant formatting for the article, and returns the formatted article content
       def format_article(article)
         format_text(article.formatter, article.content)
       end
-      
+
       ##
       # This performs the requested formatting, returning the formatted text
       def format_text(formatter, text)
         formatter = &quot;default&quot; unless available_formatters.include?(formatter)
-        test = @formatters[formatter].call(text)
+        @formatters[formatter].call(text)
       end
     end
   end</diff>
      <filename>lib/hooks/formatters.rb</filename>
    </modified>
    <modified>
      <diff>@@ -11,7 +11,7 @@ module Hooks
       end
 
       ##
-      # This returns the menu items for any plugins that have used the above call
+      # This returns the menu items for any plugins that have used the above call (providing the plugins are active)
       def menu_items
         menu_items = []
         unless @menu_item_hooks.nil?
@@ -21,7 +21,7 @@ module Hooks
         end
         menu_items
       end
-      
+
       ##
       # This removes any plugin hooks for the plugin with the specified id
       def remove_plugin_hooks(id)</diff>
      <filename>lib/hooks/menu.rb</filename>
    </modified>
    <modified>
      <diff>@@ -2,23 +2,23 @@ module Hooks
   module View
     class &lt;&lt; self
       ##
-      # This returns an array of the available hooks
+      # This returns an array of the available view hooks
       def available_hooks
         [&quot;first_article_in_list&quot;, &quot;last_article_in_list&quot;, &quot;before_article&quot;, &quot;before_article_in_list&quot;, &quot;after_article&quot;, &quot;after_article_in_list&quot;, &quot;article_form_fields&quot;, &quot;between_articles&quot;, &quot;meta_section&quot;, &quot;head&quot;, &quot;header&quot;, &quot;before_layout&quot;, &quot;after_layout&quot;, &quot;sidebar&quot;, &quot;footer&quot;]
       end
-      
+
       ##
       # This returns true if the specified plugin has views registered, false otherwise
       def has_views_registered?(plugin)
         @view_hooks.include?(plugin.id)
       end
-      
+
       ##
       # This registers a partial view, effectively adding a call to the specified partial for the specified view hook point
       def register_partial_view(name, partial)
         register_view(Hooks::get_caller, name, {:partial =&gt; partial})
       end
-      
+
       ##
       # This registers a dynamic view, effectively adding string content to the specified view hook point, with a specified identifier
       def register_dynamic_view(name, content, id = nil)
@@ -34,7 +34,7 @@ module Hooks
         @view_hooks[plugin.id] ||= []
         @view_hooks[plugin.id] &lt;&lt; {:id =&gt; id, :name =&gt; name}.merge(options)
       end
-      
+
       ##
       # This removes any view hooks registered with the specified identifier
       def deregister_dynamic_view(id)
@@ -46,7 +46,7 @@ module Hooks
       end
 
       ##
-      # This iterates through all registered views, building an array to be rendered
+      # This iterates through all registered views (from active plugins), building an array to be rendered
       def plugin_views
         plugin_views = []
         unless @view_hooks.nil? || @view_hooks.values.nil?
@@ -56,7 +56,7 @@ module Hooks
         end
         plugin_views.sort { |a, b| a[:plugin].name &lt;=&gt; b[:plugin].name }
       end
-      
+
       ##
       # This removes any view hooks for the specified plugin
       def remove_plugin_hooks(id)</diff>
      <filename>lib/hooks/view.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,8 +1,10 @@
 class Padding
   class &lt;&lt; self
+    ##
+    # This adds 0 to the beginning of the number if it's a single digit, or just returns the number as a string if it isn't a single digit
+    # e.g. 7 =&gt; &quot;07&quot;, 11 =&gt; &quot;11&quot;
     def pad_single_digit(number)
-      number = &quot;0#{number}&quot; if number.to_s.length == 1
-      number
+      number.to_s.length == 1 ? &quot;0#{number}&quot; : number.to_s
     end
   end
 end
\ No newline at end of file</diff>
      <filename>lib/padding.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,4 +1,3 @@
-
 var FormHelper = {	
   /**
 	* This toggles the visibility of the specified element, and alternately toggles the *_container element</diff>
      <filename>public/javascripts/admin.js</filename>
    </modified>
    <modified>
      <diff>@@ -1,6 +1,8 @@
 var ArticleHelper = {
 
-  // This function will auto-resize a text area instead of showing scroll bars.
+  /**
+ 	* This function will auto-resize a text area instead of showing scroll bars
+	**/
   resizeTextArea:  function(elem) {
     a = elem.value.split('\n');
     b = 1;
@@ -22,4 +24,4 @@ var ArticleHelper = {
 
 Event.observe(window, 'load', function() {
   Event.observe('article_content', 'keypress', function() { ArticleHelper.resizeTextArea($('article_content')) });
-});
+});
\ No newline at end of file</diff>
      <filename>public/javascripts/application.js</filename>
    </modified>
    <modified>
      <diff>@@ -348,4 +348,4 @@
 #footer li {
   margin: 0; padding: 0 0 0 1em;
   display: inline; 
-}
+}
\ No newline at end of file</diff>
      <filename>public/stylesheets/content.css</filename>
    </modified>
    <modified>
      <diff>@@ -44,4 +44,4 @@ body {
   height: 40px; 
   margin: 10px 0 0; padding: 10px 0 0;
   clear:both; 
-}
+}
\ No newline at end of file</diff>
      <filename>public/stylesheets/layout.css</filename>
    </modified>
    <modified>
      <diff>@@ -142,4 +142,4 @@ ol.CodeRay li { white-space:pre; }
 .ts { color:#D70; font-weight:bold; }
 .ty { color:#339; font-weight:bold; }
 .v  { color:#036; }
-.xt { color:#444; }
+.xt { color:#444; }
\ No newline at end of file</diff>
      <filename>public/stylesheets/syntax.css</filename>
    </modified>
    <modified>
      <diff>@@ -2,15 +2,12 @@ Merb::Config.use do |c|
   c[:session_store] = &quot;memory&quot;
 end
 
-
-class Hash
-  
+class Hash  
   def with( opts )
     self.merge(opts)
   end
-  
+
   def without(*args)
     self.dup.delete_if{ |k,v| args.include?(k)}
   end
-  
 end
\ No newline at end of file</diff>
      <filename>spec/authenticated_system_spec_helper.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,13 +1,21 @@
 require File.join(File.dirname(__FILE__), &quot;../..&quot;, 'spec_helper.rb')
 
-describe Admin::Configurations, &quot;show action&quot; do
-  before(:each) do
-    dispatch_to(Admin::Configurations, :show)
-  end
-  
-  it &quot;should be be succesful&quot; do
-    controller = get &quot;/show&quot;
-    controller.should be_successful
+module Admin
+  describe Configurations do
+    before(:each) do
+      @configuration = mock(:configuration)
+    end
+
+    describe &quot;/admin/configurations&quot; do
+      it &quot;should get current configuration&quot; do
+        Configuration.stub!(:current).and_return(@configuration)
+        controller = dispatch_to(Configurations, :show) do |controller|
+          controller.should_receive(:login_required).and_return(true)
+          controller.should_receive(:display).with(@configuration)
+        end
+        controller.assigns(:configuration).should == @configuration
+        controller.should be_successful
+      end
+    end
   end
-  
 end
\ No newline at end of file</diff>
      <filename>spec/controllers/admin/configurations_spec.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,20 +1,21 @@
 require File.join(File.dirname(__FILE__), &quot;../..&quot;, 'spec_helper.rb')
 
-describe Admin::Dashboard, &quot;index action&quot; do
-  before(:each) do
-    dispatch_to(Admin::Dashboard, :index)
-  end
-  
-  it &quot;should have a route to /admin&quot; do
-    request_to(&quot;/admin&quot;) do |params|
-      params[:controller].should == &quot;admin/dashboard&quot;
-      params[:action].should == &quot;index&quot;
-    end   
-  end
-  
-  it &quot;should successfully show the dashboard&quot; do
-    controller = get &quot;/admin&quot;
-    controller.should be_successful
+module Admin
+  describe Dashboard do
+    before(:each) do
+      @activity = [mock(:activity)]
+    end
+
+    describe &quot;/admin&quot; do
+      it &quot;should request dashboard&quot; do
+        Activity.should_receive(:all).with(:order =&gt; &quot;created_at DESC&quot;, :limit =&gt; 5).and_return(@activity)
+        controller = dispatch_to(Dashboard, :index) do |controller|
+          controller.should_receive(:login_required).and_return(true)
+          controller.should_receive(:display).with(@activity)
+        end
+        controller.assigns(:activity).should == @activity
+        controller.should be_successful
+      end
+    end
   end
-  
 end
\ No newline at end of file</diff>
      <filename>spec/controllers/admin/dashboard_spec.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,7 +1,20 @@
 require File.join(File.dirname(__FILE__), &quot;..&quot;, 'spec_helper.rb')
 
-describe Articles, &quot;index action&quot; do
+describe Articles do
   before(:each) do
-    dispatch_to(Articles, :index)
+    @article = mock(:article)
+    @articles = [@article]
+  end
+  
+  describe &quot;/&quot; do
+    it &quot;should return recent articles&quot; do
+      Article.should_receive(:find_recent).and_return @articles
+      controller = dispatch_to(Articles, :index) do |controller|
+        controller.expire_all_pages
+        controller.should_receive(:display).with(@articles)
+      end
+      controller.assigns(:articles).should == @articles
+      controller.should be_successful
+    end
   end
 end
\ No newline at end of file</diff>
      <filename>spec/controllers/articles_spec.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,5 +1,4 @@
 require File.join(File.dirname(__FILE__), &quot;../..&quot;, 'spec_helper.rb')
 
 describe Merb::Admin::ConfigurationsHelper do
-
 end
\ No newline at end of file</diff>
      <filename>spec/helpers/admin/configurations_helper_spec.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,5 +1,4 @@
 require File.join(File.dirname(__FILE__), &quot;../..&quot;, 'spec_helper.rb')
 
 describe Merb::Admin::DashboardHelper do
-
 end
\ No newline at end of file</diff>
      <filename>spec/helpers/admin/dashboard_helper_spec.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,5 +1,4 @@
 require File.join(File.dirname(__FILE__), &quot;..&quot;, 'spec_helper.rb')
 
 describe Merb::ArticlesHelper do
-
 end
\ No newline at end of file</diff>
      <filename>spec/helpers/articles_helper_spec.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,7 +1,5 @@
 require File.join( File.dirname(__FILE__), &quot;..&quot;, &quot;spec_helper&quot; )
 
 describe Article do
-
   it &quot;should have specs&quot;
-
 end
\ No newline at end of file</diff>
      <filename>spec/models/article_spec.rb</filename>
    </modified>
    <modified>
      <diff>@@ -4,7 +4,7 @@ require File.join( File.dirname(__FILE__), &quot;..&quot;, &quot;authenticated_system_spec_help
 
 describe User do
   include UserSpecHelper
-  
+
   before(:each) do
     User.clear_database_table
   end
@@ -15,14 +15,14 @@ describe User do
     user.valid?
     user.errors.on(:login).should_not be_nil
   end
-  
+
   it &quot;should fail login if there are less than 3 chars&quot; do
     user = User.new
     user.login = &quot;AB&quot;
     user.valid?
     user.errors.on(:login).should_not be_nil
   end
-  
+
   it &quot;should not fail login with between 3 and 40 chars&quot; do
     user = User.new
     [3,40].each do |num|
@@ -31,21 +31,20 @@ describe User do
       user.errors.on(:login).should be_nil
     end
   end
-  
+
   it &quot;should fail login with over 90 chars&quot; do
     user = User.new
     user.login = &quot;A&quot; * 41
     user.valid?
     user.errors.on(:login).should_not be_nil    
   end
-  
+
   it &quot;should make a valid user&quot; do
     user = User.new(valid_user_hash)
     user.save
     user.errors.should be_empty
-    
   end
-  
+
   it &quot;should make sure login is unique&quot; do
     user = User.new( valid_user_hash.with(:login =&gt; &quot;Daniel&quot;) )
     user2 = User.new( valid_user_hash.with(:login =&gt; &quot;Daniel&quot;))
@@ -54,7 +53,7 @@ describe User do
     user2.save.should be_false
     user2.errors.on(:login).should_not be_nil
   end
-  
+
   it &quot;should make sure login is unique regardless of case&quot; do
     User.find_with_conditions(:login =&gt; &quot;Daniel&quot;).should be_nil
     user = User.new( valid_user_hash.with(:login =&gt; &quot;Daniel&quot;) )
@@ -64,60 +63,58 @@ describe User do
     user2.save.should be_false
     user2.errors.on(:login).should_not be_nil
   end
-  
+
   it &quot;should downcase logins&quot; do
     user = User.new( valid_user_hash.with(:login =&gt; &quot;DaNieL&quot;))
     user.login.should == &quot;daniel&quot;    
   end  
-  
+
   it &quot;should authenticate a user using a class method&quot; do
     user = User.new(valid_user_hash)
     user.save
     User.authenticate(valid_user_hash[:login], valid_user_hash[:password]).should_not be_nil
   end
-  
+
   it &quot;should not authenticate a user using the wrong password&quot; do
     user = User.new(valid_user_hash)  
     user.save
     User.authenticate(valid_user_hash[:login], &quot;not_the_password&quot;).should be_nil
   end
-  
+
   it &quot;should not authenticate a user using the wrong login&quot; do
     user = User.create(valid_user_hash)  
     User.authenticate(&quot;not_the_login&quot;, valid_user_hash[:password]).should be_nil
   end
-  
+
   it &quot;should not authenticate a user that does not exist&quot; do
     User.authenticate(&quot;i_dont_exist&quot;, &quot;password&quot;).should be_nil
   end
-  
-  
 end
 
 describe User, &quot;the password fields for User&quot; do
   include UserSpecHelper
-  
+
   before(:each) do
     User.clear_database_table
     @user = User.new( valid_user_hash )
   end
-  
+
   it &quot;should respond to password&quot; do
     @user.should respond_to(:password)    
   end
-  
+
   it &quot;should respond to password_confirmation&quot; do
     @user.should respond_to(:password_confirmation)
   end
-  
+
   it &quot;should have a protected password_required method&quot; do
     @user.protected_methods.should include(&quot;password_required?&quot;)
   end
-  
+
   it &quot;should respond to crypted_password&quot; do
     @user.should respond_to(:crypted_password)    
   end
-  
+
   it &quot;should require password if password is required&quot; do
     user = User.new( valid_user_hash.without(:password))
     user.stub!(:password_required?).and_return(true)
@@ -125,27 +122,27 @@ describe User, &quot;the password fields for User&quot; do
     user.errors.on(:password).should_not be_nil
     user.errors.on(:password).should_not be_empty
   end
-  
+
   it &quot;should set the salt&quot; do
     user = User.new(valid_user_hash)
     user.salt.should be_nil
     user.send(:encrypt_password)
     user.salt.should_not be_nil    
   end
-  
+
   it &quot;should require the password on create&quot; do
     user = User.new(valid_user_hash.without(:password))
     user.save
     user.errors.on(:password).should_not be_nil
     user.errors.on(:password).should_not be_empty
   end  
-  
+
   it &quot;should require password_confirmation if the password_required?&quot; do
     user = User.new(valid_user_hash.without(:password_confirmation))
     user.save
     (user.errors.on(:password) || user.errors.on(:password_confirmation)).should_not be_nil
   end
-  
+
   it &quot;should fail when password is outside 4 and 40 chars&quot; do
     [3,41].each do |num|
       user = User.new(valid_user_hash.with(:password =&gt; (&quot;a&quot; * num)))
@@ -153,7 +150,7 @@ describe User, &quot;the password fields for User&quot; do
       user.errors.on(:password).should_not be_nil
     end
   end
-  
+
   it &quot;should pass when password is within 4 and 40 chars&quot; do
     [4,30,40].each do |num|
       user = User.new(valid_user_hash.with(:password =&gt; (&quot;a&quot; * num), :password_confirmation =&gt; (&quot;a&quot; * num)))
@@ -161,13 +158,13 @@ describe User, &quot;the password fields for User&quot; do
       user.errors.on(:password).should be_nil
     end    
   end
-  
-  it &quot;should autenticate against a password&quot; do
+
+  it &quot;should authenticate against a password&quot; do
     user = User.new(valid_user_hash)
     user.save    
     user.should be_authenticated(valid_user_hash[:password])
   end
-  
+
   it &quot;should not require a password when saving an existing user&quot; do
     user = User.create(valid_user_hash)
     user = User.find_with_conditions(:login =&gt; valid_user_hash[:login])
@@ -176,39 +173,37 @@ describe User, &quot;the password fields for User&quot; do
     user.login = &quot;some_different_login_to_allow_saving&quot;
     (user.save).should be_true
   end
-  
 end
 
-
 describe User, &quot;remember_me&quot; do
   include UserSpecHelper
-  
+
   predicate_matchers[:remember_token] = :remember_token?
-  
+
   before do
     User.clear_database_table
     @user = User.new(valid_user_hash)
   end
-  
+
   it &quot;should have a remember_token_expires_at attribute&quot; do
     @user.attributes.keys.any?{|a| a.to_s == &quot;remember_token_expires_at&quot;}.should_not be_nil
   end  
-  
+
   it &quot;should respond to remember_token?&quot; do
     @user.should respond_to(:remember_token?)
   end
-  
+
   it &quot;should return true if remember_token_expires_at is set and is in the future&quot; do
     @user.remember_token_expires_at = DateTime.now + 3600
     @user.should remember_token    
   end
-  
+
   it &quot;should set remember_token_expires_at to a specific date&quot; do
     time = Time.mktime(2009,12,25)
     @user.remember_me_until(time)
     @user.remember_token_expires_at.should == time    
   end
-  
+
   it &quot;should set the remember_me token when remembering&quot; do
     time = Time.mktime(2009,12,25)
     @user.remember_me_until(time)
@@ -216,7 +211,7 @@ describe User, &quot;remember_me&quot; do
     @user.save
     User.find_with_conditions(:login =&gt; valid_user_hash[:login]).remember_token.should_not be_nil
   end
-  
+
   it &quot;should remember me for&quot; do
     t = Time.now
     Time.stub!(:now).and_return(t)
@@ -225,14 +220,14 @@ describe User, &quot;remember_me&quot; do
     @user.remember_me_for( Merb::Const::WEEK * 2)
     @user.remember_token_expires_at.should == (remember_until)
   end
-  
+
   it &quot;should remember_me for two weeks&quot; do
     t = Time.now
     Time.stub!(:now).and_return(t)
     @user.remember_me
     @user.remember_token_expires_at.should == (Time.now + (2 * Merb::Const::WEEK ))
   end
-  
+
   it &quot;should forget me&quot; do
     @user.remember_me
     @user.save
@@ -240,19 +235,18 @@ describe User, &quot;remember_me&quot; do
     @user.remember_token.should be_nil
     @user.remember_token_expires_at.should be_nil    
   end
-  
+
   it &quot;should persist the forget me to the database&quot; do
     @user.remember_me
     @user.save
-    
+
     @user = User.find_with_conditions(:login =&gt; valid_user_hash[:login])
     @user.remember_token.should_not be_nil
-    
+
     @user.forget_me
 
     @user = User.find_with_conditions(:login =&gt; valid_user_hash[:login])
     @user.remember_token.should be_nil
     @user.remember_token_expires_at.should be_nil
   end
-  
 end
\ No newline at end of file</diff>
      <filename>spec/models/user_spec.rb</filename>
    </modified>
    <modified>
      <diff>@@ -2,14 +2,10 @@ $TESTING=true
 require 'rubygems'
 require 'merb-core'
 
-
-# TODO: Boot Merb, via the Test Rack adapter
-Merb.start :environment =&gt; (ENV['MERB_ENV'] || 'test'),
-           :merb_root  =&gt; File.join(File.dirname(__FILE__), &quot;..&quot; )
-
+Merb.start_environment :environment =&gt; (ENV['MERB_ENV'] || 'test'), :merb_root =&gt; File.join(File.dirname(__FILE__), &quot;..&quot; )
 
 Spec::Runner.configure do |config|
   config.include(Merb::Test::ViewHelper)
   config.include(Merb::Test::RouteHelper)
   config.include(Merb::Test::ControllerHelper)
-end
+end
\ No newline at end of file</diff>
      <filename>spec/spec_helper.rb</filename>
    </modified>
  </modified>
  <removed type="array">
    <removed>
      <filename>spec/controllers/sessions_spec.rb</filename>
    </removed>
    <removed>
      <filename>spec/controllers/users_spec.rb</filename>
    </removed>
  </removed>
  <parents type="array">
    <parent>
      <id>ff10a5ba6eacaa4a208b5b9c4f8341a4b9ff23be</id>
    </parent>
  </parents>
  <author>
    <name>El Draper</name>
    <email>el@eldiablo.co.uk</email>
  </author>
  <url>http://github.com/mbleigh/feather/commit/19632b010024424bd365b6e5cd66eb2548f838f4</url>
  <id>19632b010024424bd365b6e5cd66eb2548f838f4</id>
  <committed-date>2008-04-25T17:22:33-07:00</committed-date>
  <authored-date>2008-04-25T17:22:33-07:00</authored-date>
  <message>this tidies up various bits of the feather core code, and tries to employ a few common usage patterns across the codebase; also adds a few new event hooks, and gets all the current specs working, as well as adding a few new ones to kickstart the spec writing process</message>
  <tree>6368dfe27f4420abf4ddad32f8b7d8201fb2af32</tree>
  <committer>
    <name>El Draper</name>
    <email>el@eldiablo.co.uk</email>
  </committer>
</commit>
