initial commit

This commit is contained in:
Milos Stojanovic
2019-06-13 18:52:40 +02:00
commit 261607e1d3
160 changed files with 41704 additions and 0 deletions

View File

@@ -0,0 +1,21 @@
<?php
/*
* This file is part of the FileGator package.
*
* (c) Milos Stojanovic <alcalbg@gmail.com>
*
* For the full copyright and license information, please view the LICENSE file
*/
namespace Tests;
use Filegator\Kernel\Response;
class FakeResponse extends Response
{
public function send()
{
// do nothing
}
}

View File

@@ -0,0 +1,21 @@
<?php
/*
* This file is part of the FileGator package.
*
* (c) Milos Stojanovic <alcalbg@gmail.com>
*
* For the full copyright and license information, please view the LICENSE file
*/
namespace Tests;
use Filegator\Kernel\StreamedResponse;
class FakeStreamedResponse extends StreamedResponse
{
public function send()
{
// do nothing
}
}

View File

@@ -0,0 +1,221 @@
<?php
/*
* This file is part of the FileGator package.
*
* (c) Milos Stojanovic <alcalbg@gmail.com>
*
* For the full copyright and license information, please view the LICENSE file
*/
namespace Tests\Feature;
use Tests\TestCase;
/**
* @internal
*/
class AdminTest extends TestCase
{
public function testOnlyAdminCanPerformUserActions()
{
$this->signOut();
$this->sendRequest('GET', '/listusers');
$this->assertStatus(404);
$this->sendRequest('POST', '/storeuser');
$this->assertStatus(404);
$this->sendRequest('POST', '/updateuser/test@example.com');
$this->assertStatus(404);
$this->sendRequest('POST', '/deleteuser/test@example.com');
$this->assertStatus(404);
}
public function testListUsers()
{
$this->signIn('admin@example.com', 'admin123');
$this->sendRequest('GET', '/listusers');
$this->assertOk();
$this->assertResponseJsonHas([
'data' => [
[
'role' => 'guest',
'permissions' => [],
'homedir' => '/',
'username' => 'guest',
'name' => 'Guest',
],
[
'role' => 'admin',
'permissions' => [],
'homedir' => '/',
'username' => 'admin@example.com',
'name' => 'Admin',
],
[
'role' => 'user',
'permissions' => [],
'homedir' => '/john',
'username' => 'john@example.com',
'name' => 'John Doe',
],
[
'role' => 'user',
'permissions' => [],
'homedir' => '/jane',
'username' => 'jane@example.com',
'name' => 'Jane Doe',
],
],
]);
}
public function testAddingNewUser()
{
$this->signIn('admin@example.com', 'admin123');
$this->sendRequest('POST', '/storeuser', [
'name' => 'Mike Test',
'username' => 'mike@example.com',
'role' => 'user',
'permissions' => [],
'password' => 'pass123',
'homedir' => '/john',
]);
$this->assertOk();
$this->assertResponseJsonHas([
'data' => [
'role' => 'user',
'permissions' => [],
'homedir' => '/john',
'username' => 'mike@example.com',
'name' => 'Mike Test',
],
]);
}
public function testAddingNewUserValidation()
{
$this->signIn('admin@example.com', 'admin123');
$this->sendRequest('POST', '/storeuser', [
'name' => '',
'username' => '',
'role' => 'user',
'permissions' => [],
'password' => 'pass123',
'homedir' => '',
]);
$this->assertStatus(422);
$this->sendRequest('POST', '/storeuser', [
'name' => 'Mike Test',
'username' => 'mike@example.com',
'role' => 'bear',
'permissions' => ['xxx'],
'password' => 'pass123',
'homedir' => '/john',
]);
$this->assertStatus(422);
}
public function testUpdatingUser()
{
$this->signIn('admin@example.com', 'admin123');
$this->sendRequest('POST', '/updateuser/john@example.com', [
'name' => 'Johnny Doe',
'username' => 'john2@example.com',
'role' => 'admin',
'permissions' => ['read', 'write'],
'homedir' => '/jane',
]);
$this->assertOk();
$this->assertResponseJsonHas([
'data' => [
'role' => 'admin',
'permissions' => ['read', 'write'],
'homedir' => '/jane',
'username' => 'john2@example.com',
'name' => 'Johnny Doe',
],
]);
}
public function testDeletingUser()
{
$this->signIn('admin@example.com', 'admin123');
$this->sendRequest('POST', '/deleteuser/john@example.com');
$this->assertOk();
}
public function testUpdatingNonExistingUser()
{
$this->signIn('admin@example.com', 'admin123');
$this->sendRequest('POST', '/updateuser/nonexisting@example.com');
$this->assertStatus(422);
}
public function testUpdatingUserValidation()
{
$this->signIn('admin@example.com', 'admin123');
$this->sendRequest('POST', '/updateuser/john@example.com', [
'name' => '',
'username' => '',
'homedir' => '',
]);
$this->assertStatus(422);
$this->sendRequest('POST', '/updateuser/john@example.com', [
'name' => 'something',
'username' => 'something',
'homedir' => '/',
'permissions' => ['xxx', 'write'],
]);
$this->assertStatus(422);
}
public function testDeletingNonExistingUser()
{
$this->signIn('admin@example.com', 'admin123');
$this->sendRequest('POST', '/deleteuser/nonexisting@example.com');
$this->assertStatus(422);
}
public function testAddingOrEditingUserWithUsernameThatIsAlreadyTaken()
{
$this->signIn('admin@example.com', 'admin123');
$this->sendRequest('POST', '/storeuser', [
'name' => 'Mike Test',
'username' => 'admin@example.com',
'role' => 'user',
'password' => '123',
'permissions' => [],
'homedir' => '/mike',
]);
$this->assertStatus(422);
$this->sendRequest('POST', '/updateuser/admin@example.com', [
'name' => 'Admin',
'username' => 'john@example.com',
'role' => 'admin',
'permissions' => [],
'homedir' => '/',
]);
$this->assertStatus(422);
}
}

View File

@@ -0,0 +1,74 @@
<?php
/*
* This file is part of the FileGator package.
*
* (c) Milos Stojanovic <alcalbg@gmail.com>
*
* For the full copyright and license information, please view the LICENSE file
*/
namespace Tests\Unit;
use Filegator\Kernel\Request;
use Filegator\Kernel\Response;
use Filegator\Services\Auth\AuthInterface;
use Filegator\Services\Session\Session;
use Filegator\Services\Session\SessionStorageInterface;
use Tests\TestCase;
/**
* @internal
*/
class AppTest extends TestCase
{
public function testAppWithoutSession()
{
$app = $this->bootFreshApp();
$request = $app->resolve(Request::class);
$response = $app->resolve(Response::class);
$session = $app->resolve(SessionStorageInterface::class);
$auth = $app->resolve(AuthInterface::class);
$this->assertNotNull($request);
$this->assertNotNull($response);
$this->assertNotNull($session);
$this->assertNull($auth->user());
}
public function testAppWithSession()
{
// first login request
$request1 = Request::create(
'?r=/login',
'POST',
[],
[],
[],
[
'CONTENT_TYPE' => 'application/json',
'HTTP_ACCEPT' => 'application/json',
],
'{"username":"admin@example.com","password":"admin123"}'
);
$config = $this->getMockConfig();
$app1 = $this->bootFreshApp($config, $request1, null, true);
$prev_session = $request1->getSession();
// another request with previous session
$request2 = Request::create(
'?r=/',
'GET',
);
$request2->setSession($prev_session);
$app2 = $this->bootFreshApp($config, $request2);
$auth = $app2->resolve(AuthInterface::class);
$this->assertNotNull($auth->user());
}
}

View File

@@ -0,0 +1,145 @@
<?php
/*
* This file is part of the FileGator package.
*
* (c) Milos Stojanovic <alcalbg@gmail.com>
*
* For the full copyright and license information, please view the LICENSE file
*/
namespace Tests\Feature;
use Filegator\Kernel\Request;
use Filegator\Kernel\Response;
use Tests\TestCase;
/**
* @internal
*/
class AuthTest extends TestCase
{
public function testSuccessfulLogin()
{
$ret = $this->sendRequest('POST', '/login', [
'username' => 'john@example.com',
'password' => 'john123',
]);
$this->assertOk();
}
public function testBadLogin()
{
$this->sendRequest('POST', '/login', [
'username' => 'fake',
'password' => 'fake',
]);
$this->assertUnprocessable();
}
public function testAlreadyLoggedIn()
{
$username = 'john@example.com';
$this->signIn($username, 'john123');
$this->sendRequest('POST', '/login', ['username' => $username, 'password' => 'john123']);
$this->assertStatus(404);
}
public function testGetUser()
{
$user = 'john@example.com';
$this->signIn($user, 'john123');
$this->sendRequest('GET', '/getuser');
$this->assertOk();
$this->assertResponseJsonHas([
'data' => [
'username' => $user,
'name' => 'John Doe',
'role' => 'user',
'homedir' => '/john',
],
]);
}
public function testGetAdmin()
{
$admin = 'admin@example.com';
$this->signIn($admin, 'admin123');
$this->sendRequest('GET', '/getuser');
$this->assertOk();
$this->assertResponseJsonHas([
'data' => [
'username' => $admin,
'name' => 'Admin',
'role' => 'admin',
'homedir' => '/',
],
]);
}
public function testReceiveGuestIfNoUserIsLoggedIn()
{
$this->sendRequest('GET', '/getuser');
$this->assertOk();
$this->assertResponseJsonHas([
'data' => [
'role' => 'guest',
],
]);
}
public function testLogout()
{
$this->signIn('john@example.com', 'john123');
$this->sendRequest('POST', '/logout');
$this->assertOk();
}
public function testResponseThrows404()
{
$request = Request::create(
'?r=/notfound',
'GET',
);
$app = $this->bootFreshApp(null, $request);
$response = $app->resolve(Response::class);
$this->assertEquals($response->getStatusCode(), 404);
}
public function testChangePassword()
{
$this->signIn('john@example.com', 'john123');
$this->sendRequest('POST', '/changepassword', [
'oldpassword' => 'john123',
'newpassword' => '',
]);
$this->assertStatus(422);
$this->signIn('john@example.com', 'john123');
$this->sendRequest('POST', '/changepassword', [
'oldpassword' => 'wrongpass',
'newpassword' => 'password123',
]);
$this->assertStatus(422);
$this->signIn('john@example.com', 'john123');
$this->sendRequest('POST', '/changepassword', [
'oldpassword' => 'john123',
'newpassword' => 'password123',
]);
$this->assertOk();
}
}

View File

@@ -0,0 +1,62 @@
<?php
/*
* This file is part of the FileGator package.
*
* (c) Milos Stojanovic <alcalbg@gmail.com>
*
* For the full copyright and license information, please view the LICENSE file
*/
namespace Tests\Feature;
use Tests\TestCase;
/**
* @internal
*/
class FeatureTest extends TestCase
{
public function testHome()
{
$this->sendRequest('GET', '/');
$this->assertOk();
}
public function testMethodNotAllowed()
{
$this->sendRequest('DELETE', '/');
$this->assertStatus(401);
}
public function testNotFoundPage()
{
$this->sendRequest('GET', '/fakeroute');
$this->assertStatus(404);
}
public function testUnprocessableRequest()
{
$this->sendRequest('POST', '/login', 'dddddd');
$this->assertUnprocessable();
}
public function testGetFrontendConfig()
{
$this->sendRequest('GET', '/getconfig');
$this->assertOk();
$this->assertResponseJsonHas([
'data' => [
'app_name' => 'FileGator',
'upload_max_size' => 2 * 1024 * 1024,
'upload_chunk_size' => 1 * 1024 * 1024,
'upload_simultaneous' => 3,
],
]);
}
}

View File

