/* * Jitsi, the OpenSource Java VoIP and Instant Messaging client. * * Copyright @ 2015 Atlassian Pty Ltd * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package net.java.sip.communicator.slick.msghistory; import java.util.*; import junit.framework.*; import net.java.sip.communicator.impl.protocol.mock.*; import net.java.sip.communicator.service.contactlist.*; import net.java.sip.communicator.service.history.*; import net.java.sip.communicator.service.msghistory.*; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.service.protocol.event.*; import net.java.sip.communicator.util.*; import org.osgi.framework.*; /** * Tests message history. * First installs the MoxkProtocolProvider to be able to send some messages * The message history service stores them * and then tests the verious find methods - does they find the messsages we have * already sent * * @author Damian Minkov */ public class TestMsgHistoryServiceMultiChat extends TestCase { private static final Logger logger = Logger.getLogger(TestMsgHistoryServiceMultiChat.class); static final String TEST_CONTACT_NAME_1 = "Mincho_Penchev_the_fisrt"; static final String TEST_CONTACT_NAME_2 = "Mincho_Penchev_the_second"; static final String TEST_ROOM_NAME = "test_room"; /** * The provider that we use to make a dummy server-stored contactlist * used for testing. The mockProvider is instantiated and registered * by the metacontactlist slick activator. */ public static MockProvider mockProvider = null; /** * The persistent presence operation set of the default mock provider. */ public static MockPersistentPresenceOperationSet mockPresOpSet = null; public static MockBasicInstantMessaging mockBImOpSet = null; public static MockMultiUserChat mockMultiChat = null; private static ServiceReference msgHistoryServiceRef = null; public static MessageHistoryService msgHistoryService = null; public static HistoryService historyService = null; private static MockContact testContact = null; private static ServiceReference metaCLref = null; private static MetaContactListService metaClService = null; private static MetaContact testMetaContact = null; /** * A reference to the registration of the first mock provider. */ public static ServiceRegistration mockPrServiceRegistration = null; private static Message[] messagesToSend = null; private static Date controlDate1 = null; private static Date controlDate2 = null; private static Object lock = new Object(); public TestMsgHistoryServiceMultiChat(String name) { super(name); } public static Test suite() { TestSuite suite = new TestSuite(); suite.addTest( new TestMsgHistoryServiceMultiChat("readRecordsFromMultiChat")); return suite; } @Override protected void setUp() throws Exception { setupContact(); msgHistoryService.eraseLocallyStoredHistory(); writeRecordsToMultiChat(); } @Override protected void tearDown() throws Exception { metaClService.purgeLocallyStoredContactListCopy(); } public void setupContact() { // changes the history service target derictory System.setProperty("HistoryServiceDirectory", "test-msghistory"); mockProvider = new MockProvider("MessageHistoryMockUser"); //store thre presence op set of the new provider into the fixture Map<String, OperationSet> supportedOperationSets = mockProvider.getSupportedOperationSets(); //get the operation set presence here. mockPresOpSet = (MockPersistentPresenceOperationSet) supportedOperationSets.get( OperationSetPersistentPresence.class.getName()); mockBImOpSet = (MockBasicInstantMessaging) supportedOperationSets.get( OperationSetBasicInstantMessaging.class.getName()); mockMultiChat = (MockMultiUserChat) supportedOperationSets.get( OperationSetMultiUserChat.class.getName()); msgHistoryServiceRef = MsgHistoryServiceLick.bc. getServiceReference(MessageHistoryService.class.getName()); msgHistoryService = (MessageHistoryService)MsgHistoryServiceLick.bc. getService(msgHistoryServiceRef); ServiceReference historyServiceRef = MsgHistoryServiceLick.bc. getServiceReference(HistoryService.class.getName()); historyService = (HistoryService)MsgHistoryServiceLick.bc. getService(historyServiceRef); // fill in a contact to comunicate with MockContactGroup root = (MockContactGroup)mockPresOpSet.getServerStoredContactListRoot(); testContact = new MockContact(TEST_CONTACT_NAME_1, mockProvider); root.addContact(testContact); metaCLref = MsgHistoryServiceLick.bc.getServiceReference( MetaContactListService.class.getName()); metaClService = (MetaContactListService)MsgHistoryServiceLick.bc.getService(metaCLref); System.setProperty(MetaContactListService.PROVIDER_MASK_PROPERTY, "1"); Hashtable<String, String> mockProvProperties = new Hashtable<String, String>(); mockProvProperties.put(ProtocolProviderFactory.PROTOCOL , mockProvider.getProtocolName()); mockProvProperties.put(MetaContactListService.PROVIDER_MASK_PROPERTY, "1"); mockPrServiceRegistration = MsgHistoryServiceLick.bc.registerService( ProtocolProviderService.class.getName(), mockProvider, mockProvProperties); logger.debug("Registered a mock protocol provider! "); testMetaContact = metaClService.getRoot(). getMetaContact(mockProvider, TEST_CONTACT_NAME_1); // add one more contact as specific problems may happen only when // more than one contact is in the metacontact metaClService.addNewContactToMetaContact( mockProvider, testMetaContact, TEST_CONTACT_NAME_2); messagesToSend = new Message[] { mockBImOpSet.createMessage("test message word1-" + Math.random()), mockBImOpSet.createMessage("test message word2" + Math.random()), mockBImOpSet.createMessage("test message word3" + Math.random()), mockBImOpSet.createMessage("test message word4" + Math.random()), mockBImOpSet.createMessage("test message word5" + Math.random()), mockBImOpSet.createMessage("Hello \u0002World\u0002!"), mockBImOpSet.createMessage("less than < this, greater than > and an ampersand &") }; } private static void waitWrite(long timeout) { synchronized (lock) { // wait a moment try { lock.wait(timeout); } catch (InterruptedException ex) { } } } public void writeRecordsToMultiChat() { try { ChatRoom room = mockMultiChat.createChatRoom("test_room", null); room.join(); // ChatRoom room = mockMultiChat.findRoom(TEST_ROOM_NAME); // room.joinAs(TEST_CONTACT_NAME); // First deliver message, so they are stored by the message history service room.sendMessage(messagesToSend[0]); waitWrite(1000); TestMsgHistoryServiceMultiChat.controlDate1 = new Date(); logger.info("controlDate1:" + controlDate1.getTime()); waitWrite(1000); room.sendMessage(messagesToSend[1]); waitWrite(100); room.sendMessage(messagesToSend[2]); waitWrite(1000); TestMsgHistoryServiceMultiChat.controlDate2 = new Date(); logger.info("controlDate2:" + controlDate2.getTime()); waitWrite(1000); room.sendMessage(messagesToSend[3]); waitWrite(1000); room.sendMessage(messagesToSend[4]); waitWrite(1000); } catch(OperationFailedException ex) { fail("Failed to create room : " + ex.getMessage()); logger.error("Failed to create room", ex); } catch(OperationNotSupportedException ex) { fail("Failed to create room : " + ex.getMessage()); logger.error("Failed to create room", ex); } } /** * tests all read methods (finders) */ public void readRecordsFromMultiChat() { ChatRoom room = null; try { room = mockMultiChat.findRoom(TEST_ROOM_NAME); }catch(Exception ex) { fail("Cannot find room!" + ex.getMessage()); } /** * This matches all written messages, they are minimum 5 */ Collection<EventObject> rs = msgHistoryService.findByKeyword(room, "test"); assertTrue("Nothing found findByKeyword ", !rs.isEmpty()); List<String> msgs = getChatMessages(rs); assertTrue("Messages too few - findByKeyword", msgs.size() >= 5); /** * Will test case sensitive and insensitive search */ rs = msgHistoryService.findByKeyword(room, "Test", false); assertTrue("Nothing found findByKeyword caseINsensitive search", !rs.isEmpty()); msgs = getChatMessages(rs); assertTrue("Messages too few - findByKeyword", msgs.size() >= 5); rs = msgHistoryService.findByKeyword(room, "Test", true); assertFalse("Something found by findByKeyword casesensitive search", !rs.isEmpty()); /** * This must match also many messages, as tests are run many times * but the minimum is 3 */ rs = msgHistoryService.findByEndDate(room, controlDate2); assertTrue("Nothing found findByEndDate", !rs.isEmpty()); msgs = getChatMessages(rs); assertTrue("Messages too few - findByEndDate", msgs.size() >= 3); /** * This must find also many messages but atleast one */ rs = msgHistoryService.findByKeywords( room, new String[]{"test", "word2"}); assertTrue("Nothing found findByKeywords", !rs.isEmpty()); msgs = getChatMessages(rs); assertTrue("Messages too few - findByKeywords", msgs.size() >= 1); /** * Nothing to be found */ rs = msgHistoryService.findByKeywords( room, new String[]{"test1", "word2"}); assertFalse("Something found findByKeywords", !rs.isEmpty()); /** * must find 2 messages */ rs = msgHistoryService.findByPeriod( room, controlDate1, controlDate2); assertTrue("Nothing found findByPeriod", !rs.isEmpty()); msgs = getChatMessages(rs); assertEquals("Messages must be 2", 2, msgs.size()); assertTrue("Message no found", msgs.contains(messagesToSend[1].getContent())); assertTrue("Message no found", msgs.contains(messagesToSend[2].getContent())); /** * must find 1 record */ rs = msgHistoryService.findByPeriod( room, controlDate1, controlDate2, new String[]{"word2"}); assertTrue("Nothing found findByPeriod", !rs.isEmpty()); msgs = getChatMessages(rs); assertEquals("Messages must be 1", 1, msgs.size()); assertTrue("Message no found", msgs.contains(messagesToSend[1].getContent())); /** * must find 2 records */ rs = msgHistoryService.findByStartDate(room, controlDate2); assertTrue("Nothing found findByStartDate", !rs.isEmpty()); msgs = getChatMessages(rs); assertEquals("Messages must be 2", 2, msgs.size()); assertTrue("Message no found", msgs.contains(messagesToSend[3].getContent())); assertTrue("Message no found", msgs.contains(messagesToSend[4].getContent())); /** * Must return exactly the last 3 messages */ rs = msgHistoryService.findLast(room, 3); assertTrue("Nothing found 8", !rs.isEmpty()); msgs = getChatMessages(rs); assertEquals("Messages must be 3", 3, msgs.size()); assertTrue("Message no found", msgs.contains(messagesToSend[2].getContent())); assertTrue("Message no found", msgs.contains(messagesToSend[3].getContent())); assertTrue("Message no found", msgs.contains(messagesToSend[4].getContent())); /** * Must return exactly the 3 messages after controlDate1 */ rs = msgHistoryService.findFirstMessagesAfter(room, controlDate1, 3); assertTrue("Nothing found 9", !rs.isEmpty()); msgs = getChatMessages(rs); assertEquals("Messages must be 3", 3, msgs.size()); assertTrue("Message no found", msgs.contains(messagesToSend[1].getContent())); assertTrue("Message no found", msgs.contains(messagesToSend[2].getContent())); assertTrue("Message no found", msgs.contains(messagesToSend[3].getContent())); /** * Must return exactly the 3 messages before controlDate2 */ rs = msgHistoryService.findLastMessagesBefore(room, controlDate2, 3); assertTrue("Nothing found 10", !rs.isEmpty()); msgs = getChatMessages(rs); assertEquals("Messages must be 3", 3, msgs.size()); assertTrue("Message no found", msgs.contains(messagesToSend[0].getContent())); assertTrue("Message no found", msgs.contains(messagesToSend[1].getContent())); assertTrue("Message no found", msgs.contains(messagesToSend[2].getContent())); } private List<String> getMessages(Collection<EventObject> rs) { List<String> result = new Vector<String>(); for (EventObject item : rs) { if(item instanceof MessageDeliveredEvent) result.add( ((MessageDeliveredEvent)item) .getSourceMessage().getContent()); else if(item instanceof MessageReceivedEvent) result.add( ((MessageReceivedEvent)item) .getSourceMessage().getContent()); } return result; } private List<String> getChatMessages(Collection<EventObject> rs) { List<String> result = new Vector<String>(); for (EventObject item : rs) { if(item instanceof ChatRoomMessageDeliveredEvent) result.add(((ChatRoomMessageDeliveredEvent)item). getMessage().getContent()); else if(item instanceof ChatRoomMessageReceivedEvent) result.add(((ChatRoomMessageReceivedEvent)item). getMessage().getContent()); } return result; } }