package com.limegroup.gnutella; import java.io.UnsupportedEncodingException; import java.util.Arrays; import java.util.Set; import junit.framework.Test; import org.limewire.core.settings.FilterSettings; import org.limewire.gnutella.tests.ActivityCallbackStub; import org.limewire.gnutella.tests.LimeTestUtils; import org.limewire.io.GUID; import org.limewire.util.MediaType; import com.google.inject.Injector; import com.google.inject.Singleton; import com.limegroup.gnutella.connection.BlockingConnection; import com.limegroup.gnutella.filters.response.XMLDocFilterTest; import com.limegroup.gnutella.helpers.UrnHelper; import com.limegroup.gnutella.messages.BadPacketException; import com.limegroup.gnutella.messages.QueryReply; import com.limegroup.gnutella.messages.QueryReplyFactory; import com.limegroup.gnutella.messages.QueryRequest; import com.limegroup.gnutella.util.DataUtils; import com.limegroup.gnutella.xml.LimeXMLDocumentFactory; import com.limegroup.gnutella.xml.LimeXMLDocumentHelper; import com.limegroup.gnutella.xml.LimeXMLNames; import com.limegroup.gnutella.xml.LimeXMLUtils; /** * Tests the client's WhatIsNewSearch behavior. */ public class ClientSideWhatIsNewSearchTest extends ClientSideTestCase { private StoreRepliesActivityCallback callback; private SearchServices searchServices; private ResponseFactory responseFactory; private QueryReplyFactory queryReplyFactory; private LimeXMLDocumentFactory limeXMLDocumentFactory; public ClientSideWhatIsNewSearchTest(String name) { super(name); } public static Test suite() { return buildTestSuite(ClientSideWhatIsNewSearchTest.class); } @Override protected void setUp() throws Exception { Injector injector = LimeTestUtils.createInjector(StoreRepliesActivityCallback.class); super.setUp(injector); callback = (StoreRepliesActivityCallback) injector.getInstance(ActivityCallback.class); searchServices = injector.getInstance(SearchServices.class); responseFactory = injector.getInstance(ResponseFactory.class); queryReplyFactory = injector.getInstance(QueryReplyFactory.class); limeXMLDocumentFactory = injector.getInstance(LimeXMLDocumentFactory.class); } @Override public int getNumberOfPeers() { return 1; } /** * Ensure all results come through if filtering is disabled. */ public void testAdultFilterDisabled() throws Exception { testAdultFilter(false); } /** * Ensure appropiate results are filtered when adult filtering is turned on * and valid results still get through. */ public void testAdultFilterEnabled() throws Exception { testAdultFilter(true); } public void testAdultFilter(boolean enabled) throws Exception { FilterSettings.FILTER_WHATS_NEW_ADULT.setValue(enabled); drainAll(); GUID guid = new GUID(); searchServices.queryWhatIsNew(guid.bytes(), MediaType.getAnyTypeMediaType()); assertQuery(testUP[0], guid); // send back a result that will be filtered Response resp = responseFactory.createResponse(101, 1019, "sex", UrnHelper.SHA1); sendAndAssertResponse(resp, guid, enabled); resp = XMLDocFilterTest.createXMLResponse("filename", LimeXMLNames.VIDEO_TYPE, "adult", responseFactory, limeXMLDocumentFactory); sendAndAssertResponse(resp, guid, enabled); resp = XMLDocFilterTest.createXMLResponse("filename", LimeXMLNames.VIDEO_RATING, "NC-17", responseFactory, limeXMLDocumentFactory); sendAndAssertResponse(resp, guid, enabled); resp = responseFactory.createResponse(105, 345, "harmless", UrnHelper.SHA1); sendAndAssertResponse(resp, guid, false); } private void sendAndAssertResponse(Response resp, GUID guid, boolean expectedToBeFiltered) throws Exception { QueryReply reply = createReply(resp, guid, testUP[0].getPort(), testUP[0].getInetAddress().getAddress()); callback.guid = reply.getClientGUID(); callback.desc = null; testUP[0].send(reply); testUP[0].flush(); RemoteFileDesc desc = callback.waitForRFD(1000); if (expectedToBeFiltered) { assertNull(desc); } else { assertNotNull(desc); assertEquals(resp.getName(), desc.getFileName()); } } private QueryRequest assertQuery(BlockingConnection c, GUID guid) throws BadPacketException { QueryRequest qr = BlockingConnectionUtils.getFirstInstanceOfMessageType(c, QueryRequest.class); assertNotNull(qr); assertEquals(guid.bytes(), qr.getGUID()); return qr; } @Singleton private static class StoreRepliesActivityCallback extends ActivityCallbackStub { RemoteFileDesc desc = null; byte[] guid = null; @Override public synchronized void handleQueryResult(RemoteFileDesc rfd, QueryReply queryReply, Set alts) { if (Arrays.equals(queryReply.getClientGUID(), guid)) { desc = rfd; notify(); } } public synchronized RemoteFileDesc waitForRFD(long timeout) throws Exception { if (desc == null) { wait(timeout); } return desc; } } public QueryReply createReply(Response resp, GUID guid, int port, byte[] address) { String xmlCollectionString = LimeXMLDocumentHelper.getAggregateString(new Response [] { resp } ); if (xmlCollectionString == null) xmlCollectionString = ""; byte[] xmlBytes = null; try { xmlBytes = xmlCollectionString.getBytes("UTF-8"); } catch(UnsupportedEncodingException ueex) {//no support for utf-8?? } byte[] xmlCompressed = null; if (!xmlCollectionString.equals("")) xmlCompressed = LimeXMLUtils.compress(xmlBytes); else //there is no XML xmlCompressed = DataUtils.EMPTY_BYTE_ARRAY; return queryReplyFactory.createQueryReply(guid.bytes(), (byte)1, port, address, 0, new Response[] { resp }, GUID.makeGuid(), xmlCompressed, false, false, true, true, true, false); } }