@@ -0,0 +1,574 @@
<?php
/*
* This file is part of the FileGator package.
*
* (c) Milos Stojanovic <alcalbg@gmail.com>
*
* For the full copyright and license information, please view the LICENSE file
*/
namespace Tests\Feature;
use Tests\TestCase;
/**
* @internal
*/
class FilesTest extends TestCase
{
protected $timestamp;
public function setUp(): void
{
$this->resetTempDir();
$this->timestamp = time();
}
public function tearDown(): void
{
$this->resetTempDir();
}
public function testGuestCannotListDirectories()
{
$this->signOut();
$this->sendRequest('POST', '/changedir', [
'to' => '/',
]);
$this->assertStatus(404);
$this->sendRequest('POST', '/getdir', [
'to' => '/',
]);
$this->assertStatus(404);
}
public function testUserCanChangeDir()
{
$username = 'john@example.com';
$this->signIn($username, 'john123');
mkdir(TEST_REPOSITORY.'/john');
mkdir(TEST_REPOSITORY.'/john/johnsub');
touch(TEST_REPOSITORY.'/john/john.txt', $this->timestamp);
$this->sendRequest('POST', '/changedir', [
'to' => '/',
]);
$this->assertOk();
$this->assertResponseJsonHas([
'data' => [
'files' => [
0 => [
'type' => 'dir',
'path' => '/johnsub',
'name' => 'johnsub',
],
1 => [
'type' => 'file',
'path' => '/john.txt',
'name' => 'john.txt',
'time' => $this->timestamp,
],
],
],
]);
}
public function testUserCanListHisHomeDir()
{
$username = 'john@example.com';
$this->signIn($username, 'john123');
mkdir(TEST_REPOSITORY.'/john');
mkdir(TEST_REPOSITORY.'/john/johnsub');
touch(TEST_REPOSITORY.'/john/john.txt', $this->timestamp);
$this->sendRequest('POST', '/getdir', [
'dir' => '/',
]);
$this->assertOk();
$this->assertResponseJsonHas([
'data' => [
'files' => [
0 => [
'type' => 'dir',
'path' => '/johnsub',
'name' => 'johnsub',
],
1 => [
'type' => 'file',
'path' => '/john.txt',
'name' => 'john.txt',
'time' => $this->timestamp,
],
],
],
]);
}
public function testDeleteItems()
{
$username = 'john@example.com';
$this->signIn($username, 'john123');
mkdir(TEST_REPOSITORY.'/john');
mkdir(TEST_REPOSITORY.'/john/johnsub');
touch(TEST_REPOSITORY.'/john/john.txt', $this->timestamp);
$items = [
0 => [
'type' => 'dir',
'path' => '/johnsub',
'name' => 'johnsub',
'time' => $this->timestamp,
],
1 => [
'type' => 'file',
'path' => '/john.txt',
'name' => 'john.txt',
'time' => $this->timestamp,
],
];
$this->sendRequest('POST', '/deleteitems', [
'items' => $items,
]);
$this->assertOk();
}
public function testDownloadFile()
{
$username = 'john@example.com';
$this->signIn($username, 'john123');
mkdir(TEST_REPOSITORY.'/john');
touch(TEST_REPOSITORY.'/john/john.txt', $this->timestamp);
$path_encoded = base64_encode('john.txt');
$this->sendRequest('GET', '/download/'.$path_encoded);
$this->assertOk();
}
public function testGuestCannotDownloadFilesWithoutDownloadPermissions()
{
touch(TEST_REPOSITORY.'/test.txt', $this->timestamp);
$path_encoded = base64_encode('test.txt');
$this->sendRequest('GET', '/download/'.$path_encoded);
$this->assertStatus(404);
}
public function testDownloadFileOnlyWithPermissions()
{
// jane does not have download permissions
$username = 'jane@example.com';
$this->signIn($username, 'jane123');
mkdir(TEST_REPOSITORY.'/jane');
touch(TEST_REPOSITORY.'/jane/jane.txt', $this->timestamp);
$path_encoded = base64_encode('jane.txt');
$this->sendRequest('GET', '/download/'.$path_encoded);
$this->assertStatus(404);
}
public function testDownloadMissingFileThrowsRedirect()
{
$username = 'john@example.com';
$this->signIn($username, 'john123');
$path_encoded = base64_encode('missing.txt');
$this->sendRequest('GET', '/download/'.$path_encoded);
$this->assertStatus(302);
}
public function testRenameJohnsFile()
{
$username = 'john@example.com';
$this->signIn($username, 'john123');
mkdir(TEST_REPOSITORY.'/john');
touch(TEST_REPOSITORY.'/john/john.txt', $this->timestamp);
$this->sendRequest('POST', '/renameitem', [
'from' => '/john.txt',
'to' => '/john2.txt',
]);
$this->assertOk();
$this->assertFileExists(TEST_REPOSITORY.'/john/john2.txt');
$this->assertFileNotExists(TEST_REPOSITORY.'/john/john.txt');
}
public function testRenameMissingfileThrowsException()
{
$username = 'john@example.com';
$this->signIn($username, 'john123');
$this->expectException(\Exception::class);
$this->sendRequest('POST', '/renameitem', [
'from' => 'missing.txt',
'to' => 'john2.txt',
]);
}
public function testDeleteMissingItemsThrowsException()
{
$username = 'john@example.com';
$this->signIn($username, 'john123');
$items = [
0 => [
'type' => 'file',
'path' => '/missing',
'name' => 'missing',
'time' => $this->timestamp,
],
];
$this->expectException(\Exception::class);
$this->sendRequest('POST', '/deleteitems', [
'items' => $items,
]);
}
public function testCreateNewDirAndFileInside()
{
$username = 'john@example.com';
$this->signIn($username, 'john123');
mkdir(TEST_REPOSITORY.'/john');
$this->sendRequest('POST', '/createnew', [
'type' => 'dir',
'name' => 'maximus',
]);
$this->assertOk();
$this->sendRequest('POST', '/changedir', [
'to' => '/maximus/',
]);
$this->assertOk();
$this->sendRequest('POST', '/createnew', [
'type' => 'file',
'name' => 'samplefile.txt',
]);
$this->assertOk();
$this->assertDirectoryExists(TEST_REPOSITORY.'/john/maximus');
$this->assertFileExists(TEST_REPOSITORY.'/john/maximus/samplefile.txt');
}
public function testCopyAdminFiles()
{
$username = 'admin@example.com';
$this->signIn($username, 'admin123');
touch(TEST_REPOSITORY.'/a.txt', $this->timestamp);
touch(TEST_REPOSITORY.'/c.zip', $this->timestamp);
mkdir(TEST_REPOSITORY.'/sub');
mkdir(TEST_REPOSITORY.'/sub/sub1');
mkdir(TEST_REPOSITORY.'/john');
mkdir(TEST_REPOSITORY.'/john/johnsub');
$items = [
0 => [
'type' => 'file',
'path' => '/a.txt',
'name' => 'a.txt',
'time' => $this->timestamp,
],
1 => [
'type' => 'file',
'path' => '/c.zip',
'name' => 'c.zip',
'time' => $this->timestamp,
],
2 => [
'type' => 'dir',
'path' => '/sub',
'name' => 'sub',
'time' => $this->timestamp,
],
];
$this->sendRequest('POST', '/copyitems', [
'items' => $items,
'destination' => '/john/johnsub/',
]);
$this->assertOk();
$this->assertFileExists(TEST_REPOSITORY.'/john/johnsub/a.txt');
$this->assertFileExists(TEST_REPOSITORY.'/john/johnsub/c.zip');
$this->assertDirectoryExists(TEST_REPOSITORY.'/john/johnsub/sub/');
$this->assertDirectoryExists(TEST_REPOSITORY.'/john/johnsub/sub/sub1');
}
public function testCopyInvalidFilesThrowsException()
{
$username = 'admin@example.com';
$this->signIn($username, 'admin123');
$items = [
0 => [
'type' => 'file',
'path' => '/missin.txt',
'name' => 'missina.txt',
'time' => $this->timestamp,
],
];
$this->expectException(\Exception::class);
$this->sendRequest('POST', '/copyitems', [
'items' => $items,
'destination' => '/john/johnsub/',
]);
}
public function testMoveFiles()
{
$username = 'admin@example.com';
$this->signIn($username, 'admin123');
mkdir(TEST_REPOSITORY.'/john');
touch(TEST_REPOSITORY.'/a.txt', $this->timestamp);
touch(TEST_REPOSITORY.'/b.txt', $this->timestamp);
$items = [
0 => [
'type' => 'file',
'path' => '/a.txt',
'name' => 'a.txt',
'time' => $this->timestamp,
],
1 => [
'type' => 'file',
'path' => '/b.txt',
'name' => 'b.txt',
'time' => $this->timestamp,
],
];
$this->sendRequest('POST', '/moveitems', [
'items' => $items,
'destination' => '/john',
]);
$this->assertOk();
$this->assertFileExists(TEST_REPOSITORY.'/john/a.txt');
$this->assertFileExists(TEST_REPOSITORY.'/john/b.txt');
$this->assertFileNotExists(TEST_REPOSITORY.'/a.txt');
$this->assertFileNotExists(TEST_REPOSITORY.'/b.txt');
}
public function testMoveDirsWithContent()
{
$username = 'admin@example.com';
$this->signIn($username, 'admin123');
mkdir(TEST_REPOSITORY.'/sub');
mkdir(TEST_REPOSITORY.'/sub/sub1');
touch(TEST_REPOSITORY.'/sub/sub1/f.txt', $this->timestamp);
mkdir(TEST_REPOSITORY.'/jane');
touch(TEST_REPOSITORY.'/jane/cookie.txt', $this->timestamp);
mkdir(TEST_REPOSITORY.'/john');
$items = [
0 => [
'type' => 'dir',
'path' => '/sub',
'name' => 'sub',
'time' => $this->timestamp,
],
1 => [
'type' => 'dir',
'path' => '/jane',
'name' => 'jane',
'time' => $this->timestamp,
],
];
$this->sendRequest('POST', '/moveitems', [
'items' => $items,
'destination' => '/john',
]);
$this->assertOk();
$this->assertDirectoryNotExists(TEST_REPOSITORY.'/jane');
$this->assertDirectoryNotExists(TEST_REPOSITORY.'/sub');
$this->assertFileNotExists(TEST_REPOSITORY.'/sub/sub1/f.txt');
$this->assertDirectoryExists(TEST_REPOSITORY.'/john/jane');
$this->assertDirectoryExists(TEST_REPOSITORY.'/john/sub');
$this->assertDirectoryExists(TEST_REPOSITORY.'/john/sub/sub1');
$this->assertFileExists(TEST_REPOSITORY.'/john/sub/sub1/f.txt');
$this->assertFileExists(TEST_REPOSITORY.'/john/jane/cookie.txt');
}
public function testZipFilesOnly()
{
$username = 'admin@example.com';
$this->signIn($username, 'admin123');
touch(TEST_REPOSITORY.'/a.txt', $this->timestamp);
touch(TEST_REPOSITORY.'/b.txt', $this->timestamp);
mkdir(TEST_REPOSITORY.'/john');
$items = [
0 => [
'type' => 'file',
'path' => '/a.txt',
'name' => 'a.txt',
'time' => $this->timestamp,
],
1 => [
'type' => 'file',
'path' => '/b.txt',
'name' => 'b.txt',
'time' => $this->timestamp,
],
];
$this->sendRequest('POST', '/zipitems', [
'name' => 'compressed.zip',
'items' => $items,
'destination' => '/john',
]);
$this->assertOk();
$this->assertFileExists(TEST_REPOSITORY.'/a.txt');
$this->assertFileExists(TEST_REPOSITORY.'/b.txt');
$this->assertFileExists(TEST_REPOSITORY.'/john/compressed.zip');
}
public function testZipFilesAndDirectories()
{
$username = 'admin@example.com';
$this->signIn($username, 'admin123');
touch(TEST_REPOSITORY.'/a.txt', $this->timestamp);
touch(TEST_REPOSITORY.'/b.txt', $this->timestamp);
mkdir(TEST_REPOSITORY.'/sub');
mkdir(TEST_REPOSITORY.'/jane');
$items = [
0 => [
'type' => 'file',
'path' => '/a.txt',
'name' => 'a.txt',
'time' => $this->timestamp,
],
1 => [
'type' => 'file',
'path' => '/b.txt',
'name' => 'b.txt',
'time' => $this->timestamp,
],
2 => [
'type' => 'dir',
'path' => '/sub',
'name' => 'sub',
'time' => $this->timestamp,
],
];
$this->sendRequest('POST', '/zipitems', [
'name' => 'compressed2.zip',
'items' => $items,
'destination' => '/jane',
]);
$this->assertOk();
$this->assertFileExists(TEST_REPOSITORY.'/a.txt');
$this->assertFileExists(TEST_REPOSITORY.'/b.txt');
$this->assertDirectoryExists(TEST_REPOSITORY.'/sub');
$this->assertFileExists(TEST_REPOSITORY.'/jane/compressed2.zip');
}
public function testUnzipArchive()
{
$username = 'admin@example.com';
$this->signIn($username, 'admin123');
copy(TEST_ARCHIVE, TEST_REPOSITORY.'/c.zip');
mkdir(TEST_REPOSITORY.'/jane');
$this->sendRequest('POST', '/unzipitem', [
'item' => '/c.zip',
'destination' => '/jane',
]);
$this->assertOk();
$this->assertFileExists(TEST_REPOSITORY.'/jane/one.txt');
$this->assertFileExists(TEST_REPOSITORY.'/jane/two.txt');
$this->assertDirectoryExists(TEST_REPOSITORY.'/jane/onetwo');
$this->assertFileExists(TEST_REPOSITORY.'/jane/onetwo/three.txt');
}
public function testDownloadMultipleItems()
{
$username = 'john@example.com';
$this->signIn($username, 'john123');
mkdir(TEST_REPOSITORY.'/john');
touch(TEST_REPOSITORY.'/john/john.txt', $this->timestamp);
mkdir(TEST_REPOSITORY.'/john/johnsub');
touch(TEST_REPOSITORY.'/john/johnsub/sub.txt', $this->timestamp);
mkdir(TEST_REPOSITORY.'/john/johnsub/sub2');
$items = [
0 => [
'type' => 'dir',
'path' => '/johnsub',
'name' => 'johnsub',
'time' => $this->timestamp,
],
1 => [
'type' => 'file',
'path' => '/john.txt',
'name' => 'john.txt',
'time' => $this->timestamp,
],
];
$this->sendRequest('POST', '/batchdownload', [
'items' => $items,
]);
$this->assertOk();
$res = json_decode($this->response->getContent());
$uniqid = $res->data->uniqid;
$this->sendRequest('GET', '/batchdownload', [
'uniqid' => $uniqid,
]);
$this->assertOk();
}
}

View File

