<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array">
    <added>
      <filename>app/views/email_addresses/_email_address.html.erb</filename>
    </added>
    <added>
      <filename>app/views/email_addresses/_form.html.erb</filename>
    </added>
    <added>
      <filename>app/views/email_addresses/_standard.html.erb</filename>
    </added>
    <added>
      <filename>app/views/email_addresses/edit.html.erb</filename>
    </added>
    <added>
      <filename>app/views/email_addresses/index.html.erb</filename>
    </added>
    <added>
      <filename>app/views/email_addresses/new.html.erb</filename>
    </added>
    <added>
      <filename>app/views/email_addresses/show.html.erb</filename>
    </added>
    <added>
      <filename>app/views/users/_footer.html.erb</filename>
    </added>
    <added>
      <filename>app/views/users/_header.html.erb</filename>
    </added>
    <added>
      <filename>app/views/users/_standard.html.erb</filename>
    </added>
  </added>
  <modified type="array">
    <modified>
      <diff>@@ -1,2 +1,91 @@
 class EmailAddressesController &lt; ApplicationController
+	before_filter :staff_or_admin_required
+	before_filter :setup
+	
+	def index
+		@key = params[:key]
+		@max = params[:max].to_i
+		@max = 10 if @max &lt; 1
+		@page = params[:page].blank? ? nil : params[:page].to_i
+		@email_addresses = EmailAddress.paginate(
+			:per_page=&gt;@max, :page=&gt;@page, :order=&gt;EmailAddress.default_order,
+			:include=&gt;EmailAddress.default_include,
+			:conditions=&gt;EmailAddress.search_conditions(
+				{:item=&gt;@user, :u=&gt;current_user, :key=&gt;@key})
+			)
+		@page_title += 'Email Addresses'
+		@page_title += &quot;: &#8216;#{@key}&#8217;&quot; unless @key.blank?
+		@page_title += &quot; (#{@page})&quot; if @page and @page &gt; 1
+	end
+	
+	def show
+		@email_address = EmailAddress.find(params[:id])
+		@page_title += &quot;Email Address #{@email_address.id}&quot;
+	rescue ActiveRecord::RecordNotFound
+		missing
+	end
+	
+	def new
+		pre_new
+	end
+	
+	def create
+		pre_new
+		@email_address.save!
+		flash[:notice] = 'Email Address saved.'
+		redirect_to :action=&gt;'show', :id=&gt;@email_address
+	rescue ActiveRecord::RecordInvalid
+		render :action=&gt;:new
+	end
+	
+	def edit
+		@email_address = EmailAddress.find(params[:id])
+		@page_title += &quot;Edit Email Address #{@email_address.id}&quot;
+	rescue ActiveRecord::RecordNotFound
+		missing
+	end
+	
+	def update
+		@email_address = EmailAddress.find(params[:id])
+		if params[:email_address] &amp;&amp; params[:email_address].size &gt; 0
+			@email_address.update_attributes!(params[:email_address])
+			flash[:notice] = 'Email Address updated.'
+			redirect_to :action=&gt;'show', :id=&gt;@email_address
+		else
+			# no changes to save, back to edit form
+			render :action=&gt;:edit
+		end
+	rescue ActiveRecord::RecordInvalid
+		render :action=&gt;:edit
+	rescue ActiveRecord::RecordNotFound
+		missing
+	end
+	
+	def destroy
+		@email_address = EmailAddress.find(params[:id])
+		@email_address.destroy
+		flash[:notice] = &quot;The email address &#8216;#{@email_address.email}&#8217; has been permanently removed.&quot;
+		redirect_to :action=&gt;:index
+	rescue ActiveRecord::RecordNotFound
+		missing
+	end
+	
+	protected
+	
+	def setup
+		if params[:user_id].blank?
+			@user = nil
+		else
+			@user = User.find(params[:user_id]) # rescue ActiveRecord::RecordNotFound
+		end
+		@section = 'contacts'
+		@page_title = @user.nil? ? '' : &quot;#{@user.title}: &quot;
+	end
+	
+	def pre_new
+		@email_address = EmailAddress.new(params[:email_address])
+		@email_address.user = @user
+		@page_title += &quot;New Email Address&quot;
+	end
+	
 end</diff>
      <filename>app/controllers/email_addresses_controller.rb</filename>
    </modified>
    <modified>
      <diff>@@ -18,7 +18,7 @@ class MembershipsController &lt; ApplicationController
 	
 	def show
 		@membership = @group.memberships.find(params[:id])
-		@page_title = &quot;#{@group.name} Membership for #{member_name(@membership)}&quot;
+		@page_title = &quot;#{@group.name} Membership for #{h(@membership.member_name(current_user))}&quot;
 	rescue ActiveRecord::RecordNotFound
 		missing
 	end
@@ -51,7 +51,7 @@ class MembershipsController &lt; ApplicationController
 	
 	def edit
 		@membership = Membership.find(params[:id])
-		@page_title = &quot;Edit Membership for #{member_name(@membership)}&quot;
+		@page_title = &quot;Edit Membership for #{h(@membership.member_name(current_user))}&quot;
 	rescue ActiveRecord::RecordNotFound
 		missing
 	end
@@ -62,7 +62,7 @@ class MembershipsController &lt; ApplicationController
 			# can&#8217;t update - was caught in edit
 		else
 			if params[:membership] &amp;&amp; params[:membership].size &gt; 0 &amp;&amp; @membership.update_attributes(params[:membership])
-				flash[:notice] = &quot;Updated membership information for #{member_name(@membership)}.&quot;
+				flash[:notice] = &quot;Updated membership information for #{h(@membership.member_name(current_user))}.&quot;
 				redirect_to group_membership_path(@group, @membership)
 			else
 				# failed to save, back to edit form
@@ -74,7 +74,7 @@ class MembershipsController &lt; ApplicationController
 	def destroy
 		@membership = Membership.find(params[:id], :include=&gt;:user)
 		@membership.destroy
-		flash[:notice] = &quot;The membership for &#8216;#{member_name(@membership)}&#8217; has been permanently removed.&quot;
+		flash[:notice] = &quot;The membership for &#8216;#{h(@membership.member_name(current_user))}&#8217; has been permanently removed.&quot;
 		redirect_to group_memberships_path(@group)
 	rescue ActiveRecord::RecordNotFound
 		missing
@@ -140,20 +140,7 @@ class MembershipsController &lt; ApplicationController
 			render :action=&gt;:bulk
 		end
 	end
-	
-	
-	def member_name(membership)
-		name = &quot;member #{membership.id}&quot;
-		if membership.user
-			name = h(membership.user.display_name_for_admin(
-				membership.group.has_access_to?(:admin, current_user)
-			))
-		elsif membership.group.has_access_to?(:admin, current_user) and !(membership.email_address.name.blank?)
-			name = h(membership.email_address.name)
-		end
-		name
-	end
-	
+		
 	
 	protected
 	</diff>
      <filename>app/controllers/memberships_controller.rb</filename>
    </modified>
    <modified>
      <diff>@@ -86,6 +86,33 @@ class EmailAddress &lt; ActiveRecord::Base
 		end
 	end
 	
+	# standard Wayground class methods for displayable items
+	def self.default_include
+		[:user]
+	end
+	def self.default_order(p={})
+		(p[:recent].blank? ? '' : 'email_addresses.updated_at DESC, ') +
+			'email_addresses.email'
+	end
+	# Returns a conditions array for find.
+	# p is a hash of parameters:
+	# - :key is a search restriction key
+	# - :u is the current_user to use to determine access to private items.
+	# - :item is the Item the message is attached to
+	# strs is a list of condition strings (with &#8216;?&#8217; for params) to be joined by &#8220;AND&#8221;
+	# vals is a list of condition values to be appended to the result array (matching &#8216;?&#8217; in the strs)
+	def self.search_conditions(p={}, strs=[], vals=[])
+		unless p[:item].nil?
+			strs &lt;&lt; 'email_addresses.user_id = ?'
+			vals &lt;&lt; p[:item].id
+		end
+		unless p[:key].blank?
+			strs &lt;&lt; '(email_addresses.email like ? OR email_addresses.name like ?)'
+			vals += [&quot;%#{p[:key]}%&quot;] * 2
+		end
+		strs.size &gt; 0 ? [strs.join(' AND ')] + vals : nil
+	end
+	
 	
 	# INSTANCE METHODS
 	
@@ -188,4 +215,25 @@ class EmailAddress &lt; ActiveRecord::Base
 			&quot;#{self.name} &lt;#{self.email}&gt;&quot;
 		end
 	end
+	
+	# standard Wayground instance methods for displayable items
+	def css_class(prefix='')
+		&quot;#{prefix}contact&quot;
+	end
+	def description
+		nil
+	end
+	def link
+		&quot;/email_addresses/#{self.id}&quot;
+	end
+	def title
+		if self.name.blank?
+			&quot;Contact #{self.id}&quot;
+		else
+			self.name
+		end
+	end
+	def title_prefix
+		nil
+	end
 end</diff>
      <filename>app/models/email_address.rb</filename>
    </modified>
    <modified>
      <diff>@@ -124,8 +124,8 @@ class Membership &lt; ActiveRecord::Base
 	end
 	
 	def make_active!
-		invited_at = nil
-		expires_at = nil if expired?
+		self.invited_at = nil
+		self.expires_at = nil if expired?
 		clear_block! # saves
 	end
 	
@@ -168,11 +168,11 @@ class Membership &lt; ActiveRecord::Base
 	end
 	
 	def expired?
-		!(expires_at.nil?) &amp;&amp; (expires_at &lt;= Time.current)
+		!(self.expires_at.nil?) &amp;&amp; (self.expires_at &lt;= Time.current)
 	end
 	
 	def invited?
-		!(invited_at.nil?)
+		!(self.invited_at.nil?)
 	end
 	
 	# s - a symbol or an array of symbols (which any of which matching will return true)
@@ -180,18 +180,18 @@ class Membership &lt; ActiveRecord::Base
 		if s.is_a? Symbol
 			s = [s]
 		end
-		has_access = (is_admin or user == group.owner)
+		has_access = (self.is_admin or self.user == self.group.owner)
 		unless has_access
 			s.each do |sym|
 				case sym
 				when :self_join
 					has_access ||= (!(active?) and (invited? or !(group.is_invite_only)))
 				when :member_list
-					has_access ||= (active? and (can_manage_members or group.is_members_visible))
+					has_access ||= (active? and (self.can_manage_members or self.group.is_members_visible))
 				when :manage_members
-					has_access ||= (active? and can_manage_members)
+					has_access ||= (active? and self.can_manage_members)
 				when :inviting
-					has_access ||= (active? and can_invite)
+					has_access ||= (active? and self.can_invite)
 				when :admin
 					# covered by default has_access set when user is_admin or group.owner
 				else
@@ -203,10 +203,40 @@ class Membership &lt; ActiveRecord::Base
 	end
 	
 	def email
-		if email_address
-			email_address.email
+		if self.email_address
+			self.email_address.email
 		else
-			user.email
+			self.user.email
+		end
+	end
+	
+	def name
+		if self.user
+			self.user.nickname
+		else
+			self.email_address.name
+		end
+	end
+	
+	def member_name(user=nil)
+		name = &quot;member #{self.id}&quot;
+		unless user.nil?
+			if self.user
+				name = self.user.display_name_for_admin(
+					self.group.has_access_to?(:admin, user)
+				)
+			elsif self.group.has_access_to?(:admin, user) and !(self.email_address.name.blank?)
+				name = self.email_address.name
+			end
+		end
+		name
+	end
+	
+	def link
+		if self.user
+			self.user.link
+		else
+			self.email_address.link
 		end
 	end
 end</diff>
      <filename>app/models/membership.rb</filename>
    </modified>
    <modified>
      <diff>@@ -10,7 +10,7 @@ unless @group.nil?
 &lt;%= render :partial=&gt;'email_message', :collection=&gt;@email_messages %&gt;
 &lt;/tbody&gt;&lt;/table&gt;
 
-&lt;%= will_paginate @events, :params=&gt;params %&gt;
+&lt;%= will_paginate @email_messages, :params=&gt;params %&gt;
 
 &lt;%
 if @group.nil?</diff>
      <filename>app/views/email_messages/index.html.erb</filename>
    </modified>
    <modified>
      <diff>@@ -1,7 +1,7 @@
 &lt;%
 membership ||= @membership
 row_id ||= &quot;membership_#{membership.id}&quot;
-member_name = controller.member_name(membership)
+member_name = h membership.member_name(current_user)
 
 -%&gt;
 &lt;tr id=&quot;&lt;%= row_id%&gt;&quot;&lt;%= cycle '', ' class=&quot;alternate&quot;' %&gt;&gt;&lt;td&gt;&lt;%
@@ -11,7 +11,11 @@ else
 	%&gt;&lt;img src=&quot;/icon/contact.png&quot; alt=&quot;Member:&quot; width=&quot;16&quot; height=&quot;16&quot; class=&quot;icon&quot; title=&quot;Group Member&quot; /&gt;&lt;%
 end
 %&gt;&lt;/td&gt;
-&lt;td&gt;&lt;%= link_to member_name, group_membership_path(membership.group, membership) %&gt;&lt;/td&gt;
+&lt;td&gt;&lt;%= link_to member_name, group_membership_path(membership.group, membership) %&gt;&lt;%
+unless membership.title.blank? %&gt;
+(&lt;%= h membership.title %&gt;)&lt;%
+end
+%&gt;&lt;/td&gt;
 &lt;td&gt;&lt;%=
 link_to('&lt;img src=&quot;/icon/edit.png&quot; width=&quot;16&quot; height=&quot;16&quot; alt=&quot;Edit&quot; class=&quot;diricon&quot; /&gt;',
 	edit_group_membership_path(membership.group, membership),</diff>
      <filename>app/views/memberships/_membership.html.erb</filename>
    </modified>
    <modified>
      <diff>@@ -5,7 +5,7 @@ subsection ||= @subsection || 'member'
 
 &lt;div class=&quot;steps&quot;&gt;
 &lt;h2&gt;&lt;img src=&quot;/icon/edit_24.png&quot; width=&quot;24&quot; height=&quot;24&quot; alt=&quot; &quot; class=&quot;icon&quot; /&gt;
-Edit Membership for &lt;%= controller.member_name(@membership) %&gt;&lt;/h2&gt;
+Edit Membership for &lt;%= h @membership.member_name %&gt;&lt;/h2&gt;
 &lt;% #= error_messages_for :membership 
 %&gt;
 &lt;div class=&quot;step_form&quot;&gt;</diff>
      <filename>app/views/memberships/edit.html.erb</filename>
    </modified>
    <modified>
      <diff>@@ -4,7 +4,7 @@ subsection ||= @subsection || 'member'
 %&gt;&lt;%= render :partial=&gt;'groups/header', :locals=&gt;{:subsection=&gt;subsection} %&gt;
 
 &lt;div&gt;&lt;img src=&quot;/icon/contact.png&quot; alt=&quot; &quot; width=&quot;16&quot; height=&quot;16&quot; class=&quot;icon&quot; align=&quot;left&quot; /&gt;
-&lt;div style=&quot;float:left&quot;&gt;&lt;h2&gt;&lt;%= link_to @membership.user.nickname, @membership.user.link %&gt;&lt;/h2&gt;
+&lt;div style=&quot;float:left&quot;&gt;&lt;h2&gt;&lt;%= link_to @membership.name, @membership.link %&gt;&lt;/h2&gt;
 &lt;%
 titles = []
 titles &lt;&lt; 'Group Owner' if @membership.user == @group.owner
@@ -23,7 +23,7 @@ link_to('&lt;img src=&quot;/icon/edit.png&quot; width=&quot;16&quot; height=&quot;16&quot; alt=&quot; &quot; class=&quot;diricon
 			' alt=&quot; &quot; class=&quot;diricon&quot; /&gt; Remove Member',
 		group_membership_path(@membership.group, @membership),
 		{:method=&gt;'delete',
-		:confirm=&gt;&quot;Are you sure you want to remove this member, #{@membership.user.nickname}, from the group &#8220;#{@membership.group.name}&#8221;?&quot;,
+		:confirm=&gt;&quot;Are you sure you want to remove this member, #{@membership.name}, from the group &#8220;#{@membership.group.name}&#8221;?&quot;,
 		:href=&gt;group_membership_path(@membership.group, @membership),
 		:class=&gt;'button', :title=&gt;&quot;remove this member from the group&quot;
 		} %&gt;&lt;span class=&quot;separator&quot;&gt;.&lt;/span&gt;&lt;%
@@ -34,6 +34,8 @@ User is blocked from accessing the group.&lt;/p&gt;
 &lt;% elsif @membership.invited?
 	%&gt;&lt;p style=&quot;clear:left&quot;&gt;&lt;img src=&quot;/icon/warning.png&quot; alt=&quot; &quot; width=&quot;16&quot; height=&quot;16&quot; class=&quot;icon&quot; /&gt;
 User has been invited to, but has not yet joined, the group.&lt;/p&gt;
+&lt;% else
+	%&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
 &lt;% end
 %&gt;&lt;/div&gt;
 </diff>
      <filename>app/views/memberships/show.html.erb</filename>
    </modified>
    <modified>
      <diff>@@ -47,6 +47,7 @@ ActionController::Routing::Routes.draw do |map|
 	map.resources :users, :collection=&gt;{:activate=&gt;:get, :account=&gt;:get} do |users|
 		users.resources :email_addresses
 	end
+	map.resources :email_addresses
 	
 	# PAGES
 	# special path: the home page</diff>
      <filename>config/routes.rb</filename>
    </modified>
    <modified>
      <diff>@@ -8,14 +8,31 @@ one:
   name: Extra Address For Login
 
 two:
-  user: admin
+  user: 
   position: 2
   email: extra-regular+test@wayground.ca
   activation_code: 
   activated_at: 2009-02-04 14:59:26
   is_blocked: false
-  name: Extra Address For Regular
+  name: 
+
+searchable_email:
+  user: 
+  position: 0
+  email: keyword+test@wayground.ca
+  activation_code: 
+  activated_at: 2009-02-04 14:59:26
+  is_blocked: false
+  name: 
 
+searchable_name:
+  user: 
+  position: 0
+  email: searchable+test@wayground.ca
+  activation_code: 
+  activated_at: 2009-02-04 14:59:26
+  is_blocked: false
+  name: Address has keyword
 
 login:
   user: login
@@ -87,7 +104,7 @@ regular:
   activation_code: 
   activated_at: &lt;%= 1.day.ago.to_s(:db) %&gt;
   is_blocked: false
-  name:
+  name: Regular
 
 another:
   user: another</diff>
      <filename>test/fixtures/email_addresses.yml</filename>
    </modified>
    <modified>
      <diff>@@ -16,9 +16,289 @@ class EmailAddressesControllerTest &lt; ActionController::TestCase
 		#	users.resources :email_addresses
 		#end
 		assert_routing_for_resources 'email_addresses', [], ['user'], {}, {}
+		#map.resources :email_addresses
+		assert_routing_for_resources 'email_addresses'
 	end
 	
 	
 	# ACTIONS
 	
+	# TODO: access restriction tests for email addresses controller
+	
+	# INDEX
+	test &quot;index&quot; do
+		#assert_efficient_sql do
+			get :index, {}, {:user=&gt;users(:admin).id}
+		#end
+		assert_equal 10, assigns(:email_addresses).size
+		assert_nil assigns(:user)
+		assert_equal 'contacts', assigns(:section)
+		assert_equal 'Email Addresses', assigns(:page_title)
+		assert_nil flash[:notice]
+		assert_response :success
+		# view result
+		assert_template 'index'
+		assert_select 'div#flash:empty'
+		assert_select 'div#content' do
+			# TODO: test html content for index
+			assigns(:email_addresses).each do |e|
+				assert_select &quot;tr#email_address_#{e.id}&quot;
+			end
+		end
+	end
+	test &quot;index pagination&quot; do
+		get :index, {:page=&gt;&quot;2&quot;}, {:user=&gt;users(:admin).id}
+		assert_equal 7, assigns(:email_addresses).size
+		assert_equal 'Email Addresses (2)', assigns(:page_title)
+	end
+	test &quot;index search&quot; do
+		get :index, {:key=&gt;'keyword'}, {:user=&gt;users(:admin).id}
+		assert_equal 2, assigns(:email_addresses).size
+		assert_equal 'contacts', assigns(:section)
+		assert_equal 'Email Addresses: &#8216;keyword&#8217;', assigns(:page_title)
+		assert_nil flash[:notice]
+		assert_response :success
+	end
+	test &quot;index for user&quot; do
+		#assert_efficient_sql do
+			get :index, {:user_id=&gt;email_addresses(:one).user.id}, {:user=&gt;users(:admin).id}
+		#end
+		assert_equal email_addresses(:one).user, assigns(:user)
+		assert_equal 2, assigns(:email_addresses).size
+		assert_equal 'contacts', assigns(:section)
+		assert_equal(&quot;#{email_addresses(:one).user.title}: Email Addresses&quot;,
+			assigns(:page_title))
+		assert_nil flash[:notice]
+		assert_response :success
+		# view result
+		assert_template 'index'
+		assert_select 'div#flash:empty'
+		assert_select 'div#content' do
+			# TODO: test html content for index for user
+			assigns(:email_addresses).each do |e|
+				assert_select &quot;tr#email_address_#{e.id}&quot;
+			end
+		end
+	end
+	
+	# SHOW
+	test &quot;show&quot; do
+		assert_efficient_sql do
+			get :show, {:id=&gt;email_addresses(:one).id}, {:user=&gt;users(:admin).id}
+		end
+		assert_equal email_addresses(:one), assigns(:email_address)
+		assert_equal 'contacts', assigns(:section)
+		assert_equal(&quot;Email Address #{email_addresses(:one).id}&quot;, assigns(:page_title))
+		assert_nil flash[:notice]
+		assert_response :success
+		# view result
+		assert_template 'show'
+		assert_select 'div#flash:empty'
+		assert_select 'div#content' do
+			assert_select 'p', h(email_addresses(:one).to_s)
+		end
+	end
+	test &quot;show invalid id&quot; do
+		#assert_efficient_sql do
+			get :show, {:id=&gt;'0'}, {:user=&gt;users(:admin).id}
+		#end
+		assert_response :missing
+		assert_nil assigns(:email_address)
+		assert_nil flash[:notice]
+		assert flash[:error]
+		assert_template 'paths/missing'
+	end
+	test &quot;show for user&quot; do
+		assert_efficient_sql do
+			get :show,
+				{:user_id=&gt;email_addresses(:one).user.id, :id=&gt;email_addresses(:one).id},
+				{:user=&gt;users(:admin).id}
+		end
+		assert_equal email_addresses(:one).user, assigns(:user)
+		assert_equal email_addresses(:one), assigns(:email_address)
+		assert_equal 'contacts', assigns(:section)
+		assert_equal(&quot;#{email_addresses(:one).user.title}: Email Address #{email_addresses(:one).id}&quot;,
+			assigns(:page_title))
+		assert_nil flash[:notice]
+		assert_response :success
+		# view result
+		assert_template 'show'
+		assert_select 'div#flash:empty'
+		assert_select 'div#content' do
+			assert_select 'p', h(email_addresses(:one).to_s)
+		end
+	end
+	
+	# NEW
+	test &quot;new&quot; do
+		get :new, {}, {:user=&gt;users(:admin).id}
+		assert assigns(:email_address)
+		assert_equal 'contacts', assigns(:section)
+		assert_equal 'New Email Address', assigns(:page_title)
+		assert_nil flash[:notice]
+		assert_response :success
+		# view result
+		assert_template 'new'
+		assert_select 'div#flash:empty'
+		assert_select 'div#content' do
+			assert_select &quot;form[action=#{email_addresses_path}]&quot; do
+				assert_select 'input#email_address_name'
+				assert_select 'input#email_address_email'
+			end
+		end
+	end
+	
+	# CREATE
+	test &quot;create&quot; do
+		assert_difference(EmailAddress, :count, 1) do
+			post :create, {:email_address=&gt;{:email=&gt;'create+test@wayground.ca',
+				:name=&gt;'Test Create Email Address'}},
+				{:user=&gt;users(:admin).id}
+		end
+		assert assigns(:email_address).is_a?(EmailAddress)
+		assert flash[:notice]
+		assert_response :redirect
+		assert_redirected_to({:action=&gt;'show', :id=&gt;assigns(:email_address)})
+		# cleanup
+		assigns(:email_address).destroy
+	end
+	test &quot;create no params&quot; do
+		assert_difference(EmailAddress, :count, 0) do
+			post :create, {}, {:user=&gt;users(:admin).id}
+		end
+		# this basically returns the same as a call to new,
+		# with the addition of a validation error list in the view
+		assert_validation_errors_on(assigns(:email_address), ['email'])
+		assert_equal 'contacts', assigns(:section)
+		assert_equal 'New Email Address', assigns(:page_title)
+		assert_nil flash[:notice]
+		assert_response :success
+		# view result
+		assert_template 'new'
+		assert_select 'div#flash:empty'
+		assert_select 'div#content' do
+			assert_select &quot;form[action=#{email_addresses_path}]&quot;
+		end
+	end
+	test &quot;create bad params&quot; do
+		assert_difference(EmailAddress, :count, 0) do
+			post :create, {:email_address=&gt;{:email=&gt;'bad email', :name=&gt;'Test Bad Params',}},
+				{:user=&gt;users(:admin).id}
+		end
+		# this basically returns the same as a call to new,
+		# with the addition of a validation error list in the view
+		assert_validation_errors_on(assigns(:email_address), ['email'])
+		assert_equal 'contacts', assigns(:section)
+		assert_equal 'New Email Address', assigns(:page_title)
+		assert_nil flash[:notice]
+		assert_response :success
+		# view result
+		assert_template 'new'
+		assert_select 'div#flash:empty'
+		assert_select 'div#content' do
+			assert_select &quot;form[action=#{email_addresses_path}]&quot;
+		end
+	end
+	
+	# EDIT
+	test &quot;edit&quot; do
+		get :edit, {:id=&gt;email_addresses(:one).id}, {:user=&gt;users(:admin).id}
+		assert_equal email_addresses(:one), assigns(:email_address)
+		assert_equal 'contacts', assigns(:section)
+		assert_equal &quot;Edit Email Address #{email_addresses(:one).id}&quot;,
+			assigns(:page_title)
+		assert_nil flash[:notice]
+		assert_response :success
+		# view result
+		assert_template 'edit'
+		assert_select 'div#flash:empty'
+		assert_select 'div#content' do
+			assert_select &quot;form[action='#{email_addresses_path}/#{email_addresses(:one).id}']&quot; do
+				assert_select 'input#email_address_name'
+				assert_select 'input#email_address_email'
+			end
+		end
+	end
+	
+	# UPDATE
+	test &quot;update&quot; do
+		put :update, {:id=&gt;email_addresses(:two).id,
+				:email_address=&gt;{:email=&gt;'update-changes+email@wayground.ca',
+					:name=&gt;'Changed Email by Update'}
+			},
+			{:user=&gt;users(:admin).id}
+		assert_equal email_addresses(:two), assigns(:email_address)
+		assert_equal 'Changed Email by Update', assigns(:email_address).name
+		assert_equal 'update-changes+email@wayground.ca', assigns(:email_address).email
+		assert flash[:notice]
+		assert_response :redirect
+		assert_redirected_to({:action=&gt;'show', :id=&gt;assigns(:email_address)})
+	end
+	test &quot;update invalid params&quot; do
+		original_email = email_addresses(:two).email
+		put :update, {:id=&gt;email_addresses(:two).id,
+			:email_address=&gt;{:email=&gt;'invalid email'}},
+			{:user=&gt;users(:admin).id}
+		assert_equal email_addresses(:two), assigns(:email_address)
+		assert_validation_errors_on(assigns(:email_address), ['email'])
+		# email_address was not updated
+		assert_equal original_email, email_addresses(:two).email
+		assert_nil flash[:notice]
+		assert_response :success
+		# view result
+		assert_template 'edit'
+		assert_select 'div#flash:empty'
+		assert_select 'div#content' do
+			assert_select &quot;form[action='#{email_addresses_path}/#{email_addresses(:two).id}']&quot;
+		end
+	end
+	test &quot;update no params&quot; do
+		original_email = email_addresses(:two).email
+		put :update, {:id=&gt;email_addresses(:two).id, :email_address=&gt;{}},
+			{:user=&gt;users(:admin).id}
+		assert_equal email_addresses(:two), assigns(:email_address)
+		# email_address was not updated
+		assert_equal original_email, email_addresses(:two).email
+		assert_nil flash[:notice]
+		assert_response :success
+		# view result
+		assert_template 'edit'
+		assert_select 'div#flash:empty'
+		assert_select 'div#content' do
+			assert_select &quot;form[action='#{email_addresses_path}/#{email_addresses(:two).id}']&quot;
+		end
+	end
+	
+	# DESTROY
+	test &quot;destroy&quot; do
+		# create a email_address to be destroyed
+		email_address = nil
+		assert_difference(EmailAddress, :count, 1) do
+			email_address = EmailAddress.new(
+				{:name=&gt;'Delete Email Address', :email=&gt;'delete+test@wayground.ca'})
+			email_address.save!
+		end
+		# destroy the email_address (and it's thumbnail)
+		assert_difference(EmailAddress, :count, -1) do
+			delete :destroy, {:id=&gt;email_address.id}, {:user=&gt;users(:admin).id}
+		end
+		assert flash[:notice]
+		assert_response :redirect
+		assert_redirected_to email_addresses_path
+	end
+	test &quot;destroy with invalid id&quot; do
+		assert_difference(EmailAddress, :count, 0) do
+			delete :destroy, {:id=&gt;'invalid'}, {:user=&gt;users(:admin).id}
+		end
+		assert_nil assigns(:email_address)
+		assert_nil flash[:notice]
+		assert flash[:error]
+		assert_response :missing
+		assert_template 'paths/missing'
+	end
+	test &quot;destroy with no id&quot; do
+		assert_raise(ActionController::RoutingError) do
+			delete :destroy, {}, {:user=&gt;users(:admin).id}
+		end
+	end
 end</diff>
      <filename>test/functional/email_addresses_controller_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -95,7 +95,10 @@ class MembershipsControllerTest &lt; ActionController::TestCase
 		assert_equal 'groups', assigns(:section)
 		assert_equal groups(:membered_group), assigns(:group)
 		assert assigns(:membership)
-		assert_equal(&quot;#{assigns(:group).name} Membership for #{assigns(:membership).user.nickname}&quot;, assigns(:page_title))
+		assert_equal(
+			&quot;#{assigns(:group).name} Membership for member #{assigns(:membership).id}&quot;,
+			assigns(:page_title)
+		)
 		assert_nil flash[:notice]
 		# view result
 		assert_template 'show'
@@ -400,7 +403,7 @@ class MembershipsControllerTest &lt; ActionController::TestCase
 		assert_select 'div#flash:empty'
 		assert_select 'div#content' do
 			assert_select 'h1', assigns(:group).name
-			assert_select 'h2', &quot;Edit Membership for #{assigns(:membership).user.fullname}&quot;
+			assert_select 'h2', &quot;Edit Membership for member #{assigns(:membership).id}&quot;
 			assert_select &quot;form[action='#{group_membership_path(assigns(:group), assigns(:membership))}']&quot; do
 				assert_select 'input#membership_user_id', false,
 					'Edit form should not contain the user id'
@@ -528,7 +531,7 @@ class MembershipsControllerTest &lt; ActionController::TestCase
 		assert_select 'div#flash:empty'
 		assert_select 'div#content' do
 			assert_select 'h1', assigns(:group).name
-			assert_select 'h2', &quot;Edit Membership for #{assigns(:membership).user.fullname}&quot;
+			assert_select 'h2', &quot;Edit Membership for member #{assigns(:membership).id}&quot;
 			assert_select &quot;form[action='#{group_membership_path(assigns(:group), assigns(:membership))}']&quot; do
 				assert_select 'input#membership_user_id', false,
 					'Edit form should not contain the user id'</diff>
      <filename>test/functional/memberships_controller_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -89,6 +89,43 @@ class EmailAddressTest &lt; ActiveSupport::TestCase
 		assert_nil u.email
 	end
 	
+	test &quot;default include&quot; do
+		assert_equal [:user], EmailAddress.default_include
+	end
+	
+	test &quot;default order&quot; do
+		assert_equal 'email_addresses.email', EmailAddress.default_order
+	end
+	test &quot;default order with recent&quot; do
+		assert_equal 'email_addresses.updated_at DESC, email_addresses.email',
+			EmailAddress.default_order({:recent=&gt;true})
+	end
+	
+	test &quot;search conditions&quot; do
+		assert_nil EmailAddress.search_conditions
+	end
+	test &quot;search conditions with custom params&quot; do
+		assert_equal ['a AND b',1,2], EmailMessage.search_conditions({}, ['a','b'], [1,2])
+	end
+	test &quot;search conditions with item&quot; do
+		assert_equal(['email_addresses.user_id = ?', users(:login).id],
+			EmailAddress.search_conditions({:item=&gt;users(:login)})
+		)
+	end
+	test &quot;search conditions with key&quot; do
+		assert_equal(['(email_addresses.email like ? OR email_addresses.name like ?)',
+				'%keyword%', '%keyword%'],
+			EmailAddress.search_conditions({:key=&gt;'keyword'})
+		)
+	end
+	test &quot;search conditions with all params&quot; do
+		assert_equal ['a AND b AND email_addresses.user_id = ?' +
+			' AND (email_addresses.email like ? OR email_addresses.name like ?)',
+			1, 2, users(:login).id, '%keyword%', '%keyword%'],
+		EmailAddress.search_conditions(
+			{:item=&gt;users(:login), :key=&gt;'keyword'}, ['a','b'], [1,2])
+	end
+	
 	
 	# INSTANCE METHODS
 	
@@ -265,4 +302,32 @@ class EmailAddressTest &lt; ActiveSupport::TestCase
 		e = EmailAddress.new(:email=&gt;email, :name=&gt;name)
 		assert_equal &quot;\&quot;#{name}\&quot; &lt;#{email}&gt;&quot;, e.to_s
 	end
+	
+	test &quot;css class&quot; do
+		assert_equal 'contact', email_addresses(:login).css_class
+	end
+	test &quot;css class with prefix&quot; do
+		assert_equal 'dir-contact', email_addresses(:login).css_class('dir-')
+	end
+	
+	test &quot;description&quot; do
+		assert_nil email_addresses(:login).description
+	end
+	
+	test &quot;link&quot; do
+		assert_equal &quot;/email_addresses/#{email_addresses(:login).id}&quot;,
+			email_addresses(:login).link
+	end
+	
+	test &quot;title with name&quot; do
+		assert_equal email_addresses(:one).name, email_addresses(:one).title
+	end
+	test &quot;title with no name&quot; do
+		assert_equal &quot;Contact #{email_addresses(:two).id}&quot;,
+			email_addresses(:two).title
+	end
+	
+	test &quot;title prefix&quot; do
+		assert_nil email_addresses(:login).title_prefix
+	end
 end</diff>
      <filename>test/unit/email_address_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -8,7 +8,7 @@ class Membership &lt; ActiveRecord::Base
 end
 
 class MembershipTest &lt; ActiveSupport::TestCase
-	fixtures :memberships, :groups, :users, :locations
+	fixtures :memberships, :groups, :users, :email_addresses, :locations
 	
 	def test_membership_associations
 		assert check_associations
@@ -224,4 +224,37 @@ class MembershipTest &lt; ActiveSupport::TestCase
 		membership.email_address = addr
 		assert_equal 'location-test@wayground.ca', membership.email
 	end
+	
+	def test_membership_name
+		assert_equal 'Regular', memberships(:regular).name
+	end
+	def test_membership_name_with_no_user
+		m = Membership.new
+		m.email_address = email_addresses(:regular)
+		assert_equal 'Regular', m.name
+	end
+	
+	def test_membership_member_name
+		assert_equal &quot;member #{memberships(:regular).id}&quot;, memberships(:regular).member_name
+	end
+	def test_membership_member_name_with_admin
+		assert_equal users(:regular).fullname,
+			memberships(:regular).member_name(users(:admin))
+	end
+	def test_membership_member_name_with_admin_and_no_user
+		m = Membership.new
+		m.group = groups(:one)
+		m.email_address = email_addresses(:regular)
+		assert_equal 'Regular', m.member_name(users(:admin))
+	end
+	
+	def test_membership_link
+		m = Membership.new
+		m.email_address = email_addresses(:regular)
+		assert_equal email_addresses(:regular).link, m.link
+	end
+	def test_membership_link_with_user
+		assert_equal users(:regular).link, memberships(:regular).link
+	end
+	
 end</diff>
      <filename>test/unit/membership_test.rb</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>4058ba4c8f9a893da62f355acde991f401e1245b</id>
    </parent>
  </parents>
  <author>
    <name>Grant Neufeld</name>
    <email>grant@grantneufeld.ca</email>
  </author>
  <url>http://github.com/grantneufeld/wayground/commit/7f6ec30bb897e0f5eace60f9642b1e04e0e709e7</url>
  <id>7f6ec30bb897e0f5eace60f9642b1e04e0e709e7</id>
  <committed-date>2009-03-03T12:15:19-08:00</committed-date>
  <authored-date>2009-03-03T12:15:19-08:00</authored-date>
  <message>email addresses controller - now working

The email addresses controller now works (/email_addresses or /user/email_addresses).

Made some fixes and additions to EmailAddress and Membership (including the memberships controllers and views) to get this working.

Started implementing support for sub-sections for the users controller (like with the groups controller). Still need to put content in the views/users/ partial templates for header, footer and standard.</message>
  <tree>96fff2c5e90792c2e16bf71e04fdf3834dd51a7d</tree>
  <committer>
    <name>Grant Neufeld</name>
    <email>grant@grantneufeld.ca</email>
  </committer>
</commit>
