spec/ezmlm/list_spec.rb
changeset 12 3cc813140c80
parent 6 66beb495a861
child 14 cba9fb39bcdb
equal deleted inserted replaced
11:7fc2d1713795 12:3cc813140c80
     1 #!/usr/bin/env ruby
     1 #!/usr/bin/env ruby
     2 
     2 
     3 BEGIN {
     3 BEGIN {
     4 	require 'pathname'
     4 	require 'pathname'
     5 	basedir = Pathname.new( __FILE__ ).dirname.parent.parent
     5 	basedir = Pathname.new( __FILE__ ).dirname.parent.parent
     6 	
       
     7 	libdir = basedir + "lib"
     6 	libdir = basedir + "lib"
     8 	
       
     9 	$LOAD_PATH.unshift( libdir ) unless $LOAD_PATH.include?( libdir )
     7 	$LOAD_PATH.unshift( libdir ) unless $LOAD_PATH.include?( libdir )
    10 }
     8 }
    11 
     9 
    12 
    10 require_relative '../spec_helpers'
    13 begin
    11 require 'ezmlm'
    14 	require 'tmail'
       
    15 	require 'spec/runner'
       
    16 	require 'spec/lib/helpers'
       
    17 	require 'ezmlm/list'
       
    18 rescue LoadError
       
    19 	unless Object.const_defined?( :Gem )
       
    20 		require 'rubygems'
       
    21 		retry
       
    22 	end
       
    23 	raise
       
    24 end
       
    25 
       
    26 
    12 
    27 describe Ezmlm::List do
    13 describe Ezmlm::List do
    28 	include Ezmlm::SpecHelpers
       
    29 
       
    30 
    14 
    31 	# Testing constants
    15 	# Testing constants
    32 	TEST_LISTDIR               = Pathname.new( 'list' )
    16 	TEST_LISTDIR               = Pathname.new( 'list' )
    33 	TEST_LIST_NAME             = 'waffle-lovers'
    17 	TEST_LIST_NAME             = 'waffle-lovers'
    34 	TEST_LIST_HOST             = 'lists.syrup.info'
    18 	TEST_LIST_HOST             = 'lists.syrup.info'
    35 	TEST_OWNER                 = 'listowner@rumpus-the-whale.info'
    19 	TEST_OWNER                 = 'listowner@rumpus-the-whale.info'
    36 	TEST_CUSTOM_MODERATORS_DIR = '/foo/bar/clowns'
    20 	TEST_CUSTOM_MODERATORS_DIR = '/foo/bar/clowns'
    37 	
    21 
    38 	TEST_SUBSCRIBERS = %w[
    22 	TEST_SUBSCRIBERS = %w[
    39 		pete.chaffee@toadsmackers.com
    23 		pete.chaffee@toadsmackers.com
    40 		dolphinzombie@alahalohamorra.com
    24 		dolphinzombie@alahalohamorra.com
    41 		piratebanker@yahoo.com
    25 		piratebanker@yahoo.com
    42 	  ]
    26 	  ]
    43 
    27 
    44 	TEST_MODERATORS = %w[
    28 	TEST_MODERATORS = %w[
    45 		dolphinzombie@alahalohamorra.com
    29 		dolphinzombie@alahalohamorra.com
    46 	  ]
    30 	  ]
    47 	
    31 
    48 	TEST_CONFIG = <<-"EOF".gsub( /^\t+/, '' )
    32 	TEST_CONFIG = <<-"EOF".gsub( /^\t+/, '' )
    49 		F:-aBCDeFGHijKlMnOpQrStUVWXYZ
    33 		F:-aBCDeFGHijKlMnOpQrStUVWXYZ
    50 		X:
    34 		X:
    51 		D:/var/qmail/alias/lists/waffle-lovers/
    35 		D:/var/qmail/alias/lists/waffle-lovers/
    52 		T:/var/qmail/alias/.qmail-waffle-lovers
    36 		T:/var/qmail/alias/.qmail-waffle-lovers
    60 		6:
    44 		6:
    61 		7:
    45 		7:
    62 		8:
    46 		8:
    63 		9:
    47 		9:
    64 	EOF
    48 	EOF
    65 	
    49 
    66 
    50 
    67 	it "can create a list"
    51 	it "can create a list"
    68 	it "can add a new subscriber"
    52 	it "can add a new subscriber"
    69 	it "can remove a current subscriber"
    53 	it "can remove a current subscriber"
    70 	it "can edit the list's text files"
    54 	it "can edit the list's text files"
    71 
    55 
    72 
    56 
    73 	### 
    57 	###
    74 	### List manager functions
    58 	### List manager functions
    75 	### 
    59 	###
    76 	describe "list manager functions" do
    60 	describe "list manager functions" do
    77 		
    61 
    78 		before( :each ) do
    62 		before( :each ) do
    79 			@listpath = TEST_LISTDIR.dup
    63 			@listpath = TEST_LISTDIR.dup
    80 			@list = Ezmlm::List.new( @listpath )
    64 			@list = Ezmlm::List.new( @listpath )
    81 		end
    65 		end
    82 		
    66 
    83 		
    67 
    84 		it "can return the configured list name" do
    68 		it "can return the configured list name" do
    85 			@list.stub!( :config ).and_return({ 'L' => :the_list_name })
    69 			allow(@list).to receive( :config ).and_return({ 'L' => :the_list_name })
    86 			@list.name.should == :the_list_name
    70 			expect(@list.name).to eq(:the_list_name)
    87 		end
    71 		end
    88 		
    72 
    89 		
    73 
    90 		it "can return the configured list host" do
    74 		it "can return the configured list host" do
    91 			@list.stub!( :config ).and_return({ 'H' => :the_list_host })
    75 			allow(@list).to receive( :config ).and_return({ 'H' => :the_list_host })
    92 			@list.host.should == :the_list_host
    76 			expect(@list.host).to eq(:the_list_host)
    93 		end
    77 		end
    94 		
    78 
    95 		
    79 
    96 		it "can return the configured list address" do
    80 		it "can return the configured list address" do
    97 			@list.stub!( :config ).and_return({ 'L' => TEST_LIST_NAME, 'H' => TEST_LIST_HOST })
    81 			allow(@list).to receive( :config ).and_return({ 'L' => TEST_LIST_NAME, 'H' => TEST_LIST_HOST })
    98 			@list.address.should == "%s@%s" % [ TEST_LIST_NAME, TEST_LIST_HOST ]
    82 			expect(@list.address).to eq("%s@%s" % [ TEST_LIST_NAME, TEST_LIST_HOST ])
    99 		end
    83 		end
   100 		
    84 
   101 		
    85 
   102 		CONFIG_KEYS = %w[ F X D T L H C 0 3 4 5 6 7 8 9 ]
    86 		CONFIG_KEYS = %w[ F X D T L H C 0 3 4 5 6 7 8 9 ]
   103 
    87 
   104 		it "can fetch the list config as a Hash" do
    88 		it "can fetch the list config as a Hash" do
   105 			config_path = mock( "Mock config path" )
    89 			config_path = double( "Mock config path" )
   106 			@listpath.should_receive( :+ ).with( 'config' ).and_return( config_path )
    90 			expect(@listpath).to receive( :+ ).with( 'config' ).and_return( config_path )
   107 			config_path.should_receive( :exist? ).and_return( true )
    91 			expect(config_path).to receive( :exist? ).and_return( true )
   108 			config_path.should_receive( :read ).and_return( TEST_CONFIG )
    92 			expect(config_path).to receive( :read ).and_return( TEST_CONFIG )
   109 			
    93 
   110 			@list.config.should be_an_instance_of( Hash )
    94 			expect(@list.config).to be_an_instance_of( Hash )
   111 			@list.config.should have( CONFIG_KEYS.length ).members
    95 			expect(@list.config.size).to eq(CONFIG_KEYS.length)
   112 			@list.config.keys.should include( *CONFIG_KEYS )
    96 			expect(@list.config.keys).to include( *CONFIG_KEYS )
   113 		end
    97 		end
   114 
    98 
   115 		
    99 
   116 		it "raises an error if the list config file doesn't exist" do
   100 		it "raises an error if the list config file doesn't exist" do
   117 			config_path = mock( "Mock config path" )
   101 			config_path = double( "Mock config path" )
   118 			@listpath.should_receive( :+ ).with( 'config' ).and_return( config_path )
   102 			expect(@listpath).to receive( :+ ).with( 'config' ).and_return( config_path )
   119 			config_path.should_receive( :exist? ).and_return( false )
   103 			expect(config_path).to receive( :exist? ).and_return( false )
   120 
   104 
   121 			lambda {
   105 			expect {
   122 				@list.config
   106 				@list.config
   123 			}.should raise_error( RuntimeError, /does not exist/ )
   107 			}.to raise_error( RuntimeError, /does not exist/ )
   124 		end
   108 		end
   125 
   109 
   126 		
   110 
   127 		it "can return a list of subscribers' email addresses" do
   111 		it "can return a list of subscribers' email addresses" do
   128 			subscribers_dir = TEST_LISTDIR + 'subscribers'
   112 			subscribers_dir = TEST_LISTDIR + 'subscribers'
   129 			
   113 
   130 			expectation = Pathname.should_receive( :glob ).with( subscribers_dir + '*' )
   114 			expectation = expect(Pathname).to receive( :glob ).with( subscribers_dir + '*' )
   131 
   115 
   132 			TEST_SUBSCRIBERS.each do |email|
   116 			TEST_SUBSCRIBERS.each do |email|
   133 				mock_subfile = mock( "Mock subscribers file for '#{email}'" )
   117 				mock_subfile = double( "Mock subscribers file for '#{email}'" )
   134 				mock_subfile.should_receive( :read ).and_return( "T#{email}\0" )
   118 				expect(mock_subfile).to receive( :read ).and_return( "T#{email}\0" )
   135 
   119 
   136 				expectation.and_yield( mock_subfile )
   120 				expectation.and_yield( mock_subfile )
   137 			end
   121 			end
   138 				
   122 
   139 			subscribers = @list.subscribers
   123 			subscribers = @list.subscribers
   140 			
   124 
   141 			subscribers.should have(TEST_SUBSCRIBERS.length).members
   125 			expect(subscribers.size).to eq(TEST_SUBSCRIBERS.length)
   142 			subscribers.should include( *TEST_SUBSCRIBERS )
   126 			expect(subscribers).to include( *TEST_SUBSCRIBERS )
   143 		end
   127 		end
   144 
   128 
   145 
   129 
   146 		### Subscriber moderation
   130 		### Subscriber moderation
   147 
   131 
   148 		it "knows that subscription moderation is enabled if the dir/modsub file exists" do
   132 		it "knows that subscription moderation is enabled if the dir/modsub file exists" do
   149 			modsub_path_obj = mock( "Mock 'modsub' path object" )
   133 			modsub_path_obj = double( "Mock 'modsub' path object" )
   150 			@listpath.should_receive( :+ ).with( 'modsub' ).and_return( modsub_path_obj )
   134 			expect(@listpath).to receive( :+ ).with( 'modsub' ).and_return( modsub_path_obj )
   151 			modsub_path_obj.should_receive( :exist? ).and_return( true )
   135 			expect(modsub_path_obj).to receive( :exist? ).and_return( true )
   152 			
   136 
   153 			@list.should be_closed()
   137 			expect(@list).to be_closed()
   154 		end
   138 		end
   155 		
   139 
   156 		it "knows that subscription moderation is enabled if the dir/remote file exists" do
   140 		it "knows that subscription moderation is enabled if the dir/remote file exists" do
   157 			modsub_path_obj = mock( "Mock 'modsub' path object" )
   141 			modsub_path_obj = double( "Mock 'modsub' path object" )
   158 			@listpath.should_receive( :+ ).with( 'modsub' ).and_return( modsub_path_obj )
   142 			expect(@listpath).to receive( :+ ).with( 'modsub' ).and_return( modsub_path_obj )
   159 			modsub_path_obj.should_receive( :exist? ).and_return( false )
   143 			expect(modsub_path_obj).to receive( :exist? ).and_return( false )
   160 
   144 
   161 			remote_path_obj = mock( "Mock 'remote' path object" )
   145 			remote_path_obj = double( "Mock 'remote' path object" )
   162 			@listpath.should_receive( :+ ).with( 'remote' ).and_return( remote_path_obj )
   146 			expect(@listpath).to receive( :+ ).with( 'remote' ).and_return( remote_path_obj )
   163 			remote_path_obj.should_receive( :exist? ).and_return( true )
   147 			expect(remote_path_obj).to receive( :exist? ).and_return( true )
   164 			
   148 
   165 			@list.should be_closed()
   149 			expect(@list).to be_closed()
   166 		end
   150 		end
   167 		
   151 
   168 		
   152 
   169 		it "knows that subscription moderation is disabled if neither the dir/modsub nor " +
   153 		it "knows that subscription moderation is disabled if neither the dir/modsub nor " +
   170 		   "dir/remote files exist" do
   154 		   "dir/remote files exist" do
   171 			modsub_path_obj = mock( "Mock 'modsub' path object" )
   155 			modsub_path_obj = double( "Mock 'modsub' path object" )
   172 			@listpath.should_receive( :+ ).with( 'modsub' ).and_return( modsub_path_obj )
   156 			expect(@listpath).to receive( :+ ).with( 'modsub' ).and_return( modsub_path_obj )
   173 			modsub_path_obj.should_receive( :exist? ).and_return( false )
   157 			expect(modsub_path_obj).to receive( :exist? ).and_return( false )
   174 
   158 
   175 			remote_path_obj = mock( "Mock 'remote' path object" )
   159 			remote_path_obj = double( "Mock 'remote' path object" )
   176 			@listpath.should_receive( :+ ).with( 'remote' ).and_return( remote_path_obj )
   160 			expect(@listpath).to receive( :+ ).with( 'remote' ).and_return( remote_path_obj )
   177 			remote_path_obj.should_receive( :exist? ).and_return( false )
   161 			expect(remote_path_obj).to receive( :exist? ).and_return( false )
   178 
   162 
   179 			@list.should_not be_closed()
   163 			expect(@list).not_to be_closed()
   180 		end
   164 		end
   181 
   165 
   182 
   166 
   183 		it "returns an empty array of subscription moderators for an open list" do
   167 		it "returns an empty array of subscription moderators for an open list" do
   184 			modsub_path_obj = mock( "Mock 'modsub' path object" )
   168 			modsub_path_obj = double( "Mock 'modsub' path object" )
   185 			@listpath.should_receive( :+ ).with( 'modsub' ).and_return( modsub_path_obj )
   169 			expect(@listpath).to receive( :+ ).with( 'modsub' ).and_return( modsub_path_obj )
   186 			modsub_path_obj.should_receive( :exist? ).and_return( false )
   170 			expect(modsub_path_obj).to receive( :exist? ).and_return( false )
   187 
   171 
   188 			remote_path_obj = mock( "Mock 'remote' path object" )
   172 			remote_path_obj = double( "Mock 'remote' path object" )
   189 			@listpath.should_receive( :+ ).with( 'remote' ).and_return( remote_path_obj )
   173 			expect(@listpath).to receive( :+ ).with( 'remote' ).and_return( remote_path_obj )
   190 			remote_path_obj.should_receive( :exist? ).and_return( false )
   174 			expect(remote_path_obj).to receive( :exist? ).and_return( false )
   191 
   175 
   192 			@list.subscription_moderators.should be_empty()
   176 			expect(@list.subscription_moderators).to be_empty()
   193 		end
   177 		end
   194 	
   178 
   195 		it "can return a list of subscription moderators' email addresses" do
   179 		it "can return a list of subscription moderators' email addresses" do
   196 			# Test the moderation config files for existence
   180 			# Test the moderation config files for existence
   197 			modsub_path_obj = mock( "Mock 'modsub' path object" )
   181 			modsub_path_obj = double( "Mock 'modsub' path object" )
   198 			@listpath.should_receive( :+ ).with( 'modsub' ).twice.and_return( modsub_path_obj )
   182 			expect(@listpath).to receive( :+ ).with( 'modsub' ).twice.and_return( modsub_path_obj )
   199 			modsub_path_obj.should_receive( :exist? ).twice.and_return( true )
   183 			expect(modsub_path_obj).to receive( :exist? ).twice.and_return( true )
   200 			remote_path_obj = mock( "Mock 'remote' path object" )
   184 			remote_path_obj = double( "Mock 'remote' path object" )
   201 			@listpath.should_receive( :+ ).with( 'remote' ).and_return( remote_path_obj )
   185 			expect(@listpath).to receive( :+ ).with( 'remote' ).and_return( remote_path_obj )
   202 			remote_path_obj.should_receive( :exist? ).once.and_return( true )
   186 			expect(remote_path_obj).to receive( :exist? ).once.and_return( true )
   203 
   187 
   204 			# Try to read directory names from both config files
   188 			# Try to read directory names from both config files
   205 			modsub_path_obj.should_receive( :read ).with( 1 ).and_return( nil )
   189 			expect(modsub_path_obj).to receive( :read ).with( 1 ).and_return( nil )
   206 			remote_path_obj.should_receive( :read ).with( 1 ).and_return( nil )
   190 			expect(remote_path_obj).to receive( :read ).with( 1 ).and_return( nil )
   207 			
   191 
   208 			# Read subscribers from the default directory
   192 			# Read subscribers from the default directory
   209 			subscribers_dir = mock( "Mock moderator subscribers directory" )
   193 			subscribers_dir = double( "Mock moderator subscribers directory" )
   210 			@listpath.should_receive( :+ ).with( 'mod/subscribers' ).and_return( subscribers_dir )
   194 			expect(@listpath).to receive( :+ ).with( 'mod/subscribers' ).and_return( subscribers_dir )
   211 			subscribers_dir.should_receive( :+ ).with( '*' ).and_return( :mod_sub_dir )
   195 			expect(subscribers_dir).to receive( :+ ).with( '*' ).and_return( :mod_sub_dir )
   212 			expectation = Pathname.should_receive( :glob ).with( :mod_sub_dir )
   196 			expectation = expect(Pathname).to receive( :glob ).with( :mod_sub_dir )
   213 
   197 
   214 			TEST_MODERATORS.each do |email|
   198 			TEST_MODERATORS.each do |email|
   215 				mock_subfile = mock( "Mock subscribers file for '#{email}'" )
   199 				mock_subfile = double( "Mock subscribers file for '#{email}'" )
   216 				mock_subfile.should_receive( :read ).and_return( "T#{email}\0" )
   200 				expect(mock_subfile).to receive( :read ).and_return( "T#{email}\0" )
   217 
   201 
   218 				expectation.and_yield( mock_subfile )
   202 				expectation.and_yield( mock_subfile )
   219 			end
   203 			end
   220 
   204 
   221 			mods = @list.subscription_moderators
   205 			mods = @list.subscription_moderators
   222 			mods.should have(TEST_MODERATORS.length).members
   206 			expect(mods.size).to eq(TEST_MODERATORS.length)
   223 			mods.should include( *TEST_MODERATORS )
   207 			expect(mods).to include( *TEST_MODERATORS )
   224 		end
   208 		end
   225 		
   209 
   226 		
   210 
   227 		it "can return a list of subscription moderators' email addresses when the moderators " +
   211 		it "can return a list of subscription moderators' email addresses when the moderators " +
   228 		   "directory has been customized" do
   212 		   "directory has been customized" do
   229 			# Test the moderation config files for existence
   213 			# Test the moderation config files for existence
   230 			modsub_path_obj = mock( "Mock 'modsub' path object" )
   214 			modsub_path_obj = double( "Mock 'modsub' path object" )
   231 			@listpath.should_receive( :+ ).with( 'modsub' ).twice.and_return( modsub_path_obj )
   215 			expect(@listpath).to receive( :+ ).with( 'modsub' ).twice.and_return( modsub_path_obj )
   232 			modsub_path_obj.should_receive( :exist? ).twice.and_return( true )
   216 			expect(modsub_path_obj).to receive( :exist? ).twice.and_return( true )
   233 			@listpath.should_receive( :+ ).with( 'remote' )
   217 			expect(@listpath).to receive( :+ ).with( 'remote' )
   234 
   218 
   235 			# Try to read directory names from both config files
   219 			# Try to read directory names from both config files
   236 			modsub_path_obj.should_receive( :read ).with( 1 ).and_return( '/' )
   220 			expect(modsub_path_obj).to receive( :read ).with( 1 ).and_return( '/' )
   237 			modsub_path_obj.should_receive( :read ).with().and_return( TEST_CUSTOM_MODERATORS_DIR )
   221 			expect(modsub_path_obj).to receive( :read ).with().and_return( TEST_CUSTOM_MODERATORS_DIR )
   238 
   222 
   239 			custom_mod_path = mock( "Mock path object for customized moderator dir" )
   223 			custom_mod_path = double( "Mock path object for customized moderator dir" )
   240 			Pathname.should_receive( :new ).with( TEST_CUSTOM_MODERATORS_DIR ).and_return( custom_mod_path )
   224 			expect(Pathname).to receive( :new ).with( TEST_CUSTOM_MODERATORS_DIR ).and_return( custom_mod_path )
   241 
   225 
   242 			# Read subscribers from the default file
   226 			# Read subscribers from the default file
   243 			custom_mod_path.should_receive( :+ ).with( '*' ).and_return( :mod_sub_dir )
   227 			expect(custom_mod_path).to receive( :+ ).with( '*' ).and_return( :mod_sub_dir )
   244 			expectation = Pathname.should_receive( :glob ).with( :mod_sub_dir )
   228 			expectation = expect(Pathname).to receive( :glob ).with( :mod_sub_dir )
   245 
   229 
   246 			TEST_MODERATORS.each do |email|
   230 			TEST_MODERATORS.each do |email|
   247 				mock_subfile = mock( "Mock subscribers file for '#{email}'" )
   231 				mock_subfile = double( "Mock subscribers file for '#{email}'" )
   248 				mock_subfile.should_receive( :read ).and_return( "T#{email}\0" )
   232 				expect(mock_subfile).to receive( :read ).and_return( "T#{email}\0" )
   249 
   233 
   250 				expectation.and_yield( mock_subfile )
   234 				expectation.and_yield( mock_subfile )
   251 			end
   235 			end
   252 
   236 
   253 			mods = @list.subscription_moderators
   237 			mods = @list.subscription_moderators
   254 			mods.should have(TEST_MODERATORS.length).members
   238 			expect(mods.size).to eq(TEST_MODERATORS.length)
   255 			mods.should include( *TEST_MODERATORS )
   239 			expect(mods).to include( *TEST_MODERATORS )
   256 		end
   240 		end
   257 		
   241 
   258 		it "can get a list of modererators when remote subscription moderation is enabled" +
   242 		it "can get a list of modererators when remote subscription moderation is enabled" +
   259            " and the modsub configuration is empty" do
   243            " and the modsub configuration is empty" do
   260 			# Test the moderation config files for existence
   244 			# Test the moderation config files for existence
   261 			modsub_path_obj = mock( "Mock 'modsub' path object" )
   245 			modsub_path_obj = double( "Mock 'modsub' path object" )
   262 			@listpath.should_receive( :+ ).with( 'modsub' ).twice.and_return( modsub_path_obj )
   246 			expect(@listpath).to receive( :+ ).with( 'modsub' ).twice.and_return( modsub_path_obj )
   263 			modsub_path_obj.should_receive( :exist? ).twice.and_return( false )
   247 			expect(modsub_path_obj).to receive( :exist? ).twice.and_return( false )
   264             remote_path_obj = mock( "Mock 'remote' path object" )
   248             remote_path_obj = double( "Mock 'remote' path object" )
   265 			@listpath.should_receive( :+ ).with( 'remote' ).twice.and_return( remote_path_obj )
   249 			expect(@listpath).to receive( :+ ).with( 'remote' ).twice.and_return( remote_path_obj )
   266             remote_path_obj.should_receive( :exist? ).twice.and_return( true )
   250             expect(remote_path_obj).to receive( :exist? ).twice.and_return( true )
   267 
   251 
   268 			# Try to read directory names from both config files
   252 			# Try to read directory names from both config files
   269 			remote_path_obj.should_receive( :read ).with( 1 ).and_return( '/' )
   253 			expect(remote_path_obj).to receive( :read ).with( 1 ).and_return( '/' )
   270 			remote_path_obj.should_receive( :read ).with().and_return( TEST_CUSTOM_MODERATORS_DIR )
   254 			expect(remote_path_obj).to receive( :read ).with().and_return( TEST_CUSTOM_MODERATORS_DIR )
   271 
   255 
   272 			custom_mod_path = mock( "Mock path object for customized moderator dir" )
   256 			custom_mod_path = double( "Mock path object for customized moderator dir" )
   273 			Pathname.should_receive( :new ).with( TEST_CUSTOM_MODERATORS_DIR ).and_return( custom_mod_path )
   257 			expect(Pathname).to receive( :new ).with( TEST_CUSTOM_MODERATORS_DIR ).and_return( custom_mod_path )
   274 
   258 
   275 			# Read subscribers from the default file
   259 			# Read subscribers from the default file
   276 			custom_mod_path.should_receive( :+ ).with( '*' ).and_return( :mod_sub_dir )
   260 			expect(custom_mod_path).to receive( :+ ).with( '*' ).and_return( :mod_sub_dir )
   277 			expectation = Pathname.should_receive( :glob ).with( :mod_sub_dir )
   261 			expectation = expect(Pathname).to receive( :glob ).with( :mod_sub_dir )
   278 
   262 
   279 			TEST_MODERATORS.each do |email|
   263 			TEST_MODERATORS.each do |email|
   280 				mock_subfile = mock( "Mock subscribers file for '#{email}'" )
   264 				mock_subfile = double( "Mock subscribers file for '#{email}'" )
   281 				mock_subfile.should_receive( :read ).and_return( "T#{email}\0" )
   265 				expect(mock_subfile).to receive( :read ).and_return( "T#{email}\0" )
   282 
   266 
   283 				expectation.and_yield( mock_subfile )
   267 				expectation.and_yield( mock_subfile )
   284 			end
   268 			end
   285 
   269 
   286 			mods = @list.subscription_moderators
   270 			mods = @list.subscription_moderators
   287 			mods.should have(TEST_MODERATORS.length).members
   271 			expect(mods.size).to eq(TEST_MODERATORS.length)
   288 			mods.should include( *TEST_MODERATORS )
   272 			expect(mods).to include( *TEST_MODERATORS )
   289 		end
   273 		end
   290 
   274 
   291 		### Message moderation
   275 		### Message moderation
   292 		
   276 
   293 		it "knows that subscription moderation is enabled if the dir/modpost file exists" do
   277 		it "knows that subscription moderation is enabled if the dir/modpost file exists" do
   294 			modpost_path_obj = mock( "Mock 'modpost' path object" )
   278 			modpost_path_obj = double( "Mock 'modpost' path object" )
   295 			@listpath.should_receive( :+ ).with( 'modpost' ).and_return( modpost_path_obj )
   279 			expect(@listpath).to receive( :+ ).with( 'modpost' ).and_return( modpost_path_obj )
   296 			modpost_path_obj.should_receive( :exist? ).and_return( true )
   280 			expect(modpost_path_obj).to receive( :exist? ).and_return( true )
   297 			
   281 
   298 			@list.should be_moderated()
   282 			expect(@list).to be_moderated()
   299 		end
   283 		end
   300 		
   284 
   301 		it "knows that subscription moderation is disabled if the dir/modpost file doesn't exist" do
   285 		it "knows that subscription moderation is disabled if the dir/modpost file doesn't exist" do
   302 			modpost_path_obj = mock( "Mock 'modpost' path object" )
   286 			modpost_path_obj = double( "Mock 'modpost' path object" )
   303 			@listpath.should_receive( :+ ).with( 'modpost' ).and_return( modpost_path_obj )
   287 			expect(@listpath).to receive( :+ ).with( 'modpost' ).and_return( modpost_path_obj )
   304 			modpost_path_obj.should_receive( :exist? ).and_return( false )
   288 			expect(modpost_path_obj).to receive( :exist? ).and_return( false )
   305 
   289 
   306 			@list.should_not be_moderated()
   290 			expect(@list).not_to be_moderated()
   307 		end
   291 		end
   308 
   292 
   309 
   293 
   310 		it "returns an empty array of message moderators for an open list" do
   294 		it "returns an empty array of message moderators for an open list" do
   311 			modpost_path_obj = mock( "Mock 'modpost' path object" )
   295 			modpost_path_obj = double( "Mock 'modpost' path object" )
   312 			@listpath.should_receive( :+ ).with( 'modpost' ).and_return( modpost_path_obj )
   296 			expect(@listpath).to receive( :+ ).with( 'modpost' ).and_return( modpost_path_obj )
   313 			modpost_path_obj.should_receive( :exist? ).and_return( false )
   297 			expect(modpost_path_obj).to receive( :exist? ).and_return( false )
   314 
   298 
   315 			@list.message_moderators.should be_empty()
   299 			expect(@list.message_moderators).to be_empty()
   316 		end
   300 		end
   317 	
   301 
   318 	
   302 
   319 		it "can return a list of message moderators' email addresses" do
   303 		it "can return a list of message moderators' email addresses" do
   320 			# Test the moderation config file for existence
   304 			# Test the moderation config file for existence
   321 			modpost_path_obj = mock( "Mock 'modpost' path object" )
   305 			modpost_path_obj = double( "Mock 'modpost' path object" )
   322 			@listpath.should_receive( :+ ).with( 'modpost' ).twice.and_return( modpost_path_obj )
   306 			expect(@listpath).to receive( :+ ).with( 'modpost' ).twice.and_return( modpost_path_obj )
   323 			modpost_path_obj.should_receive( :exist? ).twice.and_return( true )
   307 			expect(modpost_path_obj).to receive( :exist? ).twice.and_return( true )
   324 
   308 
   325 			# Try to read directory names from the config file
   309 			# Try to read directory names from the config file
   326 			modpost_path_obj.should_receive( :read ).with( 1 ).and_return( nil )
   310 			expect(modpost_path_obj).to receive( :read ).with( 1 ).and_return( nil )
   327 			
   311 
   328 			# Read subscribers from the default directory
   312 			# Read subscribers from the default directory
   329 			subscribers_dir = mock( "Mock moderator subscribers directory" )
   313 			subscribers_dir = double( "Mock moderator subscribers directory" )
   330 			@listpath.should_receive( :+ ).with( 'mod/subscribers' ).and_return( subscribers_dir )
   314 			expect(@listpath).to receive( :+ ).with( 'mod/subscribers' ).and_return( subscribers_dir )
   331 			subscribers_dir.should_receive( :+ ).with( '*' ).and_return( :mod_sub_dir )
   315 			expect(subscribers_dir).to receive( :+ ).with( '*' ).and_return( :mod_sub_dir )
   332 			expectation = Pathname.should_receive( :glob ).with( :mod_sub_dir )
   316 			expectation = expect(Pathname).to receive( :glob ).with( :mod_sub_dir )
   333 
   317 
   334 			TEST_MODERATORS.each do |email|
   318 			TEST_MODERATORS.each do |email|
   335 				mock_subfile = mock( "Mock subscribers file for '#{email}'" )
   319 				mock_subfile = double( "Mock subscribers file for '#{email}'" )
   336 				mock_subfile.should_receive( :read ).and_return( "T#{email}\0" )
   320 				expect(mock_subfile).to receive( :read ).and_return( "T#{email}\0" )
   337 
   321 
   338 				expectation.and_yield( mock_subfile )
   322 				expectation.and_yield( mock_subfile )
   339 			end
   323 			end
   340 
   324 
   341 			mods = @list.message_moderators
   325 			mods = @list.message_moderators
   342 			mods.should have(TEST_MODERATORS.length).members
   326 			expect(mods.size).to eq(TEST_MODERATORS.length)
   343 			mods.should include( *TEST_MODERATORS )
   327 			expect(mods).to include( *TEST_MODERATORS )
   344 		end
   328 		end
   345 		
   329 
   346 		
   330 
   347 		it "can return a list of message moderators' email addresses when the moderators " +
   331 		it "can return a list of message moderators' email addresses when the moderators " +
   348 		   "directory has been customized" do
   332 		   "directory has been customized" do
   349 			# Test the moderation config files for existence
   333 			# Test the moderation config files for existence
   350 			modpost_path_obj = mock( "Mock 'modpost' path object" )
   334 			modpost_path_obj = double( "Mock 'modpost' path object" )
   351 			@listpath.should_receive( :+ ).with( 'modpost' ).twice.and_return( modpost_path_obj )
   335 			expect(@listpath).to receive( :+ ).with( 'modpost' ).twice.and_return( modpost_path_obj )
   352 			modpost_path_obj.should_receive( :exist? ).twice.and_return( true )
   336 			expect(modpost_path_obj).to receive( :exist? ).twice.and_return( true )
   353 
   337 
   354 			# Try to read directory names from both config files
   338 			# Try to read directory names from both config files
   355 			modpost_path_obj.should_receive( :read ).with( 1 ).and_return( '/' )
   339 			expect(modpost_path_obj).to receive( :read ).with( 1 ).and_return( '/' )
   356 			modpost_path_obj.should_receive( :read ).with().and_return( TEST_CUSTOM_MODERATORS_DIR )
   340 			expect(modpost_path_obj).to receive( :read ).with().and_return( TEST_CUSTOM_MODERATORS_DIR )
   357 
   341 
   358 			custom_mod_path = mock( "Mock path object for customized moderator dir" )
   342 			custom_mod_path = double( "Mock path object for customized moderator dir" )
   359 			Pathname.should_receive( :new ).with( TEST_CUSTOM_MODERATORS_DIR ).and_return( custom_mod_path )
   343 			expect(Pathname).to receive( :new ).with( TEST_CUSTOM_MODERATORS_DIR ).and_return( custom_mod_path )
   360 
   344 
   361 			# Read subscribers from the default file
   345 			# Read subscribers from the default file
   362 			custom_mod_path.should_receive( :+ ).with( '*' ).and_return( :mod_sub_dir )
   346 			expect(custom_mod_path).to receive( :+ ).with( '*' ).and_return( :mod_sub_dir )
   363 			expectation = Pathname.should_receive( :glob ).with( :mod_sub_dir )
   347 			expectation = expect(Pathname).to receive( :glob ).with( :mod_sub_dir )
   364 
   348 
   365 			TEST_MODERATORS.each do |email|
   349 			TEST_MODERATORS.each do |email|
   366 				mock_subfile = mock( "Mock subscribers file for '#{email}'" )
   350 				mock_subfile = double( "Mock subscribers file for '#{email}'" )
   367 				mock_subfile.should_receive( :read ).and_return( "T#{email}\0" )
   351 				expect(mock_subfile).to receive( :read ).and_return( "T#{email}\0" )
   368 
   352 
   369 				expectation.and_yield( mock_subfile )
   353 				expectation.and_yield( mock_subfile )
   370 			end
   354 			end
   371 
   355 
   372 			mods = @list.message_moderators
   356 			mods = @list.message_moderators
   373 			mods.should have(TEST_MODERATORS.length).members
   357 			expect(mods.size).to eq(TEST_MODERATORS.length)
   374 			mods.should include( *TEST_MODERATORS )
   358 			expect(mods).to include( *TEST_MODERATORS )
   375 		end
   359 		end
   376 
   360 
   377 
   361 
   378 		### List owner
   362 		### List owner
   379 		
   363 
   380 		it "returns nil when the list doesn't have an owner in its config" do
   364 		it "returns nil when the list doesn't have an owner in its config" do
   381 			@list.stub!( :config ).and_return({ '5' => nil })
   365 			allow(@list).to receive( :config ).and_return({ '5' => nil })
   382 			@list.owner.should == nil
   366 			expect(@list.owner).to eq(nil)
   383 		end
   367 		end
   384 		
   368 
   385 			
   369 
   386 		it "can return the email address of the list owner" do
   370 		it "can return the email address of the list owner" do
   387 			@list.stub!( :config ).and_return({ '5' => TEST_OWNER })
   371 			allow(@list).to receive( :config ).and_return({ '5' => TEST_OWNER })
   388 			@list.owner.should == TEST_OWNER
   372 			expect(@list.owner).to eq(TEST_OWNER)
   389 		end
   373 		end
   390 
   374 
   391 	end
   375 	end
   392 	
   376 
   393 	
   377 
   394 	### 
   378 	###
   395 	### Archive functions
   379 	### Archive functions
   396 	### 
   380 	###
   397 	describe "archive functions" do
   381 	describe "archive functions" do
   398 	
   382 
   399 		before( :each ) do
   383 		before( :each ) do
   400 			@listpath = TEST_LISTDIR.dup
   384 			@listpath = TEST_LISTDIR.dup
   401 			@list = Ezmlm::List.new( @listpath )
   385 			@list = Ezmlm::List.new( @listpath )
   402 		end
   386 		end
   403 		
   387 
   404 		
   388 
   405 		it "can return the count of archived posts" do
   389 		it "can return the count of archived posts" do
   406 			numpath_obj = mock( "num file path object" )
   390 			numpath_obj = double( "num file path object" )
   407 			@listpath.should_receive( :+ ).with( 'num' ).and_return( numpath_obj )
   391 			expect(@listpath).to receive( :+ ).with( 'num' ).and_return( numpath_obj )
   408 			
   392 
   409 			numpath_obj.should_receive( :exist? ).and_return( true )
   393 			expect(numpath_obj).to receive( :exist? ).and_return( true )
   410 			numpath_obj.should_receive( :read ).and_return( "1723:123123123" )
   394 			expect(numpath_obj).to receive( :read ).and_return( "1723:123123123" )
   411 			
   395 
   412 			@list.message_count.should == 1723
   396 			expect(@list.message_count).to eq(1723)
   413 		end
   397 		end
   414 	
   398 
   415 		it "can return the count of archived posts to a list that hasn't been posted to" do
   399 		it "can return the count of archived posts to a list that hasn't been posted to" do
   416 			numpath_obj = mock( "num file path object" )
   400 			numpath_obj = double( "num file path object" )
   417 			@listpath.should_receive( :+ ).with( 'num' ).and_return( numpath_obj )
   401 			expect(@listpath).to receive( :+ ).with( 'num' ).and_return( numpath_obj )
   418 			
   402 
   419 			numpath_obj.should_receive( :exist? ).and_return( false )
   403 			expect(numpath_obj).to receive( :exist? ).and_return( false )
   420 			
   404 
   421 			@list.message_count.should == 0
   405 			expect(@list.message_count).to eq(0)
   422 		end
   406 		end
   423 		
   407 
   424 
   408 
   425 		
   409 
   426 		TEST_ARCHIVE_DIR = TEST_LISTDIR + 'archive'
   410 		TEST_ARCHIVE_DIR = TEST_LISTDIR + 'archive'
   427 		TEST_ARCHIVE_SUBDIRS = %w[ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 ]
   411 		TEST_ARCHIVE_SUBDIRS = %w[ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 ]
   428 		TEST_POST_FILES = %w[ 00 01 02 03 04 05 06 07 08 09 10 11 12 13 ]
   412 		TEST_POST_FILES = %w[ 00 01 02 03 04 05 06 07 08 09 10 11 12 13 ]
   429 
   413 
   430 		before( :each ) do
   414 		before( :each ) do
   433 			@archive_subdir_paths = TEST_ARCHIVE_SUBDIRS.collect {|pn| TEST_ARCHIVE_DIR + pn }
   417 			@archive_subdir_paths = TEST_ARCHIVE_SUBDIRS.collect {|pn| TEST_ARCHIVE_DIR + pn }
   434 			@archive_post_paths = TEST_POST_FILES.collect {|pn|
   418 			@archive_post_paths = TEST_POST_FILES.collect {|pn|
   435 				TEST_ARCHIVE_DIR + TEST_ARCHIVE_SUBDIRS.last + pn
   419 				TEST_ARCHIVE_DIR + TEST_ARCHIVE_SUBDIRS.last + pn
   436 			  }
   420 			  }
   437 		end
   421 		end
   438 		
   422 
   439 
   423 
   440 		it "can return a TMail::Mail object parsed from the last archived post" do
   424 		it "can return a TMail::Mail object parsed from the last archived post" do
   441 			# need to find the last message
   425 			# need to find the last message
   442 			archive_path_obj = mock( "archive path" )
   426 			archive_path_obj = double( "archive path" )
   443 
   427 
   444 			@listpath.should_receive( :+ ).with( 'archive' ).and_return( archive_path_obj )
   428 			expect(@listpath).to receive( :+ ).with( 'archive' ).and_return( archive_path_obj )
   445 			archive_path_obj.should_receive( :exist? ).and_return( true )
   429 			expect(archive_path_obj).to receive( :exist? ).and_return( true )
   446 
   430 
   447 			# Find the last numbered directory under the archive dir
   431 			# Find the last numbered directory under the archive dir
   448 			archive_path_obj.should_receive( :+ ).with( '[0-9]*' ).
   432 			expect(archive_path_obj).to receive( :+ ).with( '[0-9]*' ).
   449 				and_return( :archive_dir_globpath )
   433 				and_return( :archive_dir_globpath )
   450 			Pathname.should_receive( :glob ).with( :archive_dir_globpath ).
   434 			expect(Pathname).to receive( :glob ).with( :archive_dir_globpath ).
   451 				and_return( @archive_subdir_paths )
   435 				and_return( @archive_subdir_paths )
   452 
   436 
   453 			# Find the last numbered file under the last numbered directory we found
   437 			# Find the last numbered file under the last numbered directory we found
   454 			# above.
   438 			# above.
   455 			@archive_subdir_paths.last.should_receive( :+ ).with( '[0-9]*' ).
   439 			expect(@archive_subdir_paths.last).to receive( :+ ).with( '[0-9]*' ).
   456 				and_return( :archive_post_pathglob )
   440 				and_return( :archive_post_pathglob )
   457 			Pathname.should_receive( :glob ).with( :archive_post_pathglob ).
   441 			expect(Pathname).to receive( :glob ).with( :archive_post_pathglob ).
   458 				and_return( @archive_post_paths )
   442 				and_return( @archive_post_paths )
   459 
   443 
   460 			TMail::Mail.should_receive( :load ).with( @archive_post_paths.last.to_s ).
   444 			expect(TMail::Mail).to receive( :load ).with( @archive_post_paths.last.to_s ).
   461 				and_return( :mail_object )
   445 				and_return( :mail_object )
   462 
   446 
   463 			@list.last_post.should == :mail_object
   447 			expect(@list.last_post).to eq(:mail_object)
   464 		end
   448 		end
   465 		
   449 
   466 		
   450 
   467 		it "returns nil for the last post if there is no archive directory for the list" do
   451 		it "returns nil for the last post if there is no archive directory for the list" do
   468 			archive_path_obj = mock( "archive path" )
   452 			archive_path_obj = double( "archive path" )
   469 
   453 
   470 			@listpath.should_receive( :+ ).with( 'archive' ).and_return( archive_path_obj )
   454 			expect(@listpath).to receive( :+ ).with( 'archive' ).and_return( archive_path_obj )
   471 			archive_path_obj.should_receive( :exist? ).and_return( false )
   455 			expect(archive_path_obj).to receive( :exist? ).and_return( false )
   472 			@list.last_post.should == nil
   456 			expect(@list.last_post).to eq(nil)
   473 		end
   457 		end
   474 		
   458 
   475 		
   459 
   476 		it "returns nil for the last post if there haven't been any posts to the list" do
   460 		it "returns nil for the last post if there haven't been any posts to the list" do
   477 			archive_path_obj = mock( "archive path" )
   461 			archive_path_obj = double( "archive path" )
   478 			mail_object = mock( "Mock TMail object" )
   462 			mail_object = double( "Mock TMail object" )
   479 
   463 
   480 			@listpath.should_receive( :+ ).with( 'archive' ).and_return( archive_path_obj )
   464 			expect(@listpath).to receive( :+ ).with( 'archive' ).and_return( archive_path_obj )
   481 			archive_path_obj.should_receive( :exist? ).and_return( true )
   465 			expect(archive_path_obj).to receive( :exist? ).and_return( true )
   482 
   466 
   483 			# Find the last numbered directory under the archive dir
   467 			# Find the last numbered directory under the archive dir
   484 			archive_path_obj.should_receive( :+ ).with( '[0-9]*' ).
   468 			expect(archive_path_obj).to receive( :+ ).with( '[0-9]*' ).
   485 				and_return( :archive_dir_globpath )
   469 				and_return( :archive_dir_globpath )
   486 			Pathname.should_receive( :glob ).with( :archive_dir_globpath ).and_return( [] )
   470 			expect(Pathname).to receive( :glob ).with( :archive_dir_globpath ).and_return( [] )
   487 
   471 
   488 			@list.last_post.should == nil
   472 			expect(@list.last_post).to eq(nil)
   489 		end
   473 		end
   490 		
   474 
   491 		
   475 
   492 		it "raises a RuntimeError if the last archive directory doesn't have any messages in it" do
   476 		it "raises a RuntimeError if the last archive directory doesn't have any messages in it" do
   493 			archive_path_obj = mock( "archive path" )
   477 			archive_path_obj = double( "archive path" )
   494 			mail_object = mock( "Mock TMail object" )
   478 			mail_object = double( "Mock TMail object" )
   495 
   479 
   496 			@listpath.should_receive( :+ ).with( 'archive' ).and_return( archive_path_obj )
   480 			expect(@listpath).to receive( :+ ).with( 'archive' ).and_return( archive_path_obj )
   497 			archive_path_obj.should_receive( :exist? ).and_return( true )
   481 			expect(archive_path_obj).to receive( :exist? ).and_return( true )
   498 
   482 
   499 			# Find the last numbered directory under the archive dir
   483 			# Find the last numbered directory under the archive dir
   500 			archive_path_obj.should_receive( :+ ).with( '[0-9]*' ).
   484 			expect(archive_path_obj).to receive( :+ ).with( '[0-9]*' ).
   501 				and_return( :archive_dir_globpath )
   485 				and_return( :archive_dir_globpath )
   502 			Pathname.should_receive( :glob ).with( :archive_dir_globpath ).
   486 			expect(Pathname).to receive( :glob ).with( :archive_dir_globpath ).
   503 				and_return( @archive_subdir_paths )
   487 				and_return( @archive_subdir_paths )
   504 
   488 
   505 			@archive_subdir_paths.last.should_receive( :+ ).with( '[0-9]*' ).
   489 			expect(@archive_subdir_paths.last).to receive( :+ ).with( '[0-9]*' ).
   506 				and_return( :archive_post_pathglob )
   490 				and_return( :archive_post_pathglob )
   507 			Pathname.should_receive( :glob ).with( :archive_post_pathglob ).
   491 			expect(Pathname).to receive( :glob ).with( :archive_post_pathglob ).
   508 				and_return( [] )
   492 				and_return( [] )
   509 
   493 
   510 			lambda {
   494 			expect {
   511 				@list.last_post
   495 				@list.last_post
   512 			}.should raise_error( RuntimeError, /unexpectedly empty/i )
   496 			}.to raise_error( RuntimeError, /unexpectedly empty/i )
   513 		end
   497 		end
   514 		
   498 
   515 		
   499 
   516 		it "can fetch the date of the last archived post" do
   500 		it "can fetch the date of the last archived post" do
   517 			mail_object = mock( "Mock TMail object" )
   501 			mail_object = double( "Mock TMail object" )
   518 
   502 
   519 			@list.should_receive( :last_post ).and_return( mail_object )
   503 			expect(@list).to receive( :last_post ).and_return( mail_object )
   520 			mail_object.should_receive( :date ).and_return( :the_message_date )
   504 			expect(mail_object).to receive( :date ).and_return( :the_message_date )
   521 
   505 
   522 			@list.last_message_date.should == :the_message_date
   506 			expect(@list.last_message_date).to eq(:the_message_date)
   523 		end
   507 		end
   524 
   508 
   525 		
   509 
   526 		it "can fetch the date of the last archived post" do
   510 		it "can fetch the date of the last archived post" do
   527 			mail_object = mock( "Mock TMail object" )
   511 			mail_object = double( "Mock TMail object" )
   528 
   512 
   529 			@list.should_receive( :last_post ).and_return( mail_object )
   513 			expect(@list).to receive( :last_post ).and_return( mail_object )
   530 			mail_object.should_receive( :date ).and_return( :the_message_date )
   514 			expect(mail_object).to receive( :date ).and_return( :the_message_date )
   531 
   515 
   532 			@list.last_message_date.should == :the_message_date
   516 			expect(@list.last_message_date).to eq(:the_message_date)
   533 		end
   517 		end
   534 
   518 
   535 		
   519 
   536 		it "can fetch the author of the last archived post" do
   520 		it "can fetch the author of the last archived post" do
   537 			mail_object = mock( "Mock TMail object" )
   521 			mail_object = double( "Mock TMail object" )
   538 
   522 
   539 			@list.should_receive( :last_post ).and_return( mail_object )
   523 			expect(@list).to receive( :last_post ).and_return( mail_object )
   540 			mail_object.should_receive( :from ).and_return( :the_message_author )
   524 			expect(mail_object).to receive( :from ).and_return( :the_message_author )
   541 
   525 
   542 			@list.last_message_author.should == :the_message_author
   526 			expect(@list.last_message_author).to eq(:the_message_author)
   543 		end
   527 		end
   544 
   528 
   545 		
   529 
   546 		it "can fetch the subject of the last archived post" do
   530 		it "can fetch the subject of the last archived post" do
   547 			mail_object = mock( "Mock TMail object" )
   531 			mail_object = double( "Mock TMail object" )
   548 
   532 
   549 			@list.should_receive( :last_post ).and_return( mail_object )
   533 			expect(@list).to receive( :last_post ).and_return( mail_object )
   550 			mail_object.should_receive( :from ).and_return( :the_message_author )
   534 			expect(mail_object).to receive( :from ).and_return( :the_message_author )
   551 
   535 
   552 			@list.last_message_author.should == :the_message_author
   536 			expect(@list.last_message_author).to eq(:the_message_author)
   553 		end
   537 		end
   554 
   538 
   555 	end
   539 	end
   556 
   540 
   557 
   541 
   558 	it "can fetch the body of an archived post by message id"
   542 	it "can fetch the body of an archived post by message id"
   559 	it "can fetch the header of an archived post by message id"
   543 	it "can fetch the header of an archived post by message id"
   560 	
   544 
   561 	it "can return a hash of the subjects of all archived posts to message ids" 
   545 	it "can return a hash of the subjects of all archived posts to message ids"
   562 	it "can return an Array of the subjects of all archived posts"
   546 	it "can return an Array of the subjects of all archived posts"
   563 
   547 
   564 	it "can return a hash of the threads of all archived posts to message ids"
   548 	it "can return a hash of the threads of all archived posts to message ids"
   565 	it "can return an Array of the threads of all archived posts"
   549 	it "can return an Array of the threads of all archived posts"
   566 
   550