@@ -0,0 +1,303 @@
<?php
/*
* This file is part of the FileGator package.
*
* (c) Milos Stojanovic <alcalbg@gmail.com>
*
* For the full copyright and license information, please view the LICENSE file
*/
namespace Tests\Feature;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Tests\TestCase;
/**
* @internal
*/
class UploadTest extends TestCase
{
public function setUp(): void
{
$this->resetTempDir();
parent::setUp();
}
public function testSimpleFileUpload()
{
$this->signIn('john@example.com', 'john123');
// create 5Kb dummy file
$fp = fopen(TEST_FILE, 'w');
fseek($fp, 0.5 * 1024 * 1024 - 1, SEEK_CUR);
fwrite($fp, 'a');
fclose($fp);
$files = ['file' => new UploadedFile(TEST_FILE, 'sample.txt', 'text/plain', null, true)];
$data = [
'resumableChunkNumber' => 1,
'resumableChunkSize' => 1048576,
'resumableCurrentChunkSize' => 0.5 * 1024 * 1024,
'resumableTotalChunks' => 1,
'resumableTotalSize' => 0.5 * 1024 * 1024,
'resumableType' => 'text/plain',
'resumableIdentifier' => 'CHUNKS-SIMPLE-TEST',
'resumableFilename' => 'sample.txt',
'resumableRelativePath' => '/',
];
$this->sendRequest('GET', '/upload', $data, $files);
$this->assertStatus(204);
$this->sendRequest('POST', '/upload', $data, $files);
$this->assertOk();
$this->sendRequest('POST', '/getdir', [
'dir' => '/',
]);
$this->assertOk();
$this->assertResponseJsonHas([
'data' => [
'files' => [
0 => [
'type' => 'file',
'path' => '/sample.txt',
'name' => 'sample.txt',
],
],
],
]);
}
public function testFileUploadWithTwoChunks()
{
$this->signIn('john@example.com', 'john123');
// create 1MB dummy file part 1
$fp = fopen(TEST_FILE, 'w');
fseek($fp, 1 * 1024 * 1024 - 1, SEEK_CUR);
fwrite($fp, 'a');
fclose($fp);
$files = ['file' => new UploadedFile(TEST_FILE, 'sample.txt', 'text/plain', null, true)];
$data = [
'resumableChunkNumber' => 1,
'resumableChunkSize' => 1048576,
'resumableCurrentChunkSize' => 1 * 1024 * 1024,
'resumableTotalChunks' => 2,
'resumableTotalSize' => 1.5 * 1024 * 1024,
'resumableType' => 'text/plain',
'resumableIdentifier' => 'CHUNKS-MULTIPART-TEST',
'resumableFilename' => 'sample.txt',
'resumableRelativePath' => '/',
];
// part does not exists
$this->sendRequest('GET', '/upload', $data, $files);
$this->assertStatus(204);
$this->sendRequest('POST', '/upload', $data, $files);
$this->assertOk();
// this part should already exists, no need to upload again
$this->sendRequest('GET', '/upload', $data, $files);
$this->assertOk();
// create 512Kb dummy file part 2
$fp = fopen(TEST_FILE, 'w');
fseek($fp, 0.5 * 1024 * 1024 - 1, SEEK_CUR);
fwrite($fp, 'a');
fclose($fp);
$files = ['file' => new UploadedFile(TEST_FILE, 'sample.txt', 'text/plain', null, true)];
$data = [
'resumableChunkNumber' => 2,
'resumableChunkSize' => 1048576,
'resumableCurrentChunkSize' => 0.5 * 1024 * 1024,
'resumableTotalChunks' => 2,
'resumableTotalSize' => 1.5 * 1024 * 1024,
'resumableType' => 'text/plain',
'resumableIdentifier' => 'CHUNKS-MULTIPART-TEST',
'resumableFilename' => 'sample.txt',
'resumableRelativePath' => '/',
];
// part does not exists
$this->sendRequest('GET', '/upload', $data, $files);
$this->assertStatus(204);
$this->sendRequest('POST', '/upload', $data, $files);
$this->assertOk();
}
public function testUploadFileBiggerThanAllowed()
{
$this->signIn('john@example.com', 'john123');
// create 3MB dummy file
$fp = fopen(TEST_FILE, 'w');
fseek($fp, 3 * 1024 * 1024 - 1, SEEK_CUR);
fwrite($fp, 'a');
fclose($fp);
$files = ['file' => new UploadedFile(TEST_FILE, 'sample.txt', 'text/plain', null, true)];
$data = [
'resumableChunkNumber' => 1,
'resumableChunkSize' => 1048576,
'resumableCurrentChunkSize' => 1 * 1024 * 1024,
'resumableTotalChunks' => 1,
'resumableTotalSize' => 1 * 1024 * 1024,
'resumableType' => 'text/plain',
'resumableIdentifier' => 'CHUNKS-FAILED-TEST',
'resumableFilename' => 'sample.txt',
'resumableRelativePath' => '/',
];
$this->sendRequest('POST', '/upload', $data, $files);
$this->assertStatus(422);
}
public function testUploadFileBiggerThanAllowedUsingChunks()
{
$this->signIn('john@example.com', 'john123');
// create 1MB dummy file
$fp = fopen(TEST_FILE, 'w');
fseek($fp, 1 * 1024 * 1024 - 1, SEEK_CUR);
fwrite($fp, 'a');
fclose($fp);
$files = ['file' => new UploadedFile(TEST_FILE, 'sample.txt', 'text/plain', null, true)];
$data = [
'resumableChunkNumber' => 1,
'resumableChunkSize' => 1048576,
'resumableCurrentChunkSize' => 1 * 1024 * 1024,
'resumableTotalChunks' => 3,
'resumableTotalSize' => 2 * 1024 * 1024,
'resumableType' => 'text/plain',
'resumableIdentifier' => 'CHUNKS-FAILED2-TEST',
'resumableFilename' => 'sample.txt',
'resumableRelativePath' => '/',
];
$this->sendRequest('POST', '/upload', $data, $files);
$this->assertOk();
// create 512Kb dummy file
$fp = fopen(TEST_FILE, 'w');
fseek($fp, .5 * 1024 * 1024 - 1, SEEK_CUR);
fwrite($fp, 'a');
fclose($fp);
$files = ['file' => new UploadedFile(TEST_FILE, 'sample.txt', 'text/plain', null, true)];
$data = [
'resumableChunkNumber' => 2,
'resumableChunkSize' => 1048576,
'resumableCurrentChunkSize' => 0.5 * 1024 * 1024,
'resumableTotalChunks' => 3,
'resumableTotalSize' => 2 * 1024 * 1024,
'resumableType' => 'text/plain',
'resumableIdentifier' => 'CHUNKS-FAILED2-TEST',
'resumableFilename' => 'sample.txt',
'resumableRelativePath' => '/',
];
$this->sendRequest('POST', '/upload', $data, $files);
$this->assertOk();
// create 1MB dummy file
$fp = fopen(TEST_FILE, 'w');
fseek($fp, 1 * 1024 * 1024 - 1, SEEK_CUR);
fwrite($fp, 'a');
fclose($fp);
$files = ['file' => new UploadedFile(TEST_FILE, 'sample.txt', 'text/plain', null, true)];
$data = [
'resumableChunkNumber' => 3,
'resumableChunkSize' => 1048576,
'resumableCurrentChunkSize' => 1 * 1024 * 1024,
'resumableTotalChunks' => 3,
'resumableTotalSize' => 2 * 1024 * 1024,
'resumableType' => 'text/plain',
'resumableIdentifier' => 'CHUNKS-FAILED2-TEST',
'resumableFilename' => 'sample.txt',
'resumableRelativePath' => '/',
];
$this->sendRequest('POST', '/upload', $data, $files);
$this->assertStatus(422);
// create 1MB dummy file
$fp = fopen(TEST_FILE, 'w');
fseek($fp, 1 * 1024 * 1024 - 1, SEEK_CUR);
fwrite($fp, 'a');
fclose($fp);
$files = ['file' => new UploadedFile(TEST_FILE, 'sample.txt', 'text/plain', null, true)];
$data = [
'resumableChunkNumber' => 3,
'resumableChunkSize' => 1048576,
'resumableCurrentChunkSize' => 1 * 1024 * 1024,
'resumableTotalChunks' => 3,
'resumableTotalSize' => 2 * 1024 * 1024,
'resumableType' => 'text/plain',
'resumableIdentifier' => 'CHUNKS-FAILED2-TEST',
'resumableFilename' => 'sample.txt',
'resumableRelativePath' => '/',
];
$this->sendRequest('POST', '/upload', $data, $files);
$this->assertStatus(422);
}
public function testFileUploadWithBadName()
{
$this->signIn('john@example.com', 'john123');
$files = ['file' => new UploadedFile(TEST_FILE, 'sample.txt', 'text/plain', null, true)];
$data = [
'resumableChunkNumber' => 1,
'resumableChunkSize' => 1048576,
'resumableCurrentChunkSize' => 0.5 * 1024 * 1024,
'resumableTotalChunks' => 1,
'resumableTotalSize' => 0.5 * 1024 * 1024,
'resumableType' => 'text/plain',
'resumableIdentifier' => 'CHUNKS-SIMPLE-TEST',
'resumableFilename' => "../\\s\"u<:>pe////rm?*|an\\.t\txt../;",
'resumableRelativePath' => '/',
];
$this->sendRequest('POST', '/upload', $data, $files);
$this->assertOk();
$this->sendRequest('POST', '/getdir', [
'dir' => '/',
]);
$this->assertResponseJsonHas([
'data' => [
'files' => [
0 => [
'type' => 'file',
'path' => '/..--s-u---pe----rm---an-.t-xt..--',
'name' => '..--s-u---pe----rm---an-.t-xt..--',
],
],
],
]);
}
}

View File

@@ -0,0 +1,72 @@
<?php
/*
* This file is part of the FileGator package.
*
* (c) Milos Stojanovic <alcalbg@gmail.com>
*
* For the full copyright and license information, please view the LICENSE file
*/
namespace Tests;
use Filegator\Services\Auth\Adapters\JsonFile;
use Filegator\Services\Auth\AuthInterface;
use Filegator\Services\Auth\User;
use Filegator\Services\Service;
class MockUsers extends JsonFile implements Service, AuthInterface
{
private $users_array = [];
public function init(array $config = [])
{
$this->addMockUsers();
}
protected function getUsers(): array
{
return $this->users_array;
}
protected function saveUsers(array $users)
{
return $this->users_array = $users;
}
private function addMockUsers()
{
$guest = new User();
$guest->setRole('guest');
$guest->setHomedir('/');
$guest->setUsername('guest');
$guest->setName('Guest');
$guest->setPermissions([]);
$admin = new User();
$admin->setRole('admin');
$admin->setHomedir('/');
$admin->setUsername('admin@example.com');
$admin->setName('Admin');
$admin->setPermissions(['read', 'write', 'upload', 'download', 'batchdownload', 'zip']);
$john = new User();
$john->setRole('user');
$john->setHomedir('/john');
$john->setUsername('john@example.com');
$john->setName('John Doe');
$john->setPermissions(['read', 'write', 'upload', 'download', 'batchdownload']);
$jane = new User();
$jane->setRole('user');
$jane->setHomedir('/jane');
$jane->setUsername('jane@example.com');
$jane->setName('Jane Doe');
$jane->setPermissions(['read', 'write']);
$this->add($guest, '');
$this->add($admin, 'admin123');
$this->add($john, 'john123');
$this->add($jane, 'jane123');
}
}

136
tests/backend/TestCase.php Normal file
View File

@@ -0,0 +1,136 @@
<?php
/*
* This file is part of the FileGator package.
*
* (c) Milos Stojanovic <alcalbg@gmail.com>
*
* For the full copyright and license information, please view the LICENSE file
*/
namespace Tests;
use Filegator\App;
use Filegator\Config\Config;
use Filegator\Container\Container;
use Filegator\Kernel\Request;
use Filegator\Kernel\Response;
use Filegator\Services\Session\Session;
use PHPUnit\Framework\TestCase as BaseTestCase;
use Symfony\Component\HttpFoundation\Session\Storage\MockFileSessionStorage;
define('APP_ENV', 'test');
define('TEST_DIR', __DIR__.'/tmp');
define('TEST_REPOSITORY', TEST_DIR.'/repository');
define('TEST_ARCHIVE', TEST_DIR.'/testarchive.zip');
define('TEST_FILE', TEST_DIR.'/sample.txt');
define('TEST_TMP_PATH', TEST_DIR.'/temp/');
/**
* @internal
* @coversNothing
*/
class TestCase extends BaseTestCase
{
use TestResponse;
public $response;
public $previous_session = false;
protected $auth = false;
public function bootFreshApp($config = null, $request = null, $response = null, $mock_users = false)
{
$config = $config ?: $this->getMockConfig();
$request = $request ?: new Request();
return new App($config, $request, new FakeResponse(), new FakeStreamedResponse(), new Container());
}
public function sendRequest($method, $uri, $data = null, $files = [])
{
$fakeRequest = Request::create(
'?r='.$uri,
$method,
[],
[],
$files,
[
'CONTENT_TYPE' => 'application/json',
'HTTP_ACCEPT' => 'application/json',
],
json_encode($data)
);
if ($this->previous_session) {
$fakeRequest->setSession($this->previous_session);
} else {
$sessionStorage = new MockFileSessionStorage();
$fakeRequest->setSession(new Session($sessionStorage));
}
$app = $this->bootFreshApp(null, $fakeRequest, null, true);
$this->response = $app->resolve(Response::class);
return $app;
}
public function signIn($username, $password)
{
$this->signOut();
$app = $this->sendRequest('POST', '/login', [
'username' => $username,
'password' => $password,
]);
$request = $app->resolve(Request::class);
$this->previous_session = $request->getSession();
}
public function signOut()
{
$this->previous_session = false;
}
public function getMockConfig()
{
$config = require __DIR__.'/configuration.php';
return new Config($config);
}
public function delTree($dir)
{
if (! is_dir($dir)) {
return;
}
$files = array_diff(scandir($dir), ['.', '..']);
foreach ($files as $file) {
(is_dir("{$dir}/{$file}")) ? $this->delTree("{$dir}/{$file}") : unlink("{$dir}/{$file}");
}
return rmdir($dir);
}
public function resetTempDir()
{
$this->delTree(TEST_TMP_PATH);
$this->delTree(TEST_REPOSITORY);
mkdir(TEST_TMP_PATH);
mkdir(TEST_REPOSITORY);
}
public function invokeMethod(&$object, $methodName, array $parameters = [])
{
$reflection = new \ReflectionClass(get_class($object));
$method = $reflection->getMethod($methodName);
$method->setAccessible(true);
return $method->invokeArgs($object, $parameters);
}
}

View File

