package com.limegroup.gnutella.browser;
import java.net.InetSocketAddress;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import org.jmock.Expectations;
import org.jmock.Mockery;
import org.limewire.io.GUID;
import org.limewire.util.BaseTestCase;
import com.limegroup.gnutella.FileDetails;
import com.limegroup.gnutella.URN;
import com.limegroup.gnutella.util.EncodingUtils;
public class MagnetOptionsTest extends BaseTestCase {
MagnetOptions[] validMagnets;
private String[] guidMagnets;
private Mockery context;
@Override
public void setUp() {
validMagnets = MagnetOptions.parseMagnet("magnet:?xt.1=urn:sha1:YNCKHTQCWBTRNJIV4WNAE52SJUQCZO5C&xt.2=urn:sha1:TXGCZQTH26NL6OUQAJJPFALHG2LTGBC7");
guidMagnets = new String[] {
"magnet:?xt=urn:sha1:YNCKHTQCWBTRNJIV4WNAE52SJUQCZO5C&xs=" + URN.createGUIDUrn(new GUID()),
"magnet:?xt=urn:sha1:YNCKHTQCWBTRNJIV4WNAE52SJUQCZO5C&xs=http://127.0.0.1:6346/uri-res/N2R?urn:sha1:YNCKHTQCWBTRNJIV4WNAE52SJUQCZO5C&xs=" + URN.createGUIDUrn(new GUID()),
"magnet:?xt=urn:sha1:YNCKHTQCWBTRNJIV4WNAE52SJUQCZO5C&as=" + URN.createGUIDUrn(new GUID()),
"magnet:?xt=urn:sha1:YNCKHTQCWBTRNJIV4WNAE52SJUQCZO5C&xs=" + URN.createGUIDUrn(new GUID()),
};
context = new Mockery();
}
public MagnetOptionsTest(String name) {
super(name);
}
public void testParseValidMagnet() {
MagnetOptions[] opts = MagnetOptions.parseMagnet("magnet:?dn="
+ EncodingUtils.encode("compilc.:fileNm?7ßä") + "&kt="
+ EncodingUtils.encode("keyword topic string")
+ "&xt=urn:sha1:YNCKHTQCWBTRNJIV4WNAE52SJUQCZO5C&xs=http://127.0.0.1:6346/uri-res/N2R?urn:sha1:YNCKHTQCWBTRNJIV4WNAE52SJUQCZO5C");
assertEquals("Should have parsed one magnet", 1, opts.length);
opts = MagnetOptions.parseMagnet(opts[0].toString());
assertEquals("Should have parsed one magnet", 1, opts.length);
opts = MagnetOptions.parseMagnet("magnet:?dn=" + EncodingUtils.encode("compile me")
+ "&xt=urn:sha1:YNCKHTQCWBTRNJIV4WNAE52SJUQCZO59&xs=http://127.0.0.1:6346/uri-res/N2R?urn:sha1:YNCKHTQCWBTRNJIV4WNAE52SJUQCZO59");
assertEquals("Should have parsed one magnet", 1, opts.length);
opts = MagnetOptions.parseMagnet(opts[0].toString());
assertEquals("Should have parsed one magnet", 1, opts.length);
opts = MagnetOptions.parseMagnet("magnet:?xt.1=urn:sha1:YNCKHTQCWBTRNJIV4WNAE52SJUQCZO5C&xt.2=urn:sha1:TXGCZQTH26NL6OUQAJJPFALHG2LTGBC7");
assertEquals("Should have parsed 2 magnets", 2, opts.length);
// compound magnets
opts = MagnetOptions.parseMagnet("magnet:?xt.1=urn:sha1:YNCKHTQCWBTRNJIV4WNAE52SJUQCZO5C&xt.2=urn:sha1:TXGCZQTH26NL6OUQAJJPFALHG2LTGBC7");
assertEquals("Should have parsed 2 magnets", 2, opts.length);
}
public void testParseInvalidMagnet() {
MagnetOptions[] opts = MagnetOptions.parseMagnet("magnet:?");
assertEquals("Wrong number of parsed magnets", 0, opts.length);
}
public void testisDownloadable() {
// invalid magnets
// is invalid because we don't have a url
MagnetOptions[] opts = MagnetOptions.parseMagnet("magnet:?xt=urn:sha1:WRCIRZV5ZO56CWMNHFV4FRGNPWPPDVKT");
assertEquals("Wrong number of parsed magnets", 1, opts.length);
assertFalse("Should not be downloadable", opts[0].isDownloadable());
// invalid: has empty kt
opts = MagnetOptions.parseMagnet("magnet:?kt=&xt=urn:sha1:WRCIRZV5ZO56CWMNHFV4FRGNPWPPDVKT");
assertEquals("Wrong number of parsed magnets", 1, opts.length);
assertFalse("Should not be downloadable", opts[0].isDownloadable());
// invalid: has only a display name
opts = MagnetOptions.parseMagnet("magnet:?dn=me");
assertEquals("Wrong number of parsed magnets", 1, opts.length);
assertFalse("Should not be downloadable", opts[0].isDownloadable());
// valid magnets
// valid: has a url and a sha1
opts = MagnetOptions.parseMagnet("magnet:?xs=http://magnet2.limewire.com:6346/uri-res/N2R?urn:sha1:WRCIRZV5ZO56CWMNHFV4FRGNPWPPDVKT");
assertEquals("Wrong number of parsed magnets", 1, opts.length);
assertTrue("Should be valid", opts[0].isDownloadable());
// valid: has a url and keyword topic
opts = MagnetOptions.parseMagnet("magnet:?kt=test&xs=http://magnet2.limewire.com:6346");
assertEquals("Wrong number of parsed magnets", 1, opts.length);
assertTrue("Should be valid", opts[0].isDownloadable());
// valid: has everything
opts = MagnetOptions.parseMagnet("magnet:?xt=urn:sha1:WRCIRZV5ZO56CWMNHFV4FRGNPWPPDVKT&dn=-weed-Soul%20Coughing-Rolling.wma&xs=http://magnet2.limewire.com:6346/uri-res/N2R?urn:sha1:WRCIRZV5ZO56CWMNHFV4FRGNPWPPDVKT");
assertEquals("Wrong number of parsed magnets", 1, opts.length);
assertTrue("Should be invalid", opts[0].isDownloadable());
// downloadable: has kt and hash
opts = MagnetOptions.parseMagnet("magnet:?kt=test&xt=urn:sha1:WRCIRZV5ZO56CWMNHFV4FRGNPWPPDVKT");
assertEquals("Wrong number of parsed magnets", 1, opts.length);
assertTrue("Should be valid", opts[0].isDownloadable());
// downloadable: has dn and hash
opts = MagnetOptions.parseMagnet("magnet:?dn=test&xt=urn:sha1:WRCIRZV5ZO56CWMNHFV4FRGNPWPPDVKT");
assertEquals("Wrong number of parsed magnets", 1, opts.length);
assertTrue("Should be valid", opts[0].isDownloadable());
}
public void testIsHashOnly() {
// hash only
MagnetOptions[] opts = MagnetOptions.parseMagnet("magnet:?xt=http://magnet2.limewire.com:6346/uri-res/N2R?urn:sha1:WRCIRZV5ZO56CWMNHFV4FRGNPWPPDVKT");
assertEquals("Wrong number of parsed magnets", 1, opts.length);
assertTrue("Should be valid", opts[0].isDownloadable());
assertTrue("Should be hash only", opts[0].isHashOnly());
// not hash only
opts = MagnetOptions.parseMagnet("magnet:?xt=urn:sha1:WRCIRZV5ZO56CWMNHFV4FRGNPWPPDVKT&dn=-weed-Soul%20Coughing-Rolling.wma&xs=http://magnet2.limewire.com:6346/uri-res/N2R?urn:sha1:WRCIRZV5ZO56CWMNHFV4FRGNPWPPDVKT");
assertEquals("Wrong number of parsed magnets", 1, opts.length);
assertTrue("Should be invalid", opts[0].isDownloadable());
assertFalse("Should not be hash only", opts[0].isHashOnly());
opts = MagnetOptions.parseMagnet("magnet:?kt=test&xs=http://magnet2.limewire.com:6346");
assertEquals("Wrong number of parsed magnets", 1, opts.length);
assertTrue("Should be invalid", opts[0].isDownloadable());
assertFalse("Should not be hash only", opts[0].isHashOnly());
assertTrue(opts[0].getGUIDUrns().isEmpty());
}
public void testGetFileNameForSaving() throws Exception {
MagnetOptions magnet = MagnetOptions.createMagnet(null, "file name", null, null);
assertEquals("file name", magnet.getFileNameForSaving());
magnet = MagnetOptions.createMagnet("keywords", null, null, null);
assertEquals("keywords", magnet.getFileNameForSaving());
magnet = MagnetOptions.createMagnet("keywords", "", null, null);
assertEquals("keywords", magnet.getFileNameForSaving());
URN urn = URN.createSHA1Urn("urn:sha1:GLSTHIPQGSSZTS5FJUPAKPZWUGYQYPFB");
magnet = MagnetOptions.createMagnet(null, null, urn, null);
assertEquals(urn.toString(), magnet.getFileNameForSaving());
magnet = MagnetOptions.createMagnet("", "", urn, null);
assertEquals(urn.toString(), magnet.getFileNameForSaving());
magnet = MagnetOptions.createMagnet(null, null, null, new String[] { "http://www.limewire.com:4444/test.file" });
assertEquals("test.file", magnet.getFileNameForSaving());
magnet = MagnetOptions.createMagnet(null, null, null, new String[] { "http://www.limewire.com:4444/test.file?notpartofthename" });
assertEquals("test.file", magnet.getFileNameForSaving());
magnet = MagnetOptions.createMagnet("", "", null, new String[] { "http://192.168.0.2/test.file" });
assertEquals("test.file", magnet.getFileNameForSaving());
magnet = MagnetOptions.createMagnet(null, null, null, new String[] { "http://host/" });
assertEquals("MAGNET download from host", magnet.getFileNameForSaving());
magnet = MagnetOptions.createMagnet(null, null, null, null);
assertNotNull(magnet.getFileNameForSaving());
}
public void testParseValidMagnets() {
String magnets = createMultiLineMagnetLinks(validMagnets);
MagnetOptions[] opts = MagnetOptions.parseMagnets(magnets);
assertEquals("Should have parsed " + validMagnets.length + " magnets", validMagnets.length, opts.length);
// and parse again
assertEquals("Should have parsed " + opts.length + " magnets", opts.length,
MagnetOptions.parseMagnets(createMultiLineMagnetLinks(opts)).length);
// compound magnets with multiple lines
opts = MagnetOptions.parseMagnets
("magnet:?xt.1=urn:sha1:YNCKHTQCWBTRNJIV4WNAE52SJUQCZO5C&xt.2=urn:sha1:TXGCZQTH26NL6OUQAJJPFALHG2LTGBC7"
+ System.getProperty("line.separator")
+ "magnet:?xt.1=urn:sha1:YNCKHTQCWBTRNJIV4WNAE52SJUQCZO5C&xt.2=urn:sha1:TXGCZQTH26NL6OUQAJJPFALHG2LTGBC7");
assertEquals("Should have parsed 2 magnets", 4, opts.length);
}
public void testMagnetOptionsParsesGuidUrns() {
String prefix = "magnet:?dn=filename&kt=keyword&xt=urn:sha1:YNCKHTQCWBTRNJIV4WNAE52SJUQCZO5C&xs=http://127.0.0.1:6346/uri-res/N2R?urn:sha1:YNCKHTQCWBTRNJIV4WNAE52SJUQCZO5C";
String guidUrn = "urn:guid:" + new GUID().toHexString();
String magnet = prefix + "&xs=" + guidUrn;
MagnetOptions opts = MagnetOptions.parseMagnet(magnet)[0];
assertContains(opts.getXS(), guidUrn);
// same for alternate sources
magnet = prefix + "&as=" + guidUrn;
opts = MagnetOptions.parseMagnet(magnet)[0];
assertContains(opts.getAS(), guidUrn);
}
public void testGetGUIDUrns() {
List<String> magnets = new ArrayList<String>(Arrays.asList(guidMagnets));
// and add them as all upper case too
for (String magnet : guidMagnets) {
magnets.add(magnet.toUpperCase(Locale.US));
}
for (String magnet : magnets) {
MagnetOptions options = MagnetOptions.parseMagnet(magnet)[0];
Collection<URN> urns = options.getGUIDUrns();
assertFalse(urns.isEmpty());
for (URN urn : urns) {
assertTrue(urn.isGUID());
}
}
// magnets without GUID urns
for (MagnetOptions magnet : validMagnets) {
assertTrue(magnet.getGUIDUrns().isEmpty());
}
}
public void testCreateMagnetWithGUIDUrn() throws Exception {
final GUID guid = new GUID();
final URN urn = URN.createSHA1Urn("urn:sha1:PLSTHIPQGSSZTS5FJUPAKOZWUGZQYPFB");
final FileDetails fileDetails = context.mock(FileDetails.class);
context.checking(new Expectations() {{
allowing(fileDetails).getFileName();
will(returnValue("filename"));
allowing(fileDetails).getSHA1Urn();
will(returnValue(urn));
// first time a zero file size
one(fileDetails).getSize();
will(returnValue(-1L));
one(fileDetails).getSize();
will(returnValue(123456789L));
}});
MagnetOptions magnet = MagnetOptions.createMagnet(fileDetails, null, guid.bytes());
assertTrue(magnet.toExternalForm().contains(guid.toHexString()));
assertEquals(urn, magnet.getSHA1Urn());
assertEquals(URN.createGUIDUrn(guid), magnet.getGUIDUrns().iterator().next());
assertFalse(magnet.toExternalForm().contains("xl"));
assertEquals(-1, magnet.getFileSize());
magnet = MagnetOptions.createMagnet(fileDetails, new InetSocketAddress("127.0.0.1", 5555), guid.bytes());
assertTrue(magnet.toExternalForm().contains(guid.toHexString()));
assertEquals(urn, magnet.getSHA1Urn());
assertEquals(URN.createGUIDUrn(guid), magnet.getGUIDUrns().iterator().next());
assertEquals(2, magnet.getXS().size());
assertTrue(magnet.toExternalForm().contains("127.0.0.1:5555"));
assertEquals(1, magnet.getDefaultURLs().length);
assertTrue(magnet.toExternalForm().contains("xl=123456789"));
assertEquals(123456789, magnet.getFileSize());
}
public void testCreateMagnetOptionsWithGuidUrns() throws Exception {
GUID guid = new GUID();
URN guidUrn = URN.createGUIDUrn(guid);
URN sha1Urn = URN.createSHA1Urn("urn:sha1:GLSTHIPQGSSZTS5FJUPAKPZWUGYQYPFB");
MagnetOptions magnet = MagnetOptions.createMagnet("hello", "fileName", sha1Urn, null, Collections.singleton(guidUrn));
assertEquals(Collections.singleton(guidUrn), magnet.getGUIDUrns());
assertTrue(magnet.toExternalForm().contains(guidUrn.httpStringValue()));
}
private String createMultiLineMagnetLinks(MagnetOptions[] opts) {
StringBuilder buffer = new StringBuilder();
for (int i = 0; i < opts.length; i++) {
if (i > 0) {
buffer.append(System.getProperty("line.separator"));
}
buffer.append(opts[i].toString());
}
return buffer.toString();
}
}