git clone of logicmail with some fixes/features added
at master 380 lines 17 kB view raw
1/*- 2 * Copyright (c) 2009, Derek Konigsberg 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. Neither the name of the project nor the names of its 15 * contributors may be used to endorse or promote products derived 16 * from this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 21 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 22 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 24 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 27 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 29 * OF THE POSSIBILITY OF SUCH DAMAGE. 30 */ 31package org.logicprobe.LogicMail.model; 32 33import java.util.Date; 34 35import org.logicprobe.LogicMail.mail.FakeMessageToken; 36import org.logicprobe.LogicMail.mail.FolderExpungedEvent; 37import org.logicprobe.LogicMail.mail.FolderMessagesEvent; 38import org.logicprobe.LogicMail.mail.FolderTreeItem; 39import org.logicprobe.LogicMail.mail.MessageToken; 40import org.logicprobe.LogicMail.message.FolderMessage; 41import org.logicprobe.LogicMail.message.MessageEnvelope; 42 43import j2meunit.framework.Test; 44import j2meunit.framework.TestCase; 45import j2meunit.framework.TestMethod; 46import j2meunit.framework.TestSuite; 47 48public class MailboxNodeTest extends TestCase { 49 private MailboxNode instance; 50 51 /** Creates a new instance of MailboxNodeTest */ 52 public MailboxNodeTest() { 53 } 54 55 public MailboxNodeTest(String testName, TestMethod testMethod) { 56 super(testName, testMethod); 57 } 58 59 public void setUp() { 60 instance = new MailboxNode(new FolderTreeItem("INBOX", "INBOX", ".")); 61 } 62 63 public void tearDown() { 64 instance = null; 65 } 66 67 public void testAddMessage() { 68 MessageNode message1 = new MessageNode(createFolderMessage(1, 1, 1)); 69 MessageNode message2 = new MessageNode(createFolderMessage(2, 2, 2)); 70 MessageNode message3 = new MessageNode(createFolderMessage(3, 3, 3)); 71 MessageNode message4 = new MessageNode(createFolderMessage(4, 4, 4)); 72 73 // Add messages in-order 74 instance.addMessage(message1); 75 instance.addMessage(message2); 76 instance.addMessage(message3); 77 instance.addMessage(message4); 78 79 MessageNode[] messageNodes = instance.getMessages(); 80 assertEquals(4, messageNodes.length); 81 assertEquals(message1, messageNodes[0]); 82 assertEquals(message2, messageNodes[1]); 83 assertEquals(message3, messageNodes[2]); 84 assertEquals(message4, messageNodes[3]); 85 86 // Clear the messages 87 instance.clearMessages(); 88 messageNodes = instance.getMessages(); 89 assertEquals(0, messageNodes.length); 90 91 // Add messages out-of-order 92 instance.addMessage(message4); 93 instance.addMessage(message1); 94 instance.addMessage(message3); 95 instance.addMessage(message2); 96 97 messageNodes = instance.getMessages(); 98 assertEquals(4, messageNodes.length); 99 assertEquals(message1, messageNodes[0]); 100 assertEquals(message2, messageNodes[1]); 101 assertEquals(message3, messageNodes[2]); 102 assertEquals(message4, messageNodes[3]); 103 } 104 105 public void testAddMessagesFromEvent() { 106 FolderMessage message1 = createFolderMessage(1, 1, 1); 107 FolderMessage message2 = createFolderMessage(2, 2, 2); 108 FolderMessage message3 = createFolderMessage(3, 3, 3); 109 FolderMessage message4 = createFolderMessage(4, 4, 4); 110 111 instance.mailStoreFolderMessagesAvailable(new FolderMessagesEvent( 112 this, instance.getFolderTreeItem(), new FolderMessage[] { 113 message1, message2, message3, message4 114 })); 115 116 MessageNode[] messageNodes = instance.getMessages(); 117 assertEquals(4, messageNodes.length); 118 assertEquals(message1.getMessageToken(), messageNodes[0].getMessageToken()); 119 assertEquals(message2.getMessageToken(), messageNodes[1].getMessageToken()); 120 assertEquals(message3.getMessageToken(), messageNodes[2].getMessageToken()); 121 assertEquals(message4.getMessageToken(), messageNodes[3].getMessageToken()); 122 } 123 124 public void testHasMoreLoadableMessages() { 125 assertTrue("Empty mailbox", instance.hasMoreLoadableMessages()); 126 127 // Initial set of messages, assuming no more loadable 128 FolderMessage message1 = createFolderMessage(1, 1, 1); 129 FolderMessage message2 = createFolderMessage(2, 2, 2); 130 FolderMessage message3 = createFolderMessage(3, 3, 3); 131 FolderMessage message4 = createFolderMessage(4, 4, 4); 132 133 // Need to add from event, since this is the only place where the 134 // mailbox is able to directly read FolderMessage properties 135 instance.mailStoreFolderMessagesAvailable(new FolderMessagesEvent( 136 this, instance.getFolderTreeItem(), new FolderMessage[] { 137 message1, message2, message3, message4 138 })); 139 140 assertTrue("No more loadable", !instance.hasMoreLoadableMessages()); 141 142 // Fake an event to remove the first message 143 instance.mailStoreFolderExpunged(new FolderExpungedEvent( 144 this, instance.getFolderTreeItem(), 145 new MessageToken[] { new FakeMessageToken(1) }, 146 new MessageToken[0])); 147 148 assertTrue("Removed and has more loadable", instance.hasMoreLoadableMessages()); 149 150 instance.clearMessages(); 151 152 // Set of messages, assuming more are loadable 153 message1 = createFolderMessage(1, 11, 1); 154 message2 = createFolderMessage(2, 12, 2); 155 message3 = createFolderMessage(3, 13, 3); 156 message4 = createFolderMessage(4, 14, 4); 157 158 instance.mailStoreFolderMessagesAvailable(new FolderMessagesEvent( 159 this, instance.getFolderTreeItem(), new FolderMessage[] { 160 message1, message2, message3, message4 161 })); 162 163 assertTrue("Has more loadable", instance.hasMoreLoadableMessages()); 164 } 165 166 public void testFindMessageNodeGaps() { 167 // Empty mailbox test 168 MessageNode[][] result = instance.findMessageNodeGaps(); 169 String msg = "Empty mailbox"; 170 assertNotNull(msg, result); 171 assertEquals(msg, 0, result.length); 172 173 // Initial set of messages, assuming no more loadable 174 FolderMessage message1 = createFolderMessage(1, 1, 1); 175 FolderMessage message2 = createFolderMessage(2, 2, 2); 176 FolderMessage message3 = createFolderMessage(3, 3, 3); 177 FolderMessage message4 = createFolderMessage(4, 4, 4); 178 179 instance.mailStoreFolderMessagesAvailable(new FolderMessagesEvent( 180 this, instance.getFolderTreeItem(), new FolderMessage[] { 181 message1, message2, message3, message4 182 })); 183 184 result = instance.findMessageNodeGaps(); 185 msg = "No gaps"; 186 assertNotNull(msg, result); 187 assertEquals(msg, 0, result.length); 188 189 instance.clearMessages(); 190 191 message1 = createFolderMessage(1, 11, 1); 192 message2 = createFolderMessage(2, 12, 2); 193 message3 = createFolderMessage(3, 13, 3); 194 message4 = createFolderMessage(4, 14, 4); 195 196 instance.mailStoreFolderMessagesAvailable(new FolderMessagesEvent( 197 this, instance.getFolderTreeItem(), new FolderMessage[] { 198 message1, message2, message3, message4 199 })); 200 201 result = instance.findMessageNodeGaps(); 202 msg = "Gap at start"; 203 assertNotNull(msg, result); 204 assertEquals(msg, 1, result.length); 205 MessageNode[] gap = result[0]; 206 assertNotNull(msg, gap); 207 assertEquals(msg, 2, gap.length); 208 assertNull(msg, gap[0]); 209 assertEquals(msg, new FakeMessageToken(1), gap[1].getMessageToken()); 210 211 instance.clearMessages(); 212 213 message1 = createFolderMessage(1, 1, 1); 214 message2 = createFolderMessage(2, 2, 2); 215 message3 = createFolderMessage(3, 5, 3); 216 message4 = createFolderMessage(4, 6, 4); 217 218 instance.mailStoreFolderMessagesAvailable(new FolderMessagesEvent( 219 this, instance.getFolderTreeItem(), new FolderMessage[] { 220 message1, message2, message3, message4 221 })); 222 223 result = instance.findMessageNodeGaps(); 224 msg = "Gap in middle"; 225 assertNotNull(msg, result); 226 assertEquals(msg, 1, result.length); 227 gap = result[0]; 228 assertNotNull(msg, gap); 229 assertEquals(msg, 2, gap.length); 230 assertEquals(msg, new FakeMessageToken(2), gap[0].getMessageToken()); 231 assertEquals(msg, new FakeMessageToken(3), gap[1].getMessageToken()); 232 } 233 234 public void testFindMessageNodeGapsMultiple() { 235 // Two gaps in the middle 236 FolderMessage message1 = createFolderMessage(10, 1, 1); 237 FolderMessage message2 = createFolderMessage(20, 5, 2); 238 FolderMessage message3 = createFolderMessage(30, 6, 3); 239 FolderMessage message4 = createFolderMessage(40, 10, 4); 240 241 instance.mailStoreFolderMessagesAvailable(new FolderMessagesEvent( 242 this, instance.getFolderTreeItem(), new FolderMessage[] { 243 message1, message2, message3, message4 244 })); 245 246 MessageNode[][] result = instance.findMessageNodeGaps(); 247 String msg = "Gaps between 10-20 and 30-40"; 248 assertNotNull(msg, result); 249 assertEquals(msg, 2, result.length); 250 boolean found1 = false; 251 boolean found2 = false; 252 for(int i=0; i<result.length; i++) { 253 MessageNode[] gap = result[i]; 254 assertNotNull(msg, gap); 255 assertNotNull(msg, gap[0]); 256 assertNotNull(msg, gap[1]); 257 if(gap[0].getMessageToken().getUniqueId() == 10 258 && gap[1].getMessageToken().getUniqueId() == 20) { 259 found1 = true; 260 } 261 else if(gap[0].getMessageToken().getUniqueId() == 30 262 && gap[1].getMessageToken().getUniqueId() == 40) { 263 found2 = true; 264 } 265 } 266 assertTrue(msg, found1 && found2); 267 } 268 269 public void testFolderExpunged() { 270 // Create our initial set of messages 271 FolderMessage message1 = createFolderMessage(1, 1, 1); 272 FolderMessage message2 = createFolderMessage(2, 2, 2); 273 FolderMessage message3 = createFolderMessage(3, 3, 3); 274 FolderMessage message4 = createFolderMessage(4, 4, 4); 275 276 // These tests all verify correct expunge handling, which includes 277 // the removal of messages without gap creation. 278 279 String msg = "Two at the end"; 280 instance.mailStoreFolderMessagesAvailable(new FolderMessagesEvent( 281 this, instance.getFolderTreeItem(), new FolderMessage[] { 282 message1, message2, message3, message4 283 })); 284 285 instance.mailStoreFolderExpunged(new FolderExpungedEvent( 286 this, instance.getFolderTreeItem(), 287 new MessageToken[] { 288 message3.getMessageToken(), message4.getMessageToken() 289 }, 290 new MessageToken[0])); 291 292 MessageNode[] messageNodes = instance.getMessages(); 293 assertEquals(msg, 2, messageNodes.length); 294 assertEquals(msg, message1.getMessageToken(), messageNodes[0].getMessageToken()); 295 assertEquals(msg, message2.getMessageToken(), messageNodes[1].getMessageToken()); 296 MessageNode[][] messageGaps = instance.findMessageNodeGaps(); 297 assertEquals(msg, 0, messageGaps.length); 298 instance.clearMessages(); 299 300 msg = "Two at the beginning"; 301 instance.mailStoreFolderMessagesAvailable(new FolderMessagesEvent( 302 this, instance.getFolderTreeItem(), new FolderMessage[] { 303 message1, message2, message3, message4 304 })); 305 306 MessageToken updatedToken3 = message3.getMessageToken().clone(); 307 updatedToken3.updateMessageIndex(1); 308 MessageToken updatedToken4 = message4.getMessageToken().clone(); 309 updatedToken4.updateMessageIndex(2); 310 311 instance.mailStoreFolderExpunged(new FolderExpungedEvent( 312 this, instance.getFolderTreeItem(), 313 new MessageToken[] { 314 message1.getMessageToken(), message2.getMessageToken() 315 }, 316 new MessageToken[] { updatedToken3, updatedToken4 })); 317 318 messageNodes = instance.getMessages(); 319 assertEquals(msg, 2, messageNodes.length); 320 assertEquals(msg, message3.getMessageToken(), messageNodes[0].getMessageToken()); 321 assertEquals(msg, message4.getMessageToken(), messageNodes[1].getMessageToken()); 322 messageGaps = instance.findMessageNodeGaps(); 323 assertEquals(msg, 0, messageGaps.length); 324 instance.clearMessages(); 325 326 msg = "One in the middle"; 327 instance.mailStoreFolderMessagesAvailable(new FolderMessagesEvent( 328 this, instance.getFolderTreeItem(), new FolderMessage[] { 329 message1, message2, message3, message4 330 })); 331 332 updatedToken4 = message4.getMessageToken().clone(); 333 updatedToken4.updateMessageIndex(3); 334 335 instance.mailStoreFolderExpunged(new FolderExpungedEvent( 336 this, instance.getFolderTreeItem(), 337 new MessageToken[] { 338 message3.getMessageToken() 339 }, 340 new MessageToken[] { updatedToken4 })); 341 342 messageNodes = instance.getMessages(); 343 assertEquals(msg, 3, messageNodes.length); 344 assertEquals(msg, message1.getMessageToken(), messageNodes[0].getMessageToken()); 345 assertEquals(msg, message2.getMessageToken(), messageNodes[1].getMessageToken()); 346 assertEquals(msg, message4.getMessageToken(), messageNodes[2].getMessageToken()); 347 348 messageGaps = instance.findMessageNodeGaps(); 349 assertEquals(msg, 0, messageGaps.length); 350 } 351 352 private static FolderMessage createFolderMessage(int uid, int index, int sortOrder) { 353 MessageEnvelope envelope = new MessageEnvelope(); 354 envelope.subject = "Test " + uid; 355 envelope.date = new Date(1286920000 + sortOrder); 356 FakeMessageToken token = new FakeMessageToken(uid); 357 token.updateMessageIndex(index); 358 FolderMessage message = new FolderMessage(token, envelope, index, uid, -1); 359 return message; 360 } 361 362 public Test suite() { 363 TestSuite suite = new TestSuite("MailboxNode"); 364 365 suite.addTest(new MailboxNodeTest("addMessage", new TestMethod() 366 { public void run(TestCase tc) {((MailboxNodeTest)tc).testAddMessage(); } })); 367 suite.addTest(new MailboxNodeTest("addMessagesFromEvent", new TestMethod() 368 { public void run(TestCase tc) {((MailboxNodeTest)tc).testAddMessagesFromEvent(); } })); 369 suite.addTest(new MailboxNodeTest("hasMoreLoadableMessages", new TestMethod() 370 { public void run(TestCase tc) {((MailboxNodeTest)tc).testHasMoreLoadableMessages(); } })); 371 suite.addTest(new MailboxNodeTest("findMessageNodeGaps", new TestMethod() 372 { public void run(TestCase tc) {((MailboxNodeTest)tc).testFindMessageNodeGaps(); } })); 373 suite.addTest(new MailboxNodeTest("findMessageNodeGapsMultiple", new TestMethod() 374 { public void run(TestCase tc) {((MailboxNodeTest)tc).testFindMessageNodeGapsMultiple(); } })); 375 suite.addTest(new MailboxNodeTest("folderExpunged", new TestMethod() 376 { public void run(TestCase tc) {((MailboxNodeTest)tc).testFolderExpunged(); } })); 377 378 return suite; 379 } 380}