@@ -0,0 +1,159 @@
<?php
/*
* This file is part of the FileGator package.
*
* (c) Milos Stojanovic <alcalbg@gmail.com>
*
* For the full copyright and license information, please view the LICENSE file
*/
namespace Tests;
use PHPUnit\Framework\Constraint\ArraySubset;
use PHPUnit\Util\InvalidArgumentHelper;
trait TestResponse
{
public function assertResponseJsonHas(array $data, $strict = false)
{
self::assertArraySubset(
$data,
$this->decodeResponseJson(),
$strict,
$this->assertJsonMessage($data)
);
return $this;
}
public function assertResponseJsonFragment(array $data)
{
$actual = json_encode((array) $this->decodeResponseJson());
foreach ($data as $key => $value) {
$expected = $this->jsonSearchStrings($key, $value);
$this->assertTrue(
$this->str_contains($actual, $expected),
'Unable to find JSON fragment: '.PHP_EOL.PHP_EOL.
'['.json_encode([$key => $value]).']'.PHP_EOL.PHP_EOL.
'within'.PHP_EOL.PHP_EOL.
"[{$actual}]."
);
}
return $this;
}
public function decodeResponseJson($key = null)
{
$decodedResponse = json_decode($this->response->getContent(), true);
if (is_null($decodedResponse) || $decodedResponse === false) {
$this->fail('Invalid JSON was returned from the route.');
}
return $decodedResponse;
}
public static function assertArraySubset($subset, $array, bool $checkForObjectIdentity = false, string $message = ''): void
{
if (! (\is_array($subset) || $subset instanceof ArrayAccess)) {
throw InvalidArgumentHelper::factory(
1,
'array or ArrayAccess'
);
}
if (! (\is_array($array) || $array instanceof ArrayAccess)) {
throw InvalidArgumentHelper::factory(
2,
'array or ArrayAccess'
);
}
$constraint = new ArraySubset($subset, $checkForObjectIdentity);
static::assertThat($array, $constraint, $message);
}
public function getStatusCode()
{
return $this->response->getStatusCode();
}
public function assertStatus($status)
{
$this->assertEquals(
$status,
$this->getStatusCode()
);
return $this;
}
public function assertOk()
{
$this->assertTrue(
$this->isOk(),
'Response status code ['.$this->getStatusCode().'] does not match expected 200 status code.'
);
return $this;
}
public function assertUnprocessable()
{
$this->assertTrue(
$this->isUnprocessable(),
'Response status code ['.$this->getStatusCode().'] does not match expected 422 status code.'
);
return $this;
}
public function isOk(): bool
{
return 200 === $this->getStatusCode();
}
public function isUnprocessable(): bool
{
return 422 === $this->getStatusCode();
}
public function str_contains($haystack, $needles)
{
foreach ((array) $needles as $needle) {
if ($needle !== '' && mb_strpos($haystack, $needle) !== false) {
return true;
}
}
return false;
}
protected function assertJsonMessage(array $data)
{
$expected = json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
$actual = json_encode($this->decodeResponseJson(), JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
return 'Unable to find JSON: '.PHP_EOL.PHP_EOL.
"[{$expected}]".PHP_EOL.PHP_EOL.
'within response JSON:'.PHP_EOL.PHP_EOL.
"[{$actual}].".PHP_EOL.PHP_EOL;
}
protected function jsonSearchStrings($key, $value)
{
$needle = substr(json_encode([$key => $value]), 1, -1);
return [
$needle.']',
$needle.'}',
$needle.',',
];
}
}

View File

@@ -0,0 +1,132 @@
<?php
/*
* This file is part of the FileGator package.
*
* (c) Milos Stojanovic <alcalbg@gmail.com>
*
* For the full copyright and license information, please view the LICENSE file
*/
namespace Tests\Unit;
use Filegator\Services\Archiver\Adapters\ZipArchiver;
use Filegator\Services\Storage\Filesystem;
use Filegator\Services\Tmpfs\Adapters\Tmpfs;
use Tests\TestCase;
/**
* @internal
*/
class ArchiverTest extends TestCase
{
protected $archiver;
public function setUp(): void
{
$tmpfs = new Tmpfs();
$tmpfs->init([
'path' => TEST_TMP_PATH,
'gc_probability_perc' => 10,
'gc_older_than' => 60 * 60 * 24 * 2, // 2 days
]);
$this->archiver = new ZipArchiver($tmpfs);
parent::setUp();
}
public function testCreatingArchive()
{
$storage = new Filesystem();
$storage->init([
'separator' => '/',
'filesystem_adapter' => 'nulladapter',
'adapters' => [
'nulladapter' => function () {
return new \League\Flysystem\Adapter\NullAdapter();
},
],
]);
$uniqid = $this->archiver->createArchive($storage);
$this->assertNotNull($uniqid);
$this->assertFileExists(TEST_TMP_PATH.$uniqid);
}
public function testAddingDirectoryWithFilesAndSubdir()
{
$storage = new Filesystem();
$storage->init([
'separator' => '/',
'filesystem_adapter' => 'memoryadapter',
'adapters' => [
'memoryadapter' => function () {
return new \League\Flysystem\Memory\MemoryAdapter();
},
],
]);
$storage->createDir('/', 'test');
$storage->createDir('/test', 'sub');
$storage->createFile('/test', 'file1.txt');
$storage->createFile('/test', 'file2.txt');
$name = $this->archiver->createArchive($storage);
$this->archiver->addDirectoryFromStorage('/test');
$this->archiver->closeArchive();
$this->assertGreaterThan(0, filesize(TEST_TMP_PATH.$name));
}
public function testUploadingArchiveToStorage()
{
$storage = new Filesystem();
$storage->init([
'separator' => '/',
'filesystem_adapter' => 'memoryadapter',
'adapters' => [
'memoryadapter' => function () {
return new \League\Flysystem\Memory\MemoryAdapter();
},
],
]);
$storage->createDir('/', 'test');
$storage->createDir('/test', 'sub');
$storage->createFile('/test', 'file1.txt');
$storage->createFile('/test', 'file2.txt');
$name = $this->archiver->createArchive($storage);
$this->archiver->addDirectoryFromStorage('/test');
$this->archiver->storeArchive('/destination', 'myarchive.zip');
$this->assertFileNotExists(TEST_TMP_PATH.$name);
}
public function testUncompressingArchiveFromStorage()
{
$storage = new Filesystem();
$storage->init([
'separator' => '/',
'filesystem_adapter' => 'memoryadapter',
'adapters' => [
'memoryadapter' => function () {
return new \League\Flysystem\Memory\MemoryAdapter();
},
],
]);
$stream = fopen(TEST_ARCHIVE, 'r');
$storage->store('/', 'testarchive.zip', $stream);
fclose($stream);
$storage->createDir('/', 'result');
$this->archiver->uncompress('/testarchive.zip', '/result', $storage);
$this->assertStringContainsString('testarchive', (json_encode($storage->getDirectoryCollection('/'))));
$this->assertStringContainsString('onetwo', (json_encode($storage->getDirectoryCollection('/result'))));
}
}

View File

@@ -0,0 +1,226 @@
<?php
/*
* This file is part of the FileGator package.
*
* (c) Milos Stojanovic <alcalbg@gmail.com>
*
* For the full copyright and license information, please view the LICENSE file
*/
namespace Tests\Unit\Auth;
use Filegator\Services\Auth\User;
use Tests\TestCase;
abstract class AuthTest extends TestCase
{
public $auth;
public function setUp(): void
{
$this->setAuth();
parent::setUp();
}
abstract public function setAuth();
public function addAdmin($password = '123456')
{
$admin = new User();
$admin->setRole('admin');
$admin->setHomedir('/');
$admin->setUsername('admin@example.com');
$admin->setName('Admin');
return $this->auth->add($admin, $password);
}
public function addMike($password = '98747')
{
$mike = new User();
$mike->setRole('user');
$mike->setHomedir('/');
$mike->setUsername('mike@example.com');
$mike->setName('Mike');
return $this->auth->add($mike, $password);
}
public function addGuest()
{
$guest = new User();
$guest->setRole('guest');
$guest->setHomedir('/');
$guest->setUsername('guest');
$guest->setName('Guest');
return $this->auth->add($guest, '');
}
public function testWeCanFindAUser()
{
$admin = $this->addAdmin();
$user = $this->auth->find('admin@example.com');
$this->assertTrue($user->isAdmin());
}
public function testWeCanAddAUser()
{
$mike = $this->addMike();
$user = $this->auth->find('mike@example.com');
$this->assertEquals($user, $mike);
}
public function testWeCanUpdateExistingUser()
{
$this->addAdmin();
$user = $this->auth->find('admin@example.com');
$this->assertNotNull($user);
$user->setName('Jonny B');
$user->setHomeDir('/jonnyshome');
$user->setUsername('jonny@example.com');
$user->setRole('user');
$updated_user = $this->auth->update('admin@example.com', $user);
$this->assertEquals($updated_user->getName(), 'Jonny B');
$this->assertEquals($updated_user->getHomeDir(), '/jonnyshome');
$this->assertEquals($updated_user->getUsername(), 'jonny@example.com');
$this->assertTrue($updated_user->isUser());
}
public function testWeCanAuthenticateUser()
{
$admin = $this->addAdmin('test123');
$auth_attempt1 = $this->auth->authenticate('admin@example.com', 'test123');
$auth_user = $this->auth->user();
$this->assertEquals($auth_user->getUsername(), $admin->getUsername());
$this->assertFalse($this->auth->authenticate('test123@example.com', 'xxxxxx'));
}
public function testWeCanForgetUser()
{
$admin = $this->addAdmin('test123');
$this->auth->authenticate('admin@example.com', 'test123');
$auth_user = $this->auth->user();
$this->assertEquals($auth_user->getUsername(), $admin->getUsername());
$this->auth->forget();
$auth_user = $this->auth->user();
$this->assertEquals($auth_user, null);
}
public function testWeCanUpdateUsersPassword()
{
$admin = $this->addAdmin('test123');
$this->auth->update('admin@example.com', $admin, 'newpassword');
$this->assertFalse($this->auth->authenticate('test123@example.com', 'test123'));
$auth_attempt1 = $this->auth->authenticate('admin@example.com', 'newpassword');
$auth_user = $this->auth->user();
$this->assertEquals($auth_user->getUsername(), $admin->getUsername());
}
public function testWeCanDeleteUser()
{
$admin = $this->addAdmin();
$find = $this->auth->find('admin@example.com');
$this->assertNotNull($find);
$this->auth->delete($admin);
$find = $this->auth->find('admin@example.com');
$this->assertNull($find);
}
public function testWeCannotUpdateNonExistingUser()
{
$this->expectException(\Exception::class);
$user = new User();
$user->setRole('user');
$user->setHomedir('/');
$user->setUsername('tim@example.com');
$user->setName('Tim');
$this->auth->update('somebody@example.com', $user);
}
public function testWeCannotDeleteNonExistingUser()
{
$user = new User();
$user->setRole('user');
$user->setHomedir('/');
$user->setUsername('tim@example.com');
$user->setName('Tim');
$this->expectException(\Exception::class);
$this->auth->delete($user);
}
public function testWeCannotAddUserWithTheSameUsername()
{
$this->addAdmin();
$second_admin = new User();
$second_admin->setRole('user');
$second_admin->setHomedir('/');
$second_admin->setUsername('admin@example.com');
$second_admin->setName('Admin2');
$this->expectException(\Exception::class);
$updated_user = $this->auth->add($second_admin, 'pass444');
}
public function testWeCannotEditUserAndSetUsernameThatIsAlreadyTaken()
{
$this->addMike();
$this->addAdmin();
$user = $this->auth->find('mike@example.com');
$this->assertNotNull($user);
$user->setName('Jonny B');
$user->setHomeDir('/jonnyshome');
$user->setUsername('admin@example.com');
$user->setRole('user');
$this->expectException(\Exception::class);
$updated_user = $this->auth->update('mike@example.com', $user);
}
public function testNoGuestException()
{
$this->expectException(\Exception::class);
$guest = $this->auth->getGuest();
}
public function testGetGuest()
{
$this->addGuest();
$guest = $this->auth->getGuest();
$this->assertNotNull($guest);
}
public function testGetAllUsers()
{
$this->addAdmin();
$this->addMike();
$this->assertEquals($this->auth->allUsers()->length(), 2);
}
}

View File

@@ -0,0 +1,58 @@
<?php
/*
* This file is part of the FileGator package.
*
* (c) Milos Stojanovic <alcalbg@gmail.com>
*
* For the full copyright and license information, please view the LICENSE file
*/
namespace Tests\Unit\Auth;
use Filegator\Kernel\Request;
use Filegator\Services\Auth\Adapters\Database;
use Filegator\Services\Session\Adapters\SessionStorage;
/**
* @internal
*/
class DatabaseAuthTest extends AuthTest
{
protected $conn;
public function setAuth()
{
$session = new SessionStorage(new Request());
$session->init([
'session_handler' => 'mockfilesession',
'available' => [
'mockfilesession' => function () {
return new \Symfony\Component\HttpFoundation\Session\Storage\MockFileSessionStorage();
},
],
]);
$this->auth = new Database($session);
$this->auth->init([
'driver' => 'pdo',
'dsn' => 'sqlite::memory:',
'database' => 'users',
]);
$this->conn = $this->auth->getConnection();
$this->conn->query('DROP TABLE IF EXISTS [users]');
$this->conn->query('CREATE TABLE [users] (
[id] INTEGER PRIMARY KEY NOT NULL,
[username] VARCHAR(255) NOT NULL,
[name] VARCHAR(255) NOT NULL,
[role] VARCHAR(20) NOT NULL,
[permissions] VARCHAR(100) NOT NULL,
[homedir] VARCHAR(1000) NOT NULL,
[password] VARCHAR(255) NOT NULL
)');
$ret = $this->conn->fetch('SELECT * FROM users WHERE username = ?', 'admin');
}
}

View File

@@ -0,0 +1,50 @@
<?php
/*
* This file is part of the FileGator package.
*
* (c) Milos Stojanovic <alcalbg@gmail.com>
*
* For the full copyright and license information, please view the LICENSE file
*/
namespace Tests\Unit\Auth;
use Filegator\Kernel\Request;
use Filegator\Services\Auth\Adapters\JsonFile;
use Filegator\Services\Session\Adapters\SessionStorage;
/**
* @internal
*/
class JsonFileTest extends AuthTest
{
private $mock_file = TEST_DIR.'/mockusers.json';
public function tearDown(): void
{
@unlink($this->mock_file);
@unlink($this->mock_file.'.blank');
}
public function setAuth()
{
@unlink($this->mock_file);
@touch($this->mock_file.'.blank');
$session = new SessionStorage(new Request());
$session->init([
'session_handler' => 'mockfilesession',
'available' => [
'mockfilesession' => function () {
return new \Symfony\Component\HttpFoundation\Session\Storage\MockFileSessionStorage();
},
],
]);
$this->auth = new JsonFile($session);
$this->auth->init([
'file' => $this->mock_file,
]);
}
}

View File

@@ -0,0 +1,115 @@
<?php
/*
* This file is part of the FileGator package.
*
* (c) Milos Stojanovic <alcalbg@gmail.com>
*
* For the full copyright and license information, please view the LICENSE file
*/
namespace Tests\Unit;
use Filegator\Services\Auth\User;
use Filegator\Services\Auth\UsersCollection;
use Filegator\Services\Storage\DirectoryCollection;
use Filegator\Utils\Collection;
use Tests\TestCase;
/**
* @internal
*/
class CollectionTest extends TestCase
{
public function testAddToCollection()
{
$mock = $this->getMockForTrait(Collection::class);
$mock->add('one');
$mock->add('two');
$this->assertEquals($mock->length(), 2);
}
public function testDeleteFromCollection()
{
$mock = $this->getMockForTrait(Collection::class);
$mock->add('one');
$mock->delete('one');
$this->assertEquals($mock->length(), 0);
}
public function testSort()
{
$mock = $this->getMockForTrait(Collection::class);
$mock->add(['val' => 'b']);
$mock->add(['val' => 'a']);
$mock->add(['val' => 'c']);
$this->assertEquals($mock->all()[0]['val'], 'b');
$mock->sortByValue('val');
$this->assertEquals($mock->all()[0]['val'], 'a');
$mock->sortByValue('val', true);
$this->assertEquals($mock->all()[0]['val'], 'c');
}
public function testUsersCollection()
{
$mock = new UsersCollection();
$user1 = new User();
$user2 = new User();
$user3 = new User();
$mock->addUser($user1);
$mock->addUser($user2);
$mock->addUser($user3);
$this->assertEquals($mock->length(), 3);
}
public function testUserSerialization()
{
$mock = new UsersCollection();
$mock->add(['val' => 'b']);
$mock->add(['val' => 'a']);
$mock->add(['val' => 'c']);
$json = json_encode($mock);
$this->assertEquals($json, '[{"val":"b"},{"val":"a"},{"val":"c"}]');
}
public function testDirectoryCollection()
{
$dir = new DirectoryCollection('/sub1/sub2');
$dir->addFile('back', '/sub1', '..', 0, 1558942228);
$dir->addFile('file', '/sub1/sub2/test.txt', 'test.txt', 30000, 1558942228);
$dir->addFile('file', '/sub1/sub2/test2.txt', 'test.txt', 30000, 1558942228);
$dir->addFile('dir', '/sub1/sub2/sub3', 'sub3', 0, 1558942228);
$json = json_encode($dir);
$this->assertEquals($json, '{"location":"\/sub1\/sub2","files":[{"type":"back","path":"\/sub1","name":"..","size":0,"time":1558942228},{"type":"dir","path":"\/sub1\/sub2\/sub3","name":"sub3","size":0,"time":1558942228},{"type":"file","path":"\/sub1\/sub2\/test.txt","name":"test.txt","size":30000,"time":1558942228},{"type":"file","path":"\/sub1\/sub2\/test2.txt","name":"test.txt","size":30000,"time":1558942228}]}');
$this->expectException(\Exception::class);
$dir->addFile('badType', 'aaa', 'aa', 0, 1558942228);
}
public function testUserCollection()
{
$user = new UsersCollection();
$user->addUser(new User());
$user->addUser(new User());
$json = json_encode($user);
$this->assertEquals($json, '[{"role":"guest","permissions":[],"homedir":"","username":"","name":""},{"role":"guest","permissions":[],"homedir":"","username":"","name":""}]');
}
}

View File

@@ -0,0 +1,45 @@
<?php
/*
* This file is part of the FileGator package.
*
* (c) Milos Stojanovic <alcalbg@gmail.com>
*
* For the full copyright and license information, please view the LICENSE file
*/
namespace Tests\Unit;
use Filegator\Config\Config;
use Tests\TestCase;
/**
* @internal
*/
class ConfigTest extends TestCase
{
public function testGettingAnItemFromConfigUsingDotNotation()
{
$sample = [
'test' => 'something',
'test2' => [
'deep' => 123,
],
'test3' => [
'sub' => [
'subsub' => 2,
],
],
];
$config = new Config($sample);
$this->assertEquals($config->get(), $sample);
$this->assertEquals($config->get('test'), 'something');
$this->assertEquals($config->get('test2.deep'), 123);
$this->assertEquals($config->get('test3.sub.subsub'), 2);
$this->assertEquals($config->get('not-found'), null);
$this->assertEquals($config->get('not-found', 'default'), 'default');
$this->assertEquals($config->get('not.found', 'default'), 'default');
}
}

View File

@@ -0,0 +1,747 @@
<?php
/*
* This file is part of the FileGator package.
*
* (c) Milos Stojanovic <alcalbg@gmail.com>
*
* For the full copyright and license information, please view the LICENSE file
*/
namespace Tests\Unit;
use Filegator\Services\Storage\Filesystem;
use Tests\TestCase;
/**
* @internal
*/
class FilesystemTest extends TestCase
{
protected $storage;
protected $timestamp;
protected $separator = '/';
public function setUp(): void
{
$this->resetTempDir();
$this->timestamp = time();
$this->storage = new Filesystem();
$this->storage->init([
'separator' => '/',
'filesystem_adapter' => 'localfilesystem',
'adapters' => [
'localfilesystem' => function () {
return new \League\Flysystem\Adapter\Local(
TEST_REPOSITORY
);
},
],
]);
}
public function tearDown(): void
{
$this->resetTempDir();
}
public function testGetDirectyoryFileCount()
{
$this->storage->createFile('/', '1.txt');
$this->storage->createFile('/', '2.txt');
$this->storage->createFile('/', '3.txt');
$this->storage->createFile('/', '4.txt');
$this->storage->createFile('/', '5.txt');
$this->storage->createDir('/', 'tmp');
$ret = $this->storage->getDirectoryCollection('/');
$ret_array = json_decode(json_encode($ret), true);
$this->assertCount(6, $ret_array['files']);
}
public function testGetSubDirectyoryFileCount()
{
$this->storage->createDir('/', 'sub');
$this->storage->createFile('/sub', '1.txt');
$this->storage->createFile('/sub', '2.txt');
$this->storage->createFile('/sub', '3.txt');
$this->storage->createFile('/sub', '4.txt');
$this->storage->createDir('/sub', 'deep');
$this->storage->createFile('/sub/deep', '1.txt');
$ret = $this->storage->getDirectoryCollection('/sub');
$ret_array = json_decode(json_encode($ret), true);
// back + 4 files + 1 deep dir
$this->assertCount(6, $ret_array['files']);
$ret = $this->storage->getDirectoryCollection('/sub/deep');
$ret_array = json_decode(json_encode($ret), true);
// back + 1 file
$this->assertCount(2, $ret_array['files']);
}
public function testInvalidDirReturnsBackLinkOnly()
{
$ret = $this->storage->getDirectoryCollection('/etc');
$this->assertJsonStringEqualsJsonString(json_encode($ret), json_encode([
'location' => '/etc',
'files' => [
0 => [
'type' => 'back',
'path' => '/',
'name' => '..',
'size' => 0,
'time' => 0,
],
],
]));
}
public function testListSubDirContents()
{
$this->storage->createDir('/', 'john');
$this->storage->createDir('/john', 'johnsub');
$this->storage->createFile('/john/johnsub', 'john2.txt');
$ret = $this->storage->getDirectoryCollection('/john/johnsub');
$ret->resetTimestamps();
$this->assertJsonStringEqualsJsonString(json_encode($ret), json_encode([
'location' => '/john/johnsub',
'files' => [
0 => [
'type' => 'back',
'path' => '/john',
'name' => '..',
'size' => 0,
'time' => 0,
],
1 => [
'type' => 'file',
'path' => '/john/johnsub/john2.txt',
'name' => 'john2.txt',
'size' => 0,
'time' => 0,
],
],
]));
}
public function testHomeDirContentsUsingPathPrefix()
{
$this->storage->setPathPrefix('/john');
$this->storage->createDir('/', 'johnsub');
$this->storage->createFile('/', 'john.txt');
$ret = $this->storage->getDirectoryCollection('/');
$ret->resetTimestamps(-1);
$this->assertJsonStringEqualsJsonString(json_encode($ret), json_encode([
'location' => '/',
'files' => [
0 => [
'type' => 'dir',
'path' => '/johnsub',
'name' => 'johnsub',
'size' => 0,
'time' => -1,
],
1 => [
'type' => 'file',
'path' => '/john.txt',
'name' => 'john.txt',
'size' => 0,
'time' => -1,
],
],
]));
}
public function testSubDirContentsUsingPathPrefix()
{
$this->storage->setPathPrefix('/john');
$this->storage->createDir('/', 'johnsub');
$this->storage->createFile('/johnsub', 'john2.txt');
$ret = $this->storage->getDirectoryCollection('/johnsub');
$ret->resetTimestamps();
$this->assertJsonStringEqualsJsonString(json_encode($ret), json_encode([
'location' => '/johnsub',
'files' => [
0 => [
'type' => 'back',
'path' => '/',
'name' => '..',
'size' => 0,
'time' => 0,
],
1 => [
'type' => 'file',
'path' => '/johnsub/john2.txt',
'name' => 'john2.txt',
'size' => 0,
'time' => 0,
],
],
]));
}
public function testStoringFileToRoot()
{
// create dummy file
file_put_contents(TEST_FILE, 'lorem ipsum');
$resource = fopen(TEST_FILE, 'r');
$ret = $this->storage->store('/', 'loremfile.txt', $resource);
fclose($resource);
$this->assertTrue($ret);
$this->assertFileExists(TEST_REPOSITORY.'/loremfile.txt');
}
public function testStoringFileToRootSubFolder()
{
// create dummy file
file_put_contents(TEST_FILE, 'lorem ipsum');
$resource = fopen(TEST_FILE, 'r');
$ret = $this->storage->store('/sub/sub1', 'loremfile.txt', $resource);
fclose($resource);
$this->assertTrue($ret);
$this->assertFileExists(TEST_REPOSITORY.'/sub/sub1/loremfile.txt');
$this->assertFileNotExists(TEST_REPOSITORY.'/loremfile.txt');
}
public function testUpcountingFilenameOrDirname()
{
$this->assertEquals('test (1).txt', $this->invokeMethod($this->storage, 'upcountName', ['test.txt']));
$this->assertEquals('test (2).txt', $this->invokeMethod($this->storage, 'upcountName', ['test (1).txt']));
$this->assertEquals('test (100).txt', $this->invokeMethod($this->storage, 'upcountName', ['test (99).txt']));
$this->assertEquals('test (1)', $this->invokeMethod($this->storage, 'upcountName', ['test']));
$this->assertEquals('test (9) (2) (1)', $this->invokeMethod($this->storage, 'upcountName', ['test (9) (2)']));
$this->assertEquals('test (2) (3) (4).txt', $this->invokeMethod($this->storage, 'upcountName', ['test (2) (3) (3).txt']));
$this->assertEquals('1 (1)', $this->invokeMethod($this->storage, 'upcountName', ['1']));
$this->assertEquals('test (1).txt (1).zip', $this->invokeMethod($this->storage, 'upcountName', ['test (1).txt.zip']));
$this->assertEquals('test(1) (1)', $this->invokeMethod($this->storage, 'upcountName', ['test(1)']));
}
public function testStoringFileWithTheSameNameUpcountsSecondFilename()
{
// create dummy file
file_put_contents(TEST_FILE, 'lorem ipsum');
$resource = fopen(TEST_FILE, 'r');
$this->storage->store('/', 'singletone.txt', $resource);
fclose($resource);
// create another dummy file witht the same name but different content
file_put_contents(TEST_FILE, 'croissant');
$resource = fopen(TEST_FILE, 'r');
$this->storage->store('/', 'singletone.txt', $resource);
fclose($resource);
// first file is not overwritten
$ret = $this->storage->readStream('singletone.txt');
$this->assertEquals(stream_get_contents($ret['stream']), 'lorem ipsum');
// second file is also here but with upcounted name
$ret = $this->storage->readStream('singletone (1).txt');
$this->assertEquals(stream_get_contents($ret['stream']), 'croissant');
}
public function testCreatingFileWithTheSameNameUpcountsFilenameRecursively()
{
$this->storage->createFile('/', 'test.txt');
$this->storage->createFile('/', 'test (1).txt');
$resource = fopen(TEST_FILE, 'r');
$this->storage->store('/', 'test.txt', $resource);
fclose($resource);
$this->assertTrue($this->storage->fileExists('/test.txt'));
$this->assertTrue($this->storage->fileExists('/test (1).txt'));
$this->assertTrue($this->storage->fileExists('/test (2).txt')); // created with (2)
}
public function testCreatingDirectoryWithTheSameNameAsNonEmptyDirUpcountsDestinationDir()
{
$this->storage->createDir('/', 'test');
$this->storage->createFile('/test', 'a.txt');
// this dir
$this->storage->createDir('/', 'test');
$this->assertDirectoryExists(TEST_REPOSITORY.'/test');
$this->assertDirectoryExists(TEST_REPOSITORY.'/test (1)'); // goes here
}
public function testCreatingDirectoryWithTheSameNameAsNonEmptyDirUpcountsDestinationDirRecursively()
{
$this->storage->createDir('/', 'test');
$this->storage->createFile('/test', 'a.txt');
$this->storage->createDir('/', 'test (1)');
$this->storage->createFile('/test (1)', 'b.txt');
// this dir
$this->storage->createDir('/', 'test');
$this->assertDirectoryExists(TEST_REPOSITORY.'/test');
$this->assertDirectoryExists(TEST_REPOSITORY.'/test (1)');
$this->assertDirectoryExists(TEST_REPOSITORY.'/test (1) (1)'); // goes here
}
public function testMovingFileWithTheSameNameUpcountsSecondFilename()
{
$this->storage->createFile('/', 'test.txt');
$this->storage->createFile('/sub', 'test.txt');
// move second file over the first one
$this->storage->move('/sub/test.txt', '/test.txt');
$this->assertTrue($this->storage->fileExists('/test.txt'));
$this->assertTrue($this->storage->fileExists('/test (1).txt'));
}
public function testMovingFileWithTheSameNameUpcountsSecondFilenameUntilTheNameIsUnique()
{
$this->storage->createFile('/', 'test.txt');
$this->storage->createFile('/', 'test (1).txt');
$this->storage->createFile('/', 'test (2).txt');
$this->storage->createFile('/sub', 'test.txt');
// move second file over the first one
$this->storage->move('/sub/test.txt', '/test.txt');
$this->assertTrue($this->storage->fileExists('/test.txt'));
$this->assertTrue($this->storage->fileExists('/test (1).txt'));
$this->assertTrue($this->storage->fileExists('/test (2).txt'));
$this->assertTrue($this->storage->fileExists('/test (3).txt')); // file is moved here
}
public function testCopyingFileWithTheSameNameUpcountsSecondFilename()
{
$this->storage->createFile('/', 'test.txt');
$this->storage->createFile('/', 'test (1).txt');
$this->storage->createFile('/', 'test (2).txt');
$this->storage->createFile('/sub', 'test.txt');
// move second file over the first one
$this->storage->copyFile('/sub/test.txt', '/');
$this->assertTrue($this->storage->fileExists('/test.txt'));
$this->assertTrue($this->storage->fileExists('/test (1).txt'));
$this->assertTrue($this->storage->fileExists('/test (2).txt'));
$this->assertTrue($this->storage->fileExists('/test (3).txt')); // file is copied here
}
public function testGetPathPrefix()
{
$this->storage->setPathPrefix('/john/');
$this->assertEquals($this->storage->getPathPrefix(), '/john/');
$this->storage->setPathPrefix('/john');
$this->assertEquals($this->storage->getPathPrefix(), '/john/');
$this->storage->setPathPrefix('john/');
$this->assertEquals($this->storage->getPathPrefix(), '/john/');
$this->storage->setPathPrefix('john');
$this->assertEquals($this->storage->getPathPrefix(), '/john/');
}
public function testApplyPathPrefix()
{
$this->storage->setPathPrefix('/john/');
$this->assertEquals('/john/test', $this->invokeMethod($this->storage, 'applyPathPrefix', ['test']));
$this->assertEquals('/john/test/', $this->invokeMethod($this->storage, 'applyPathPrefix', ['test/']));
$this->assertEquals('/john/test/', $this->invokeMethod($this->storage, 'applyPathPrefix', ['/test/']));
$this->assertEquals('/john/test', $this->invokeMethod($this->storage, 'applyPathPrefix', ['/test']));
$this->assertEquals('/john/test.txt', $this->invokeMethod($this->storage, 'applyPathPrefix', ['test.txt']));
$this->assertEquals('/john/test.txt/', $this->invokeMethod($this->storage, 'applyPathPrefix', ['test.txt/']));
}
public function testStripPathPrefix()
{
$this->storage->setPathPrefix('/john/');
$this->assertEquals('/', $this->invokeMethod($this->storage, 'stripPathPrefix', ['/john/']));
$this->assertEquals('/test/', $this->invokeMethod($this->storage, 'stripPathPrefix', ['/john/test/']));
$this->assertEquals('/test', $this->invokeMethod($this->storage, 'stripPathPrefix', ['/john/test']));
$this->assertEquals('/doe/test', $this->invokeMethod($this->storage, 'stripPathPrefix', ['/john/doe/test']));
$this->assertEquals('/doe/test.txt', $this->invokeMethod($this->storage, 'stripPathPrefix', ['john/doe/test.txt']));
$this->assertEquals('/john', $this->invokeMethod($this->storage, 'stripPathPrefix', ['/john']));
$this->assertEquals('/', $this->invokeMethod($this->storage, 'stripPathPrefix', ['/']));
}
public function testAddSeparators()
{
$this->assertEquals('/', $this->invokeMethod($this->storage, 'addSeparators', ['']));
$this->assertEquals('/ /', $this->invokeMethod($this->storage, 'addSeparators', [' ']));
$this->assertEquals('/', $this->invokeMethod($this->storage, 'addSeparators', ['/']));
$this->assertEquals('/', $this->invokeMethod($this->storage, 'addSeparators', ['//']));
$this->assertEquals('/', $this->invokeMethod($this->storage, 'addSeparators', ['////']));
$this->assertEquals('/b/', $this->invokeMethod($this->storage, 'addSeparators', ['b']));
$this->assertEquals('/b/', $this->invokeMethod($this->storage, 'addSeparators', ['/b']));
$this->assertEquals('/b/', $this->invokeMethod($this->storage, 'addSeparators', ['/b/']));
$this->assertEquals('/b/', $this->invokeMethod($this->storage, 'addSeparators', ['/b//']));
$this->assertEquals('/b/', $this->invokeMethod($this->storage, 'addSeparators', ['//b//']));
$this->assertEquals('/a/b/', $this->invokeMethod($this->storage, 'addSeparators', ['a/b']));
$this->assertEquals('/a/b/', $this->invokeMethod($this->storage, 'addSeparators', ['a/b/']));
$this->assertEquals('/a/b/', $this->invokeMethod($this->storage, 'addSeparators', ['/a/b/']));
$this->assertEquals('/a b/', $this->invokeMethod($this->storage, 'addSeparators', ['a b']));
$this->assertEquals('/a b/c/', $this->invokeMethod($this->storage, 'addSeparators', ['a b/c']));
}
public function testJoinPaths()
{
$this->assertEquals('/1/2', $this->invokeMethod($this->storage, 'joinPaths', ['1', '2']));
$this->assertEquals('/1/2', $this->invokeMethod($this->storage, 'joinPaths', ['/1', '/2']));
$this->assertEquals('/1/2/', $this->invokeMethod($this->storage, 'joinPaths', ['1/', '2/']));
$this->assertEquals('/1/2', $this->invokeMethod($this->storage, 'joinPaths', ['1/', '/2']));
$this->assertEquals('/1/2/', $this->invokeMethod($this->storage, 'joinPaths', ['/1', '2/']));
$this->assertEquals('/1/2/', $this->invokeMethod($this->storage, 'joinPaths', ['/1/', '/2/']));
}
public function testGetBaseName()
{
$this->assertEquals('test.txt', $this->invokeMethod($this->storage, 'getBaseName', ['test.txt']));
$this->assertEquals('test.txt', $this->invokeMethod($this->storage, 'getBaseName', ['/test.txt']));
$this->assertEquals('test.txt', $this->invokeMethod($this->storage, 'getBaseName', ['/mike/test.txt']));
$this->assertEquals('b', $this->invokeMethod($this->storage, 'getBaseName', ['/a/b']));
$this->assertEquals('b', $this->invokeMethod($this->storage, 'getBaseName', ['/a/b/']));
$this->assertEquals('b', $this->invokeMethod($this->storage, 'getBaseName', ['a/b']));
$this->assertEquals('/', $this->invokeMethod($this->storage, 'getBaseName', ['']));
$this->assertEquals('/', $this->invokeMethod($this->storage, 'getBaseName', ['/']));
$this->assertEquals('/', $this->invokeMethod($this->storage, 'getBaseName', ['/////']));
}
public function testGetParent()
{
$this->assertEquals('/', $this->invokeMethod($this->storage, 'getParent', ['']));
$this->assertEquals('/', $this->invokeMethod($this->storage, 'getParent', [' ']));
$this->assertEquals('/', $this->invokeMethod($this->storage, 'getParent', ['/']));
$this->assertEquals('/', $this->invokeMethod($this->storage, 'getParent', ['////']));
$this->assertEquals('/parent', $this->invokeMethod($this->storage, 'getParent', ['/parent/child/']));
$this->assertEquals('/1/2/3/4', $this->invokeMethod($this->storage, 'getParent', ['/1/2/3/4/5/']));
$this->assertEquals('/1/2', $this->invokeMethod($this->storage, 'getParent', ['1/2/3']));
$this->assertEquals('/1/2', $this->invokeMethod($this->storage, 'getParent', ['1/2/3/']));
$this->assertEquals('/1/2', $this->invokeMethod($this->storage, 'getParent', ['/1/2/3/']));
}
public function testDeleteFiles()
{
$this->storage->createFile('/', 'sample22.txt');
$this->assertFileExists(TEST_REPOSITORY.'/sample22.txt');
$this->storage->deleteFile('sample22.txt');
$this->assertFileNotExists(TEST_REPOSITORY.'/sample22.txt');
}
public function testCreateAndDeleteDirectory()
{
$this->storage->createDir('/', 'sample22');
$this->storage->createDir('/sample22/subsample', 'sample22');
$this->assertDirectoryExists(TEST_REPOSITORY.'/sample22');
$this->assertDirectoryExists(TEST_REPOSITORY.'/sample22/subsample');
$this->storage->deleteDir('sample22');
$this->assertDirectoryNotExists(TEST_REPOSITORY.'/sample22');
$this->assertDirectoryNotExists(TEST_REPOSITORY.'/sample22/subsample');
}
public function testReadFileStream()
{
$this->storage->createFile('/', 'a.txt');
$ret = $this->storage->readStream('a.txt');
$this->assertEquals($ret['filename'], 'a.txt');
$this->assertTrue(is_resource($ret['stream']));
}
public function testReadFileStreamMissingFileThrowsException()
{
$this->expectException(\Exception::class);
$this->storage->readStream('missing');
}
public function testCannotStreamDirectory()
{
$this->storage->createDir('/', 'sub');
$this->expectException(\Exception::class);
$this->storage->readStream('sub');
}
public function testDirCheck()
{
$this->storage->createDir('/', 'sub');
$this->storage->createDir('/', 'empty');
$this->storage->createFile('/sub', 'd.txt');
$this->storage->createDir('/sub', 'sub1');
$this->storage->createFile('/sub/sub1', 'f.txt');
$this->storage->createDir('/sub', 'empty');
$this->storage->createDir('/', 'john');
$this->storage->createFile('/', 'a.txt');
$this->assertTrue($this->storage->isDir('/sub'));
$this->assertTrue($this->storage->isDir('/sub/sub1'));
$this->assertTrue($this->storage->isDir('/john'));
$this->assertTrue($this->storage->isDir('/empty'));
$this->assertTrue($this->storage->isDir('/sub/empty'));
$this->assertFalse($this->storage->isDir('a.txt'));
$this->assertFalse($this->storage->isDir('/sub/d.txt'));
$this->assertFalse($this->storage->isDir('/sub/sub1/f.txt'));
}
public function testRenameFile()
{
$this->storage->createFile('/', 'a.txt');
$this->storage->rename('/', 'a.txt', 'a1.txt');
$this->assertFalse($this->storage->fileExists('/a.txt'));
$this->assertTrue($this->storage->fileExists('/a1.txt'));
}
public function testRenameFileToExistingDestinationUpcountsFilenameRecursively()
{
$this->storage->createFile('/', 'a.txt');
$this->storage->createFile('/', 'a (1).txt');
$this->storage->createFile('/', 'test.txt');
$this->storage->rename('/', 'test.txt', 'a.txt');
$this->assertTrue($this->storage->fileExists('/a.txt'));
$this->assertTrue($this->storage->fileExists('/a (1).txt'));
$this->assertTrue($this->storage->fileExists('/a (2).txt')); // result
}
public function testRenameFileInSubfolder()
{
$this->storage->createDir('/', 'john');
$this->storage->createFile('/john', 'john.txt');
$this->storage->rename('/john/', 'john.txt', 'john2.txt');
$this->assertFalse($this->storage->fileExists('/john/john.txt'));
$this->assertTrue($this->storage->fileExists('/john/john2.txt'));
}
public function testRenameFileWithPathPrefix()
{
$this->storage->setPathPrefix('/john/');
$this->storage->createFile('/', 'john.txt');
$this->storage->rename('/', 'john.txt', 'john2.txt');
$this->assertFalse($this->storage->fileExists('/john.txt'));
$this->assertTrue($this->storage->fileExists('/john2.txt'));
}
public function testRenameNonexistingFileThrowsException()
{
$this->expectException(\Exception::class);
$this->storage->move('/', 'nonexisting.txt', 'a1.txt');
}
public function testCreatingFile()
{
$this->storage->createFile('/', 'sample22');
$ret = $this->storage->getDirectoryCollection('/');
$this->assertStringContainsString('sample22', json_encode($ret));
$this->storage->createFile('/sub/', 'sample33');
$ret = $this->storage->getDirectoryCollection('/sub/');
$this->assertStringContainsString('sample33', json_encode($ret));
}
public function testCreatingFileUpcountsNameIfAlreadyExists()
{
$this->assertFalse($this->storage->fileExists('/test.txt'));
$this->assertFalse($this->storage->fileExists('/test (1).txt'));
$this->storage->createFile('/', 'test.txt');
$this->storage->createFile('/', 'test.txt');
$this->assertTrue($this->storage->fileExists('/test.txt'));
$this->assertTrue($this->storage->fileExists('/test (1).txt'));
}
public function testCreatingFileUpcountsNameRecursivelyIfAlreadyExists()
{
$this->storage->createFile('/', 'test.txt');
$this->storage->createFile('/', 'test (1).txt');
// this file
$this->storage->createFile('/', 'test.txt');
$this->assertTrue($this->storage->fileExists('/test.txt'));
$this->assertTrue($this->storage->fileExists('/test (1).txt'));
$this->assertTrue($this->storage->fileExists('/test (2).txt')); // ends up here
}
public function testGetSeparator()
{
$separator = $this->storage->getSeparator();
$this->assertEquals($this->separator, $separator);
}
public function testCopyFile()
{
$this->storage->setPathPrefix('/john');
$this->storage->createFile('/', 'john.txt');
$this->storage->createDir('/', 'johnsub');
$this->storage->createFile('/johnsub', 'sub.txt');
$this->assertFalse($this->storage->fileExists('/johnsub/john.txt'));
$this->storage->copyFile('/john.txt', '/johnsub/');
$this->assertTrue($this->storage->fileExists('/johnsub/john.txt'));
$this->assertFalse($this->storage->fileExists('/sub.txt'));
$this->storage->copyFile('/johnsub/sub.txt', '/');
$this->assertTrue($this->storage->fileExists('/sub.txt'));
}
public function testCopyMissingFileThrowsException()
{
$this->storage->createDir('/', 'tmp');
$this->expectException(\Exception::class);
$this->storage->copyFile('/missing.txt', '/tmp/');
}
public function testCopyMissingDirCreatedADirOnDestination()
{
$this->storage->createDir('/', 'tmp');
$this->storage->copyDir('/missing/', '/tmp/');
$this->assertDirectoryExists(TEST_REPOSITORY.'/tmp/missing/');
}
public function testCopyDir()
{
$this->storage->createDir('/', '/john');
$this->storage->createDir('/john', '/johnsub');
$this->storage->createDir('/', '/jane');
$this->storage->copyDir('/john/johnsub', '/jane/');
$this->assertDirectoryExists(TEST_REPOSITORY.'/jane/johnsub');
}
public function testCopyDirWithSubDirs()
{
$this->storage->createDir('/', '/sub');
$this->storage->createDir('/sub', '/sub1');
$this->storage->createDir('/', '/jane');
$this->storage->copyDir('/sub', '/jane/');
$this->assertDirectoryExists(TEST_REPOSITORY.'/jane/sub');
$this->assertDirectoryExists(TEST_REPOSITORY.'/jane/sub/sub1');
}
public function testCopyDirWithEmptySubDir()
{
$this->storage->createDir('/', 'tmp');
$this->storage->createDir('/tmp/', 'sample22');
$this->storage->createDir('/tmp/sample22/', 'subsample1');
$this->storage->createDir('/tmp/sample22/', 'subsample2');
$this->storage->createFile('/tmp/sample22/subsample2', 'zzzz');
$this->assertDirectoryNotExists(TEST_REPOSITORY.'/jane/sample22');
$this->storage->copyDir('/tmp/sample22', '/jane/');
$this->assertDirectoryExists(TEST_REPOSITORY.'/jane/sample22');
$this->assertDirectoryExists(TEST_REPOSITORY.'/jane/sample22/subsample2');
$this->assertTrue($this->storage->fileExists('/jane/sample22/subsample2/zzzz'));
}
public function testCopyEmptyDir()
{
$this->storage->createDir('/', 'dest');
$this->storage->createDir('/', 'tmp');
$this->storage->copyDir('/tmp', '/dest');
$this->assertDirectoryExists(TEST_REPOSITORY.'/dest/tmp');
}
public function testCopyDirOverExistingUpcountsDestinationDirname()
{
/*
* /dest/tmp/
* /dest/tmp/a.txt
* /tmp/
* /tmp/b.txt
*
* copy /tmp/ => /dest/
*
* /dest/tmp/
* /dest/tmp/a.txt
* /dest/tmp (1)/
* /dest/tmp (1)/b.txt
*
*/
$this->storage->createDir('/', 'dest');
$this->storage->createDir('/dest', 'tmp');
$this->storage->createFile('/dest/tmp/', 'a.txt');
$this->storage->createDir('/', 'tmp');
$this->storage->createFile('/tmp/', 'b.txt');
$this->storage->copyDir('/tmp', '/dest');
$this->assertDirectoryExists(TEST_REPOSITORY.'/dest/tmp/');
$this->assertTrue($this->storage->fileExists('/dest/tmp/a.txt'));
$this->assertDirectoryExists(TEST_REPOSITORY.'/dest/tmp (1)');
$this->assertTrue($this->storage->fileExists('/dest/tmp (1)/b.txt'));
}
public function testMoveFile()
{
$this->storage->createFile('/', 'file.txt');
$this->storage->createDir('/', 'tmp');
$this->storage->move('/file.txt', '/tmp/file.txt');
$this->assertFalse($this->storage->fileExists('/file.txt'));
$this->assertTrue($this->storage->fileExists('/tmp/file.txt'));
}
public function testMoveDirectory()
{
$this->storage->createDir('/', 'test1');
$this->storage->createDir('/', 'test2');
$this->storage->move('/test1', '/test2/test1/');
$this->assertDirectoryExists(TEST_REPOSITORY.'/test2/test1/');
}
}

View File

@@ -0,0 +1,61 @@
<?php
/*
* This file is part of the FileGator package.
*
* (c) Milos Stojanovic <alcalbg@gmail.com>
*
* For the full copyright and license information, please view the LICENSE file
*/
namespace Tests\Unit;
use Filegator\App;
use Filegator\Config\Config;
use Filegator\Container\Container;
use Filegator\Kernel\Request;
use Filegator\Kernel\Response;
use Filegator\Services\View\Adapters\Vuejs;
use Tests\FakeResponse;
use Tests\FakeStreamedResponse;
use Tests\TestCase;
/**
* @internal
*/
class MainTest extends TestCase
{
public function testMainApp()
{
$config = new Config();
$request = new Request();
$response = new FakeResponse();
$sresponse = new FakeStreamedResponse();
$container = new Container();
$app = new App($config, $request, $response, $sresponse, $container);
$this->assertEquals($app->resolve(Config::class), $config);
$this->assertEquals($app->resolve(Request::class), $request);
$this->assertInstanceOf(Response::class, $app->resolve(Response::class));
}
public function testServices()
{
$config = [
'services' => [
'Service1' => [
'handler' => 'Filegator\Services\View\Adapters\Vuejs',
],
'Service2' => [
'handler' => 'Filegator\Services\View\Adapters\Vuejs',
],
],
];
$app = new App(new Config($config), new Request(), new FakeResponse(), new FakeStreamedResponse(), new Container());
$this->assertEquals($app->resolve('Service1'), new Vuejs(new Config($config)));
$this->assertEquals($app->resolve('Service2'), new Vuejs(new Config($config)));
}
}

View File

@@ -0,0 +1,141 @@
<?php
/*
* This file is part of the FileGator package.
*
* (c) Milos Stojanovic <alcalbg@gmail.com>
*
* For the full copyright and license information, please view the LICENSE file
*/
namespace Tests\Unit;
use Filegator\Kernel\Request;
use Tests\TestCase;
/**
* @internal
*/
class RequestTest extends TestCase
{
public function testGetRequest()
{
$request = Request::create(
'?r=/test&a=1&b=2',
'GET'
);
$this->assertEquals($request->all(), [
'r' => '/test',
'a' => '1',
'b' => '2',
]);
$this->assertEquals($request->input('r'), '/test');
$this->assertEquals($request->input('a'), '1');
$this->assertEquals($request->input('b'), '2');
}
public function testPostRequest()
{
$request = Request::create(
'/somewhere',
'POST',
['param1' => '1', 'param2' => '2']
);
$this->assertEquals($request->all(), [
'param1' => '1',
'param2' => '2',
]);
$this->assertEquals($request->input('param1'), '1');
$this->assertEquals($request->input('param2'), '2');
}
public function testJsonRequest()
{
$request = Request::create(
'',
'GET',
[],
[],
[],
[],
json_encode(['sample' => 'content'])
);
$this->assertEquals($request->all(), [
'sample' => 'content',
]);
$this->assertEquals($request->input('sample'), 'content');
}
public function testGetAndJsonParametersTogether()
{
$request = Request::create(
'/test?priority=1',
'POST',
[],
[],
[],
[],
json_encode(['sample' => 'content', 'more' => '1'])
);
$this->assertEquals($request->all(), [
'priority' => '1',
'sample' => 'content',
'more' => '1',
]);
$this->assertEquals($request->input('priority'), '1');
$this->assertEquals($request->input('sample'), 'content');
$this->assertEquals($request->input('more'), '1');
}
public function testGetPostParametersTogether()
{
$request = Request::create(
'/test?priority=10&something=else',
'POST',
['param' => 'param1', 'priority' => 5],
);
$this->assertEquals($request->all(), [
'priority' => '10',
'something' => 'else',
'param' => 'param1',
]);
$this->assertEquals($request->input('priority'), '10');
$this->assertEquals($request->input('something'), 'else');
$this->assertEquals($request->input('param'), 'param1');
}
public function testGetPostAndJsonParametersTogether()
{
$request = Request::create(
'/test?priority=10&something=else',
'POST',
['param' => 'param1', 'priority' => 5],
[],
[],
[],
json_encode(['sample' => 'content', 'priority' => '2'])
);
$this->assertEquals($request->all(), [
'priority' => '10',
'something' => 'else',
'param' => 'param1',
'sample' => 'content',
]);
$this->assertEquals($request->input('priority'), '10');
$this->assertEquals($request->input('something'), 'else');
$this->assertEquals($request->input('param'), 'param1');
$this->assertEquals($request->input('sample'), 'content');
}
}

View File

@@ -0,0 +1,172 @@
<?php
/*
* This file is part of the FileGator package.
*
* (c) Milos Stojanovic <alcalbg@gmail.com>
*
* For the full copyright and license information, please view the LICENSE file
*/
namespace Tests\Unit;
use Filegator\Container\Container;
use Filegator\Kernel\Request;
use Filegator\Services\Auth\User;
use Filegator\Services\Router\Router;
use Tests\MockUsers;
use Tests\TestCase;
/**
* @internal
*/
class RouterTest extends TestCase
{
private $config_stub;
public function setUp(): void
{
$this->config_stub = [
'query_param' => 'r',
'routes_file' => __DIR__.'/../testroutes.php',
];
parent::setUp();
}
public function testHome()
{
$request = Request::create('?r=/', 'GET');
$user = new User();
$container = $this->createMock(Container::class);
$container->expects($this->once())
->method('call')
->with(['\Filegator\Controllers\ViewController', 'index'], [])
;
$router = $this->getRouter($request, $user, $container);
}
public function testPostToLogin()
{
$request = Request::create('?r=/login', 'POST');
$user = new User();
$container = $this->createMock(Container::class);
$container->expects($this->once())
->method('call')
->with(['\Filegator\Controllers\AuthController', 'login'], [])
;
$router = $this->getRouter($request, $user, $container);
}
public function testRouteNotFound()
{
$request = Request::create('?r=/something', 'POST');
$user = new User();
$container = $this->createMock(Container::class);
$container->expects($this->once())
->method('call')
->with(['\Filegator\Controllers\ErrorController', 'notFound'], [])
;
$router = $this->getRouter($request, $user, $container);
}
public function testMethodNotAllowed()
{
$request = Request::create('?r=/login', 'GET');
$user = new User();
$container = $this->createMock(Container::class);
$container->expects($this->once())
->method('call')
->with(['\Filegator\Controllers\ErrorController', 'methodNotAllowed'], [])
;
$router = $this->getRouter($request, $user, $container);
}
public function testRouteIsProtectedFromGuests()
{
$request = Request::create('?r=/noguests', 'GET');
$user = new User();
$container = $this->createMock(Container::class);
$container->expects($this->once())
->method('call')
->with(['\Filegator\Controllers\ErrorController', 'notFound'], [])
;
$router = $this->getRouter($request, $user, $container);
}
public function testRouteIsAllowedForUser()
{
$request = Request::create('?r=/noguests', 'GET');
$user = new User();
$user->setRole('user');
$container = $this->createMock(Container::class);
$container->expects($this->once())
->method('call')
->with(['ProtectedController', 'protectedMethod'], [])
;
$router = $this->getRouter($request, $user, $container);
}
public function testRouteIsProtectedFromUsers()
{
$request = Request::create('?r=/adminonly', 'GET');
$user = new User();
$user->setRole('user');
$container = $this->createMock(Container::class);
$container->expects($this->once())
->method('call')
->with(['\Filegator\Controllers\ErrorController', 'notFound'], [])
;
$router = $this->getRouter($request, $user, $container);
}
public function testRouteIsAllowedForAdmin()
{
$request = Request::create('?r=/adminonly', 'GET');
$user = new User();
$user->setRole('admin');
$container = $this->createMock(Container::class);
$container->expects($this->once())
->method('call')
->with(['AdminController', 'adminOnlyMethod'], [])
;
$router = $this->getRouter($request, $user, $container);
}
private function getRouter(Request $request, User $user, Container $container)
{
$auth_stub = $this->createMock(MockUsers::class);
$auth_stub->method('user')
->willReturn($user)
;
$router = new Router($request, $auth_stub, $container);
$router->init($this->config_stub);
return $router;
}
}

View File

@@ -0,0 +1,62 @@
<?php
/*
* This file is part of the FileGator package.
*
* (c) Milos Stojanovic <alcalbg@gmail.com>
*
* For the full copyright and license information, please view the LICENSE file
*/
namespace Tests\Unit;
use Filegator\Kernel\Request;
use Filegator\Services\Session\Adapters\SessionStorage;
use Tests\TestCase;
/**
* @internal
*/
class SessionStorageTest extends TestCase
{
protected $session_service;
public function setUp(): void
{
$this->session_service = new SessionStorage(new Request());
$this->session_service->init([
'session_handler' => 'mockfilesession',
'available' => [
'mockfilesession' => function () {
return new \Symfony\Component\HttpFoundation\Session\Storage\MockFileSessionStorage();
},
],
]);
parent::setUp();
}
public function testInvalidateSession()
{
$this->session_service->set('test1', 444);
$this->session_service->invalidate();
$this->assertNull($this->session_service->get('test1'));
}
public function testInvalidateSessionWhichIsNotStartedYet()
{
$this->session_service->invalidate();
$this->assertNull($this->session_service->get('something'));
}
public function testUseSession()
{
$this->session_service->set('test2', 999);
$this->session_service->save();
$this->assertEquals($this->session_service->get('test2'), 999);
$this->assertNull($this->session_service->get('test1'));
}
}

View File

@@ -0,0 +1,146 @@
<?php
/*
* This file is part of the FileGator package.
*
* (c) Milos Stojanovic <alcalbg@gmail.com>
*
* For the full copyright and license information, please view the LICENSE file
*/
namespace Tests\Unit;
use Filegator\Services\Tmpfs\Adapters\Tmpfs;
use Tests\TestCase;
/**
* @internal
*/
class TmpfsTest extends TestCase
{
protected $service;
public function setUp(): void
{
$this->resetTempDir();
rmdir(TEST_TMP_PATH);
$this->service = new Tmpfs();
$this->service->init([
'path' => TEST_TMP_PATH,
'gc_probability_perc' => 100,
'gc_older_than' => 60 * 60 * 24 * 2, // 2 days
]);
parent::setUp();
}
public function testWriteContentToTmpFile()
{
$this->service->write('a.txt', 'lorem');
$this->assertFileExists(TEST_TMP_PATH.'/a.txt');
}
public function testWriteContentToTmpFileUsingStream()
{
$stream = fopen(TEST_FILE, 'r');
$this->service->write('a.txt', $stream);
$this->assertFileEquals(TEST_TMP_PATH.'/a.txt', TEST_FILE);
}
public function testReadingTmpFileContents()
{
$this->service->write('a.txt', 'lorem');
$contents = $this->service->read('a.txt');
$this->assertEquals($contents, 'lorem');
}
public function testReadingTmpFileContentsUsingStream()
{
$this->service->write('a.txt', 'lorem');
$ret = $this->service->readStream('a.txt');
$this->assertEquals($ret['filename'], 'a.txt');
$contents = stream_get_contents($ret['stream']);
$this->assertEquals($contents, 'lorem');
}
public function testRemovingTmpFile()
{
$this->service->write('a.txt', 'lorem');
$this->assertFileExists(TEST_TMP_PATH.'a.txt');
$this->service->remove('a.txt');
$this->assertFileNotExists(TEST_TMP_PATH.'a.txt');
}
public function testCheckExistingFile()
{
$this->service->write('a.txt', 'lorem');
$this->assertTrue($this->service->exists('a.txt'));
$this->assertFalse($this->service->exists('nothere.txt'));
}
public function testFindingAllFilesMatchingPatters()
{
$this->service->write('a.txt', 'lorem');
$this->service->write('b.txt', 'lorem');
$this->service->write('b.zip', 'lorem');
$this->assertCount(2, $this->service->findAll('*.txt'));
$this->assertCount(2, $this->service->findAll('b*'));
$this->assertCount(3, $this->service->findAll('*'));
$this->assertCount(0, $this->service->findAll('1*2'));
}
public function testCleaningFilesOlderThan()
{
$this->service->write('a.txt', 'lorem');
$this->service->write('b.txt', 'lorem');
$this->service->write('b.zip', 'lorem');
$this->service->clean(10000);
$this->assertCount(3, $this->service->findAll('*'));
$this->service->clean(0);
$this->assertCount(0, $this->service->findAll('*'));
}
public function testDeleteOldFilesAutomaticaly()
{
touch(TEST_TMP_PATH.'fresh.txt', time());
touch(TEST_TMP_PATH.'old.txt', time() - 60 * 60 * 24 * 10); // 10 days old
$this->service->init([
'path' => TEST_TMP_PATH,
'gc_probability_perc' => 100,
'gc_older_than' => 60 * 60 * 24 * 2, // 2 days
]);
$this->assertFileExists(TEST_TMP_PATH.'fresh.txt');
$this->assertFileNotExists(TEST_TMP_PATH.'old.txt');
}
public function testGarbageIsNotDeletedEveryTime()
{
touch(TEST_TMP_PATH.'old.txt', time() - 60 * 60 * 24 * 10); // 10 days old
$this->service->init([
'path' => TEST_TMP_PATH,
'gc_probability_perc' => 0,
'gc_older_than' => 60 * 60 * 24 * 2, // 2 days
]);
$this->assertFileExists(TEST_TMP_PATH.'old.txt');
}
}

View File

@@ -0,0 +1,173 @@
<?php
/*
* This file is part of the FileGator package.
*
* (c) Milos Stojanovic <alcalbg@gmail.com>
*
* For the full copyright and license information, please view the LICENSE file
*/
use Filegator\Services\Auth\User;
use Tests\TestCase;
/**
* @internal
*/
class UserTest extends TestCase
{
public function testUser()
{
$name = 'John Doe';
$username = 'john.doe@example.com';
$homedir = '/';
$role = 'user';
$permissions = ['read'];
$user = new User($role, $homedir, $username, $name);
$user->setRole($role);
$user->setHomedir($homedir);
$user->setUsername($username);
$user->setName($name);
$user->setPermissions($permissions);
$this->assertTrue($user->isUser());
$decoded = json_decode(json_encode($user));
$this->assertEquals('user', $decoded->role);
$this->assertEquals($username, $decoded->username);
$this->assertEquals($name, $decoded->name);
$this->assertEquals($permissions, $decoded->permissions);
}
public function testAdmin()
{
$user = new User();
$user->setRole('admin');
$this->assertTrue($user->isAdmin());
}
public function testGuest()
{
$user = new User();
$this->assertTrue($user->isGuest());
$decoded = json_decode(json_encode($user), true);
$this->assertEquals([
'role' => 'guest',
'homedir' => '',
'username' => '',
'name' => '',
'permissions' => [],
], $decoded);
}
public function testUserCannotGetNonExistingRole()
{
$user = new User();
$this->expectException(\Exception::class);
$user->setRole('nonexistent');
}
public function testUserCannotGetNonExistingPermision()
{
$user = new User();
$this->expectException(\Exception::class);
$user->setPermissions(['read', 'write', 'nonexistent']);
}
public function testUserHasRole()
{
$user = new User();
$user->setRole('user');
$this->assertTrue($user->hasRole('user'));
$this->assertTrue($user->hasRole(['user']));
$this->assertTrue($user->hasRole(['admin', 'guest', 'user']));
$this->assertFalse($user->hasRole(['admin', 'guest']));
$this->assertFalse($user->hasRole('admin'));
}
public function testDefaultUserHasNoPermissions()
{
$user = new User();
$this->assertTrue($user->hasPermissions([]));
$this->assertFalse($user->hasPermissions('read'));
$this->assertFalse($user->hasPermissions(['read']));
$this->assertFalse($user->hasPermissions(['write', 'upload', 'read']));
$this->assertFalse($user->hasPermissions(['write', 'upload']));
$this->assertFalse($user->hasPermissions('upload'));
}
public function testUserHasOnlyPermissionsSet()
{
$user = new User();
$user->setPermissions(['read', 'write']);
$this->assertTrue($user->hasPermissions('read'));
$this->assertTrue($user->hasPermissions(['read']));
$this->assertTrue($user->hasPermissions('write'));
$this->assertTrue($user->hasPermissions(['write']));
$this->assertTrue($user->hasPermissions(['read', 'write']));
$this->assertTrue($user->hasPermissions(['write', 'read']));
$this->assertFalse($user->hasPermissions(['write', 'upload', 'read']));
$this->assertFalse($user->hasPermissions(['write', 'upload']));
$this->assertFalse($user->hasPermissions('upload'));
}
public function testUserCanHaveReadPermissions()
{
$user = new User();
$user->setPermissions(['read']);
$this->assertTrue($user->hasPermissions('read'));
}
public function testUserCanHaveWritePermissions()
{
$user = new User();
$user->setPermissions(['write']);
$this->assertTrue($user->hasPermissions('write'));
}
public function testUserCanHaveUploadPermissions()
{
$user = new User();
$user->setPermissions(['upload']);
$this->assertTrue($user->hasPermissions('upload'));
}
public function testUserCanHaveDownloadPermissions()
{
$user = new User();
$user->setPermissions(['download']);
$this->assertTrue($user->hasPermissions('download'));
}
public function testUserCanHaveBatchDownloadPermissions()
{
$user = new User();
$user->setPermissions(['batchdownload']);
$this->assertTrue($user->hasPermissions('batchdownload'));
}
public function testUserCanHaveZipPermissions()
{
$user = new User();
$user->setPermissions(['zip']);
$this->assertTrue($user->hasPermissions('zip'));
}
}

View File

@@ -0,0 +1,31 @@
<?php
/*
* This file is part of the FileGator package.
*
* (c) Milos Stojanovic <alcalbg@gmail.com>
*
* For the full copyright and license information, please view the LICENSE file
*/
namespace Tests\Unit;
use Filegator\Config\Config;
use Filegator\Services\View\Adapters\Vuejs;
use Tests\TestCase;
/**
* @internal
*/
class ViewTest extends TestCase
{
public function testViewService()
{
$config_mock = new Config(['frontend_config' => ['app_name' => 'testapp']]);
$service = new Vuejs($config_mock);
$service->init();
$this->assertRegexp('/testapp/', $service->getIndexPage());
}
}

View File

@@ -0,0 +1,79 @@
<?php
return [
'public_path' => '',
'public_dir' => __DIR__.'/../../dist',
'frontend_config' => [
'app_name' => 'FileGator',
'language' => 'english',
'logo' => 'https://via.placeholder.com/263x55.png',
'upload_max_size' => 2 * 1024 * 1024,
'upload_chunk_size' => 1 * 1024 * 1024,
'upload_simultaneous' => 3,
'default_archive_name' => 'archive.zip',
],
'services' => [
'Filegator\Services\Logger\LoggerInterface' => [
'handler' => '\Filegator\Services\Logger\Adapters\MonoLogger',
'config' => [
'monolog_handlers' => [
function () {
return new \Monolog\Handler\NullHandler();
},
],
],
],
'Filegator\Services\Session\SessionStorageInterface' => [
'handler' => '\Filegator\Services\Session\Adapters\SessionStorage',
'config' => [
'session_handler' => 'mockfilesession',
'available' => [
'mockfilesession' => function () {
return new \Symfony\Component\HttpFoundation\Session\Storage\MockFileSessionStorage();
},
],
],
],
'Filegator\Services\Tmpfs\TmpfsInterface' => [
'handler' => '\Filegator\Services\Tmpfs\Adapters\Tmpfs',
'config' => [
'path' => TEST_TMP_PATH,
'gc_probability_perc' => 10,
'gc_older_than' => 60 * 60 * 24 * 2, // 2 days
],
],
'Filegator\Services\View\ViewInterface' => [
'handler' => '\Filegator\Services\View\Adapters\Vuejs',
],
'Filegator\Services\Storage\Filesystem' => [
'handler' => '\Filegator\Services\Storage\Filesystem',
'config' => [
'separator' => '/',
'filesystem_adapter' => 'localfilesystem',
'adapters' => [
'localfilesystem' => function () {
return new \League\Flysystem\Adapter\Local(
TEST_REPOSITORY
);
},
],
],
],
'Filegator\Services\Auth\AuthInterface' => [
'handler' => '\Tests\MockUsers',
],
'Filegator\Services\Archiver\ArchiverInterface' => [
'handler' => '\Filegator\Services\Archiver\Adapters\ZipArchiver',
'config' => [],
],
'Filegator\Services\Router\Router' => [
'handler' => '\Filegator\Services\Router\Router',
'config' => [
'query_param' => 'r',
'routes_file' => __DIR__.'/../../backend/Controllers/routes.php',
],
],
],
];

View File

@@ -0,0 +1,44 @@
<?php
return [
[
'route' => [
'GET', '/', '\Filegator\Controllers\ViewController@index',
],
'roles' => [
'guest',
],
'permissions' => [
],
],
[
'route' => [
'POST', '/login', '\Filegator\Controllers\AuthController@login',
],
'roles' => [
'guest',
],
'permissions' => [
],
],
[
'route' => [
'GET', '/noguests', 'ProtectedController@protectedMethod',
],
'roles' => [
'user', 'admin',
],
'permissions' => [
],
],
[
'route' => [
'GET', '/adminonly', 'AdminController@adminOnlyMethod',
],
'roles' => [
'admin',
],
'permissions' => [
],
],
];

3
tests/backend/tmp/.gitignore vendored Executable file
View File

@@ -0,0 +1,3 @@
*
!.gitignore
!testarchive.zip

Binary file not shown.