mirror of
https://github.com/OPSnet/bencode-torrent.git
synced 2026-01-16 20:04:48 -05:00
533 lines
17 KiB
PHP
533 lines
17 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace OrpheusNET\BencodeTorrent;
|
|
|
|
class BencodeTorrentTest extends \PHPUnit\Framework\TestCase
|
|
{
|
|
public function testLoadTorrent(): void
|
|
{
|
|
$bencode = new BencodeTorrent();
|
|
try {
|
|
$bencode->decodeFile(__DIR__ . '/data/test_1.torrent');
|
|
} catch (\Exception $exc) {
|
|
$this->fail('Decode should not have thrown exception');
|
|
}
|
|
$data = $bencode->getData();
|
|
$this->assertEquals(
|
|
'https://localhost:34000/4f9587fbcb06fe09165e4f84d35d0403/announce',
|
|
$data['announce']
|
|
);
|
|
$this->assertEquals(
|
|
'https://localhost:8080/torrents.php?id=2&torrentid=2',
|
|
$data['comment']
|
|
);
|
|
$this->assertEquals('uTorrent/3.4.2', $data['created by']);
|
|
$this->assertEquals(1425699508, $data['creation date']);
|
|
$this->assertEquals('UTF-8', $data['encoding']);
|
|
$this->assertArrayHasKey('info', $data);
|
|
$this->assertCount(11, $data['info']['files']);
|
|
$files = [
|
|
[
|
|
'length' => 12310347,
|
|
'path' => ['02 Should have known better.mp3']
|
|
],
|
|
[
|
|
'length' => 12197480,
|
|
'path' => ['09 John My Beloved.mp3']
|
|
],
|
|
[
|
|
'length' => 11367829,
|
|
'path' => ['07 The Only Thing.mp3']
|
|
],
|
|
[
|
|
'length' => 11360526,
|
|
'path' => ['11 Blue Bucket of Gold.mp3']
|
|
],
|
|
[
|
|
'length' => 11175567,
|
|
'path' => ['06 Fourth of July.mp3']
|
|
],
|
|
[
|
|
'length' => 9584196,
|
|
'path' => ['01 Death with Dignity.mp3']
|
|
],
|
|
[
|
|
'length' => 8871591,
|
|
'path' => ['03 All of me wants all of you.mp3']
|
|
],
|
|
[
|
|
'length' => 7942661,
|
|
'path' => ['04 Drawn to the Blood.mp3']
|
|
],
|
|
[
|
|
'length' => 7789055,
|
|
'path' => ['08 Carrie & Lowell.mp3']
|
|
],
|
|
[
|
|
'length' => 6438044,
|
|
'path' => ['10 No shade in the shadow of the cross.mp3']
|
|
],
|
|
[
|
|
'length' => 5878964,
|
|
'path' => ['05 Eugene.mp3']
|
|
]
|
|
];
|
|
$this->assertEquals($files, $data['info']['files']);
|
|
$this->assertEquals(
|
|
'Sufjan Stevens - Carrie & Lowell (2015) [MP3 320]',
|
|
$data['info']['name']
|
|
);
|
|
$this->assertEquals(
|
|
'Sufjan Stevens - Carrie & Lowell (2015) [MP3 320]',
|
|
$bencode->getName()
|
|
);
|
|
$this->assertEquals(16020, strlen($data['info']['pieces']));
|
|
$this->assertEquals(1, $data['info']['private']);
|
|
$this->assertEquals('APL', $data['info']['source']);
|
|
$this->assertStringEqualsFile(__DIR__ . '/data/test_1.torrent', $bencode->getEncode());
|
|
$this->assertEquals(104916260, $bencode->getSize());
|
|
$this->assertTrue($bencode->isPrivate());
|
|
$bencode->decodeString($bencode->getEncode());
|
|
$this->assertStringEqualsFile(__DIR__ . '/data/test_1.torrent', $bencode->getEncode());
|
|
$this->assertEquals('1f830103427029a88dd5fde85be74e622ee07951', $bencode->getInfoHash());
|
|
$this->assertEquals($bencode->getInfoHash(), unpack('H*', $bencode->getHexInfoHash())[1]);
|
|
$this->assertFalse($bencode->hasEncryptedFiles());
|
|
$file_list = [
|
|
'total_size' => 104916260,
|
|
'files' => [
|
|
[
|
|
'size' => 9584196,
|
|
'path' => '01 Death with Dignity.mp3'
|
|
],
|
|
[
|
|
'size' => 12310347,
|
|
'path' => '02 Should have known better.mp3'
|
|
],
|
|
[
|
|
'size' => 8871591,
|
|
'path' => '03 All of me wants all of you.mp3'
|
|
],
|
|
[
|
|
'size' => 7942661,
|
|
'path' => '04 Drawn to the Blood.mp3'
|
|
],
|
|
[
|
|
'size' => 5878964,
|
|
'path' => '05 Eugene.mp3'
|
|
],
|
|
[
|
|
'size' => 11175567,
|
|
'path' => '06 Fourth of July.mp3'
|
|
],
|
|
[
|
|
'size' => 11367829,
|
|
'path' => '07 The Only Thing.mp3'
|
|
],
|
|
[
|
|
'size' => 7789055,
|
|
'path' => '08 Carrie & Lowell.mp3'
|
|
],
|
|
[
|
|
'size' => 12197480,
|
|
'path' => '09 John My Beloved.mp3'
|
|
],
|
|
[
|
|
'size' => 6438044,
|
|
'path' => '10 No shade in the shadow of the cross.mp3'
|
|
],
|
|
[
|
|
'size' => 11360526,
|
|
'path' => '11 Blue Bucket of Gold.mp3'
|
|
]
|
|
]
|
|
];
|
|
$this->assertEquals($file_list, $bencode->getFileList());
|
|
$this->assertSame(1425699508, $bencode->getCreationDate());
|
|
}
|
|
|
|
public function testSetData(): void
|
|
{
|
|
$data = [
|
|
'encoding' => 'UTF8',
|
|
'info' => [
|
|
'name' => 'test',
|
|
'length' => 1213134,
|
|
'pieces' => 'fake pieces string'
|
|
]
|
|
];
|
|
|
|
$bencode = new BencodeTorrent();
|
|
$bencode->setData($data);
|
|
|
|
$data = $bencode->getData();
|
|
$this->assertEquals($data, $bencode->getData());
|
|
$this->assertEquals('test', $bencode->getName());
|
|
$this->assertFalse($bencode->isPrivate());
|
|
$this->assertEquals(1213134, $bencode->getSize());
|
|
$this->assertEquals(
|
|
[
|
|
'total_size' => 1213134,
|
|
'files' => [
|
|
[
|
|
'path' => 'test',
|
|
'size' => 1213134
|
|
]
|
|
]
|
|
],
|
|
$bencode->getFileList()
|
|
);
|
|
}
|
|
|
|
public function testEmptyDictionary(): void
|
|
{
|
|
$expected = [
|
|
'encoding' => 'UTF8',
|
|
'info' => [
|
|
'name' => 'test',
|
|
'length' => 1213134,
|
|
'pieces' => 'fake pieces string',
|
|
],
|
|
'test' => ''
|
|
];
|
|
$bencode = new BencodeTorrent();
|
|
$bencode->decodeString(
|
|
'd8:encoding4:UTF84:infod4:name4:test6:lengthi1213134e' .
|
|
'6:pieces18:fake pieces stringe4:test0:e'
|
|
);
|
|
$this->assertEquals($expected, $bencode->getData());
|
|
}
|
|
|
|
public function testClean(): void
|
|
{
|
|
$data = [
|
|
'encoding' => 'UTF8',
|
|
'info' => [
|
|
'file-duration' => '',
|
|
'file-media' => '',
|
|
'files' => [],
|
|
'name' => 'test',
|
|
'name.utf8' => 'test',
|
|
'name.utf-8' => 'test',
|
|
'length' => 12345,
|
|
'md5sum' => 12345,
|
|
'piece length' => 12345,
|
|
'pieces' => '',
|
|
'private' => 1,
|
|
'profiles' => '',
|
|
'sha1' => 1,
|
|
'source' => 'APL',
|
|
'unique' => 1,
|
|
'test' => 'delete me',
|
|
'x_cross_seed' => 1
|
|
],
|
|
'test' => 'delete me'
|
|
];
|
|
|
|
$bencode = new BencodeTorrent();
|
|
$bencode->setData($data);
|
|
$this->assertTrue($bencode->clean());
|
|
unset($data['test']);
|
|
unset($data['info']['test']);
|
|
$this->assertEquals($data, $bencode->getData());
|
|
}
|
|
|
|
public function testSetPrivate(): void
|
|
{
|
|
$data = [
|
|
'encoding' => 'UTF8',
|
|
'info' => [
|
|
'name' => 'test',
|
|
'length' => 1213134,
|
|
'pieces' => 'fake pieces string'
|
|
]
|
|
];
|
|
$bencode = new BencodeTorrent();
|
|
$bencode->setData($data);
|
|
$this->assertFalse($bencode->isPrivate());
|
|
$actual = $bencode->getData();
|
|
$this->assertNotContains('private', $actual['info']);
|
|
$this->assertTrue($bencode->makePrivate());
|
|
$this->assertTrue($bencode->isPrivate());
|
|
$actual = $bencode->getData();
|
|
$this->assertEquals(1, $actual['info']['private']);
|
|
}
|
|
|
|
public function testSetAlreadyPrivate(): void
|
|
{
|
|
$data = [
|
|
'encoding' => 'UTF8',
|
|
'info' => [
|
|
'name' => 'test',
|
|
'private' => 1
|
|
]
|
|
];
|
|
$bencode = new BencodeTorrent();
|
|
$bencode->setData($data);
|
|
$this->assertTrue($bencode->isPrivate());
|
|
$this->assertFalse($bencode->makePrivate());
|
|
}
|
|
|
|
public function testSetSource(): void
|
|
{
|
|
$data = [
|
|
'encoding' => 'UTF8',
|
|
'info' => [
|
|
'name' => 'test',
|
|
'private' => 1,
|
|
'unique' => 1,
|
|
'x_cross_seed' => 'true'
|
|
]
|
|
];
|
|
$bencode = new BencodeTorrent();
|
|
$bencode->setData($data);
|
|
$this->assertNull($bencode->getSource());
|
|
$this->assertTrue($bencode->setSource('APL'));
|
|
$actual = $bencode->getData();
|
|
$this->assertSame('APL', $bencode->getSource());
|
|
$this->assertFalse($bencode->setSource('APL'));
|
|
$this->assertNotContains('unique', $actual['info']);
|
|
$this->assertNotContains('x_cross_seed', $actual['info']);
|
|
}
|
|
|
|
public function testSetAlreadySourced(): void
|
|
{
|
|
$data = [
|
|
'encoding' => 'UTF8',
|
|
'info' => [
|
|
'name' => 'test',
|
|
'private' => 1,
|
|
'source' => 'APL',
|
|
'unique' => 1,
|
|
'x_cross_seed' => 'true'
|
|
]
|
|
];
|
|
|
|
$bencode = new BencodeTorrent();
|
|
$bencode->setData($data);
|
|
$this->assertFalse($bencode->setSource('APL'));
|
|
$this->assertEquals($data, $bencode->getData());
|
|
}
|
|
|
|
public function testSetDifferentSource(): void
|
|
{
|
|
$data = [
|
|
'encoding' => 'UTF8',
|
|
'info' => [
|
|
'name' => 'test',
|
|
'private' => 1,
|
|
'source' => 'RED',
|
|
'unique' => 1,
|
|
'x_cross_seed' => 'true'
|
|
]
|
|
];
|
|
$bencode = new BencodeTorrent();
|
|
$bencode->setData($data);
|
|
$this->assertTrue($bencode->setSource('APL'));
|
|
$actual = $bencode->getData();
|
|
$this->assertEquals('APL', $actual['info']['source']);
|
|
$this->assertNotContains('unique', $actual['info']);
|
|
$this->assertNotContains('x_cross_seed', $actual['info']);
|
|
}
|
|
|
|
public function testSetValue(): void
|
|
{
|
|
$data = [
|
|
'encoding' => 'UTF8',
|
|
'info' => [
|
|
'files' => [
|
|
0 => [
|
|
'length' => 1234,
|
|
'path' => ['01 Test.mp3'],
|
|
'path.utf-8' => ['01 Test??.mp3']
|
|
],
|
|
1 => [
|
|
'length' => 2345,
|
|
'path' => ['03 Test!!.mp3'],
|
|
'path.utf-8' => ['03 Test.mp3']
|
|
]
|
|
],
|
|
'name' => 'test',
|
|
'private' => 1
|
|
]
|
|
];
|
|
$bencode = new BencodeTorrent();
|
|
$bencode->setData($data);
|
|
$set = ['announce' => 'http://localhost:8080/announce',
|
|
'info.name' => 'test2',
|
|
'info.private' => 0,
|
|
'info.files.0.path.0' => '02 Test.mp3',
|
|
'comment' => 'http://localhost:8080/torrents.php?id=1'];
|
|
$bencode->setValue($set);
|
|
$expected = [
|
|
'announce' => 'http://localhost:8080/announce',
|
|
'comment' => 'http://localhost:8080/torrents.php?id=1',
|
|
'encoding' => 'UTF8',
|
|
'info' => [
|
|
'files' => [
|
|
0 => [
|
|
'length' => 1234,
|
|
'path' => ['02 Test.mp3'],
|
|
'path.utf-8' => ['01 Test??.mp3']
|
|
],
|
|
1 => [
|
|
'length' => 2345,
|
|
'path' => ['03 Test!!.mp3'],
|
|
'path.utf-8' => ['03 Test.mp3']
|
|
]
|
|
],
|
|
'name' => 'test2',
|
|
'private' => 0
|
|
]
|
|
];
|
|
$this->assertEquals($expected, $bencode->getData());
|
|
$this->assertEquals(
|
|
['.mp3 s1234s 01 Test??.mp3 ÷', '.mp3 s2345s 03 Test.mp3 ÷'],
|
|
$bencode->getGazelleFileList()
|
|
);
|
|
$this->assertTrue($bencode->hasFiles());
|
|
}
|
|
|
|
public function testGetUtf8Name(): void
|
|
{
|
|
$data = [
|
|
'encoding' => 'UTF8',
|
|
'info' => [
|
|
'length' => 12345,
|
|
'name' => 'test',
|
|
'name.utf-8' => 'test!!',
|
|
'private' => 1
|
|
]
|
|
];
|
|
$bencode = new BencodeTorrent();
|
|
$bencode->setData($data);
|
|
$this->assertEquals('test!!', $bencode->getName());
|
|
$this->assertEquals(12345, $bencode->getSize());
|
|
$this->assertEquals(
|
|
[
|
|
'total_size' => 12345,
|
|
'files' => [
|
|
[
|
|
'path' => 'test!!',
|
|
'size' => 12345
|
|
]
|
|
]
|
|
],
|
|
$bencode->getFileList()
|
|
);
|
|
$this->assertEquals(['. s12345s test!! ÷'], $bencode->getGazelleFileList());
|
|
}
|
|
|
|
public function testIso88591Name(): void
|
|
{
|
|
$data = [
|
|
'info' => [
|
|
'length' => 1234,
|
|
'name' => utf8_decode('(test.,!?)óÉ')
|
|
]
|
|
];
|
|
$bencode = new BencodeTorrent();
|
|
$bencode->setData($data);
|
|
$this->assertEquals(['.,!?)óÉ s1234s (test.,!?)óÉ ÷'], $bencode->getGazelleFileList());
|
|
$this->assertFalse($bencode->hasFiles());
|
|
}
|
|
|
|
public function testInvalidSet(): void
|
|
{
|
|
$data = ['encoding' => 'UTF8', 'announce' => 'http://localhost:8080/announce'];
|
|
$bencode = new BencodeTorrent();
|
|
$this->expectException(\RuntimeException::class);
|
|
$bencode->setData($data);
|
|
}
|
|
|
|
public function testInvalidSetValue(): void
|
|
{
|
|
$data = [
|
|
'encoding' => 'UTF8',
|
|
'info' => [
|
|
'name' => 'test',
|
|
'length' => 1213134,
|
|
'pieces' => 'fake pieces string'
|
|
]
|
|
];
|
|
|
|
$bencode = new BencodeTorrent();
|
|
$bencode->setData($data);
|
|
$this->expectException(\RuntimeException::class);
|
|
$bencode->setValue(['info' => []]);
|
|
}
|
|
|
|
public function testGetEncodeNoData(): void
|
|
{
|
|
$bencode = new BencodeTorrent();
|
|
$this->expectException(\RuntimeException::class);
|
|
$bencode->getEncode();
|
|
}
|
|
|
|
public function testEmptyPathPart(): void
|
|
{
|
|
$data = [
|
|
'encoding' => 'UTF8',
|
|
'info' => [
|
|
'files' => [
|
|
0 => [
|
|
'length' => 1234,
|
|
'path' => [
|
|
'',
|
|
'01 - test test',
|
|
]
|
|
]
|
|
],
|
|
'name' => 'test',
|
|
'length' => 1213134,
|
|
'pieces' => 'fake pieces string'
|
|
]
|
|
];
|
|
$bencode = new BencodeTorrent();
|
|
$bencode->setData($data);
|
|
$this->assertSame(
|
|
[
|
|
'total_size' => 1234,
|
|
'files' => [
|
|
0 => [
|
|
'path' => '/01 - test test',
|
|
'size' => 1234,
|
|
],
|
|
],
|
|
],
|
|
$bencode->getFileList()
|
|
);
|
|
}
|
|
|
|
public function testEmptyPath(): void
|
|
{
|
|
$data = [
|
|
'encoding' => 'UTF8',
|
|
'info' => [
|
|
'files' => [
|
|
0 => [
|
|
'length' => 1234,
|
|
'path' => [
|
|
'',
|
|
]
|
|
]
|
|
],
|
|
'name' => 'test',
|
|
'length' => 1213134,
|
|
'pieces' => 'fake pieces string'
|
|
]
|
|
];
|
|
$bencode = new BencodeTorrent();
|
|
$this->expectException(\RuntimeException::class);
|
|
$bencode->setData($data);
|
|
}
|
|
|
|
public function testValidateEmptyData(): void
|
|
{
|
|
$bencode = new BencodeTorrent();
|
|
$this->expectException(\TypeError::class);
|
|
$bencode->validate();
|
|
}
|
|
}
|