From 77198abd94437eb418f11957695986470b1afc9a Mon Sep 17 00:00:00 2001 From: Florian Pritz Date: Thu, 21 May 2015 14:45:53 +0200 Subject: tests: Make prove --state work; Restructure tests This moves all tests into a subdirectory and lets prove itself figure out which tests exist. It seems if you supply the testlist via arguments or stdin --state won't affect the order. Signed-off-by: Florian Pritz --- application/controllers/tools.php | 7 +- application/test/Test.php | 132 +++++++ application/test/tests/test_api_v1.php | 434 +++++++++++++++++++++ application/test/tests/test_libraries_image.php | 38 ++ application/test/tests/test_libraries_pygments.php | 86 ++++ application/test/tests/test_service_files.php | 85 ++++ .../test/tests/test_service_files_valid_id.php | 115 ++++++ application/tests/Test.php | 132 ------- application/tests/test_api_v1.php | 434 --------------------- application/tests/test_libraries_image.php | 38 -- application/tests/test_libraries_pygments.php | 86 ---- application/tests/test_service_files.php | 85 ---- application/tests/test_service_files_valid_id.php | 115 ------ 13 files changed, 895 insertions(+), 892 deletions(-) create mode 100644 application/test/Test.php create mode 100644 application/test/tests/test_api_v1.php create mode 100644 application/test/tests/test_libraries_image.php create mode 100644 application/test/tests/test_libraries_pygments.php create mode 100644 application/test/tests/test_service_files.php create mode 100644 application/test/tests/test_service_files_valid_id.php delete mode 100644 application/tests/Test.php delete mode 100644 application/tests/test_api_v1.php delete mode 100644 application/tests/test_libraries_image.php delete mode 100644 application/tests/test_libraries_pygments.php delete mode 100644 application/tests/test_service_files.php delete mode 100644 application/tests/test_service_files_valid_id.php (limited to 'application') diff --git a/application/controllers/tools.php b/application/controllers/tools.php index d1d5ba39b..d38ab7c39 100644 --- a/application/controllers/tools.php +++ b/application/controllers/tools.php @@ -70,8 +70,11 @@ class Tools extends MY_Controller { $url = $argv[3]; $testcase = $argv[4]; - $testclass = '\tests\\'.$testcase; - $test = new $testclass(); + $testcase = str_replace("application/", "", $testcase); + $testcase = str_replace("/", "\\", $testcase); + $testcase = str_replace(".php", "", $testcase); + + $test = new $testcase(); $test->setServer($url); $exitcode = 0; diff --git a/application/test/Test.php b/application/test/Test.php new file mode 100644 index 000000000..925fe131e --- /dev/null +++ b/application/test/Test.php @@ -0,0 +1,132 @@ + + * + * Licensed under AGPLv3 + * (see COPYING for full license text) + * + */ + +namespace test; + +require_once APPPATH."/third_party/test-more-php/Test-More-OO.php"; + +class TestMore extends \TestMore { + private $TestNamePrefix = ""; + + public function setTestNamePrefix($prefix) { + $this->TestNamePrefix = $prefix; + } + + public function ok ($Result = NULL, $TestName = NULL) { + return parent::ok($Result, $this->TestNamePrefix.$TestName); + } +} + +abstract class Test { + protected $t; + protected $server = ""; + + public function __construct() + { + $this->t = new TestMore(); + $this->t->plan("no_plan"); + } + + public function setServer($server) + { + $this->server = $server; + } + + // Method: POST, PUT, GET etc + // Data: array("param" => "value") ==> index.php?param=value + // Source: http://stackoverflow.com/a/9802854/953022 + protected function CallAPI($method, $url, $data = false) + { + $result = $this->SendHTTPRequest($method, $url, $data); + + $json = json_decode($result, true); + if ($json === NULL) { + $this->t->fail("json decode"); + $this->diagReply($result); + } + + return $json; + } + + protected function SendHTTPRequest($method, $url, $data = false) + { + $curl = curl_init(); + + switch ($method) { + case "POST": + curl_setopt($curl, CURLOPT_POST, 1); + + if ($data) + curl_setopt($curl, CURLOPT_POSTFIELDS, $data); + break; + case "PUT": + curl_setopt($curl, CURLOPT_PUT, 1); + break; + default: + if ($data) + $url = sprintf("%s?%s", $url, http_build_query($data)); + } + + curl_setopt($curl, CURLOPT_URL, $url); + curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($curl, CURLOPT_HTTPHEADER, array( + "Accept: application/json", + "Expect: ", + )); + + $result = curl_exec($curl); + + curl_close($curl); + return $result; + } + + protected function excpectStatus($testname, $reply, $status) + { + if (!isset($reply["status"]) || $reply["status"] != $status) { + $this->t->fail($testname); + $this->diagReply($reply); + } else { + $this->t->pass($testname); + } + return $reply; + } + + protected function expectSuccess($testname, $reply) + { + return $this->excpectStatus($testname, $reply, "success"); + } + + protected function expectError($testname, $reply) + { + return $this->excpectStatus($testname, $reply, "error"); + } + + protected function diagReply($reply) + { + $this->t->diag("Request got unexpected response:"); + $this->t->diag(var_export($reply, true)); + } + + public function init() + { + } + + public function cleanup() + { + } + + public function done_testing() + { + $this->t->done_testing(); + } + + public function setTestNamePrefix($prefix) { + $this->t->setTestNamePrefix($prefix); + } +} diff --git a/application/test/tests/test_api_v1.php b/application/test/tests/test_api_v1.php new file mode 100644 index 000000000..cdac30544 --- /dev/null +++ b/application/test/tests/test_api_v1.php @@ -0,0 +1,434 @@ + + * + * Licensed under AGPLv3 + * (see COPYING for full license text) + * + */ + +namespace test\tests; + +class test_api_v1 extends \test\Test { + + public function __construct() + { + parent::__construct(); + + $CI =& get_instance(); + $CI->load->model("muser"); + $CI->load->model("mfile"); + + } + + private function uploadFile($apikey, $file) + { + $ret = $this->CallAPI("POST", "$this->server/api/v1.1.0/file/upload", array( + "apikey" => $apikey, + "file[1]" => curl_file_create($file), + )); + $this->expectSuccess("upload file", $ret); + return $ret; + } + + private function createUser($counter) + { + $CI =& get_instance(); + $CI->db->insert("users", array( + 'username' => "testuser-api_v1-$counter", + 'password' => $CI->muser->hash_password("testpass$counter"), + 'email' => "testuser$counter@localhost.invalid", + 'referrer' => NULL + )); + + return $CI->db->insert_id(); + } + + private function createApikey($userid, $access_level = "apikey") + { + return \service\user::create_apikey($userid, "", $access_level); + } + + private function createUserAndApikey($access_level = "apikey") + { + static $counter = 100; + $counter++; + $userid = $this->createUser($counter); + return $this->createApikey($userid, $access_level); + } + + private function callEndpoint($verb, $endpoint, $data) + { + return $this->CallAPI($verb, "$this->server/api/v1.0.0/$endpoint", $data); + } + + public function test_callPrivateEndpointsWithoutApikey() + { + $endpoints = array( + "file/upload", + "file/history", + "file/delete", + "file/create_multipaste", + "user/apikeys", + "user/create_apikey", + "user/delete_apikey", + ); + foreach ($endpoints as $endpoint) { + $ret = $this->CallEndpoint("POST", $endpoint, array( + )); + $this->expectError("call $endpoint without apikey", $ret); + $this->t->is_deeply(array( + 'status' => 'error', + 'error_id' => 'api/not-authenticated', + 'message' => 'Not authenticated. FileBin requires you to have an account, please go to the homepage for more information.', + ), $ret, "expected error"); + } + } + + public function test_callEndpointsWithoutEnoughPermissions() + { + $testconfig = array( + array( + "apikey" => $this->createUserAndApikey('basic'), + "endpoints" => array( + "file/delete", + "file/history", + ), + ), + array( + "apikey" => $this->createUserAndApikey(), + "endpoints" => array( + "user/apikeys", + "user/create_apikey", + "user/delete_apikey", + ), + ), + ); + foreach ($testconfig as $test) { + foreach ($test['endpoints'] as $endpoint) { + $ret = $this->CallEndpoint("POST", $endpoint, array( + "apikey" => $test['apikey'], + )); + $this->expectError("call $endpoint without enough permissions", $ret); + $this->t->is_deeply(array( + 'status' => "error", + 'error_id' => "api/insufficient-permissions", + 'message' => "Access denied: Access level too low", + ), $ret, "expected permission error"); + } + } + } + + public function test_create_apikey_createNewKey() + { + $this->createUser(1); + $ret = $this->CallEndpoint("POST", "user/create_apikey", array( + "username" => "testuser-api_v1-1", + "password" => "testpass1", + "access_level" => "apikey", + "comment" => "main api key", + )); + $this->expectSuccess("create-apikey", $ret); + + $this->t->isnt($ret["data"]["new_key"], "", "apikey not empty"); + } + + public function test_apikeys_getApikey() + { + $userid = $this->createUser(2); + $apikey = $this->createApikey($userid); + $ret = $this->CallEndpoint("POST", "user/apikeys", array( + "username" => "testuser-api_v1-2", + "password" => "testpass2", + )); + $this->expectSuccess("get apikeys", $ret); + + $this->t->is($ret["data"]["apikeys"][$apikey]["key"], $apikey, "expected key 1"); + $this->t->is($ret["data"]["apikeys"][$apikey]["access_level"], "apikey", "expected key 1 acces_level"); + $this->t->is($ret["data"]["apikeys"][$apikey]["comment"], "", "expected key 1 comment"); + $this->t->ok(is_int($ret["data"]["apikeys"][$apikey]["created"]) , "expected key 1 creation time is int"); + } + + public function test_delete_apikey_deleteOwnKey() + { + $apikey = $this->createUserAndApikey("full"); + $ret = $this->CallEndpoint("POST", "user/delete_apikey", array( + "apikey" => $apikey, + "delete_key" => $apikey, + )); + $this->expectSuccess("delete apikey", $ret); + + $this->t->is($ret["data"]["deleted_keys"][$apikey]["key"], $apikey, "expected key"); + } + + public function test_delete_apikey_errorDeleteOtherUserKey() + { + $apikey = $this->createUserAndApikey("full"); + $apikey2 = $this->createUserAndApikey("full"); + $ret = $this->CallEndpoint("POST", "user/delete_apikey", array( + "apikey" => $apikey, + "delete_key" => $apikey2, + )); + $this->expectError("delete apikey of other user", $ret); + $this->t->is_deeply(array( + 'status' => 'error', + 'error_id' => 'user/delete_apikey/failed', + 'message' => 'Apikey deletion failed. Possibly wrong owner.', + ), $ret, "expected error"); + } + + public function test_authentication_invalidPassword() + { + $userid = $this->createUser(3); + $ret = $this->CallEndpoint("POST", "user/apikeys", array( + "username" => "testuser-api_v1-3", + "password" => "wrongpass", + )); + $this->expectError("invalid password", $ret); + + $this->t->is_deeply(array ( + 'status' => 'error', + 'error_id' => 'user/login-failed', + 'message' => 'Login failed', + ), $ret, "expected error"); + } + + public function test_authentication_invalidUser() + { + $userid = $this->createUser(4); + $ret = $this->CallEndpoint("POST", "user/apikeys", array( + "username" => "testuser-api_v1-invalid", + "password" => "testpass4", + )); + $this->expectError("invalid username", $ret); + + $this->t->is_deeply(array ( + 'status' => 'error', + 'error_id' => 'user/login-failed', + 'message' => 'Login failed', + ), $ret, "expected error"); + } + + public function test_history_empty() + { + $apikey = $this->createUserAndApikey(); + $ret = $this->CallEndpoint("POST", "file/history", array( + "apikey" => $apikey, + )); + $this->expectSuccess("get history", $ret); + + $this->t->ok(empty($ret["data"]["items"]), "items key exists and empty"); + $this->t->ok(empty($ret["data"]["multipaste_items"]), "multipaste_items key exists and empty"); + $this->t->is($ret["data"]["total_size"], 0, "total_size = 0 since no uploads"); + } + + public function test_get_config() + { + $ret = $this->CallEndpoint("GET", "file/get_config", array( + )); + $this->expectSuccess("get_config", $ret); + + $this->t->like($ret["data"]["upload_max_size"], '/[0-9]+/', "upload_max_size is int"); + $this->t->like($ret["data"]["max_files_per_request"], '/[0-9]+/', "max_files_per_request is int"); + } + + public function test_upload_uploadFile() + { + $apikey = $this->createUserAndApikey(); + $ret = $this->CallEndpoint("POST", "file/upload", array( + "apikey" => $apikey, + "file[1]" => curl_file_create("data/tests/small-file"), + )); + $this->expectSuccess("upload file", $ret); + + $this->t->ok(!empty($ret["data"]["ids"]), "got IDs"); + $this->t->ok(!empty($ret["data"]["urls"]), "got URLs"); + } + + public function test_upload_uploadFileSameMD5() + { + $apikey = $this->createUserAndApikey(); + $ret = $this->CallEndpoint("POST", "file/upload", array( + "apikey" => $apikey, + "file[1]" => curl_file_create("data/tests/message1.bin"), + "file[2]" => curl_file_create("data/tests/message2.bin"), + )); + $this->expectSuccess("upload file", $ret); + + $this->t->ok(!empty($ret["data"]["ids"]), "got IDs"); + $this->t->ok(!empty($ret["data"]["urls"]), "got URLs"); + + foreach ($ret["data"]["urls"] as $url) { + $data[] = $this->SendHTTPRequest("GET", $url, ''); + } + $this->t->ok($data[0] !== $data[1], 'Returned file contents should differ'); + } + + public function test_upload_uploadNothing() + { + $apikey = $this->createUserAndApikey(); + $ret = $this->CallEndpoint("POST", "file/upload", array( + "apikey" => $apikey, + )); + $this->expectError("upload no file", $ret); + $this->t->is_deeply(array( + 'status' => 'error', + 'error_id' => 'file/no-file', + 'message' => 'No file was uploaded or unknown error occurred.', + ), $ret, "expected reply"); + } + + public function test_history_notEmptyAfterUpload() + { + $apikey = $this->createUserAndApikey(); + $this->uploadFile($apikey, "data/tests/small-file"); + + $ret = $this->CallEndpoint("POST", "file/history", array( + "apikey" => $apikey, + )); + $this->expectSuccess("history not empty after upload", $ret); + + $this->t->ok(!empty($ret["data"]["items"]), "history not empty after upload (items)"); + $this->t->ok(empty($ret["data"]["multipaste_items"]), "didn't upload multipaste"); + $this->t->is($ret["data"]["total_size"], filesize("data/tests/small-file"), "total_size == uploaded file"); + } + + public function test_history_notSharedBetweenUsers() + { + $apikey = $this->createUserAndApikey(); + $apikey2 = $this->createUserAndApikey(); + $this->uploadFile($apikey, "data/tests/small-file"); + + $ret = $this->CallEndpoint("POST", "file/history", array( + "apikey" => $apikey2, + )); + $this->expectSuccess("get history", $ret); + + $this->t->ok(empty($ret["data"]["items"]), "items key exists and empty"); + $this->t->ok(empty($ret["data"]["multipaste_items"]), "multipaste_items key exists and empty"); + $this->t->is($ret["data"]["total_size"], 0, "total_size = 0 since no uploads"); + } + + public function test_delete_canDeleteUploaded() + { + $apikey = $this->createUserAndApikey(); + $ret = $this->uploadFile($apikey, "data/tests/small-file"); + $id = $ret["data"]["ids"][0]; + + $ret = $this->CallEndpoint("POST", "file/delete", array( + "apikey" => $apikey, + "ids[1]" => $id, + )); + $this->expectSuccess("delete uploaded file", $ret); + + $this->t->ok(empty($ret["data"]["errors"]), "no errors"); + $this->t->is_deeply(array( + $id => array( + "id" => $id + ) + ), $ret["data"]["deleted"], "deleted wanted ID"); + $this->t->is($ret["data"]["total_count"], 1, "total_count correct"); + $this->t->is($ret["data"]["deleted_count"], 1, "deleted_count correct"); + } + + public function test_delete_errorIfNotOwner() + { + $apikey = $this->createUserAndApikey(); + $apikey2 = $this->createUserAndApikey(); + $ret = $this->uploadFile($apikey, "data/tests/small-file"); + $id = $ret["data"]["ids"][0]; + + $ret = $this->CallEndpoint("POST", "file/delete", array( + "apikey" => $apikey2, + "ids[1]" => $id, + )); + $this->expectSuccess("delete file of someone else", $ret); + + $this->t->ok(empty($ret["data"]["deleted"]), "not deleted"); + $this->t->is_deeply(array( + $id => array( + "id" => $id, + "reason" => "wrong owner" + ) + ), $ret["data"]["errors"], "error wanted ID"); + $this->t->is($ret["data"]["total_count"], 1, "total_count correct"); + $this->t->is($ret["data"]["deleted_count"], 0, "deleted_count correct"); + } + + public function test_create_multipaste_canCreate() + { + $apikey = $this->createUserAndApikey("basic"); + $ret = $this->uploadFile($apikey, "data/tests/small-file"); + $id = $ret["data"]["ids"][0]; + + $ret = $this->uploadFile($apikey, "data/tests/small-file"); + $id2 = $ret["data"]["ids"][0]; + + $ret = $this->CallEndpoint("POST", "file/create_multipaste", array( + "apikey" => $apikey, + "ids[1]" => $id, + "ids[2]" => $id2, + )); + $this->expectSuccess("create multipaste", $ret); + + $this->t->isnt($ret["data"]["url_id"], "", "got a multipaste ID"); + $this->t->isnt($ret["data"]["url"], "", "got a multipaste URL"); + } + + public function test_create_multipaste_errorOnWrongID() + { + $apikey = $this->createUserAndApikey("basic"); + $ret = $this->uploadFile($apikey, "data/tests/small-file"); + $id = $ret["data"]["ids"][0]; + + $id2 = $id."invalid"; + $ret = $this->CallEndpoint("POST", "file/create_multipaste", array( + "apikey" => $apikey, + "ids[1]" => $id, + "ids[2]" => $id2, + )); + $this->expectError("create multipaste with wrong ID", $ret); + + $this->t->is_deeply(array( + 'status' => 'error', + 'error_id' => 'file/create_multipaste/verify-failed', + 'message' => 'Failed to verify ID(s)', + 'data' => + array ( + $id2 => + array ( + 'id' => $id2, + 'reason' => 'doesn\'t exist', + ), + ), + ), $ret, "expected error response"); + } + + public function test_create_multipaste_errorOnWrongOwner() + { + $apikey = $this->createUserAndApikey("basic"); + $apikey2 = $this->createUserAndApikey("basic"); + $ret = $this->uploadFile($apikey, "data/tests/small-file"); + $id = $ret["data"]["ids"][0]; + + $ret = $this->CallEndpoint("POST", "file/create_multipaste", array( + "apikey" => $apikey2, + "ids[1]" => $id, + )); + $this->expectError("create multipaste with wrong owner", $ret); + + $this->t->is_deeply(array( + 'status' => 'error', + 'error_id' => 'file/create_multipaste/verify-failed', + 'message' => 'Failed to verify ID(s)', + 'data' => + array ( + $id => + array ( + 'id' => $id, + 'reason' => 'not owned by you', + ), + ), + ), $ret, "expected error response"); + } +} diff --git a/application/test/tests/test_libraries_image.php b/application/test/tests/test_libraries_image.php new file mode 100644 index 000000000..13c9e67b9 --- /dev/null +++ b/application/test/tests/test_libraries_image.php @@ -0,0 +1,38 @@ + + * + * Licensed under AGPLv3 + * (see COPYING for full license text) + * + */ + +namespace test\tests; + +class test_libraries_image extends \test\Test { + + public function __construct() + { + parent::__construct(); + } + + public function init() + { + } + + public function cleanup() + { + } + + public function test_type_supported_normalCase() + { + $this->t->is(\libraries\Image::type_supported('image/png'), true, 'image/png should be supported'); + $this->t->is(\libraries\Image::type_supported('image/jpeg'), true, 'image/jpeg should be supported'); + $this->t->is(\libraries\Image::type_supported('application/pdf'), true, 'application/pdf should be supported'); + + $this->t->is(\libraries\Image::type_supported('application/octet-stream'), false, 'application/octet-stream should not be supported'); + $this->t->is(\libraries\Image::type_supported('text/plain'), false, 'text/plain should not be supported'); + } + +} + diff --git a/application/test/tests/test_libraries_pygments.php b/application/test/tests/test_libraries_pygments.php new file mode 100644 index 000000000..768bca439 --- /dev/null +++ b/application/test/tests/test_libraries_pygments.php @@ -0,0 +1,86 @@ + + * + * Licensed under AGPLv3 + * (see COPYING for full license text) + * + */ + +namespace test\tests; + +class test_libraries_pygments extends \test\Test { + + public function __construct() + { + parent::__construct(); + } + + public function init() + { + } + + public function cleanup() + { + } + + public function test_autodetect_lexer_normalCase() + { + $p = new \libraries\Pygments('/invalid/filepath', 'text/plain', 'stdin'); + $this->t->is($p->autodetect_lexer(), 'text', "text/plain should be text"); + + $p = new \libraries\Pygments('/invalid/filepath', 'application/x-php', 'stdin'); + $this->t->is($p->autodetect_lexer(), 'php', "application/php should be php"); + + // This is from pygments and not our hardcoded list + $p = new \libraries\Pygments('/invalid/filepath', 'text/x-pascal', 'stdin'); + $this->t->is($p->autodetect_lexer(), 'delphi', "text/x-pascal should be delphi"); + + $p = new \libraries\Pygments('/invalid/filepath', 'application/octet-stream', 'stdin'); + $this->t->is($p->autodetect_lexer(), false, "application/octet-stream should return false"); + } + + public function test_autodetect_lexer_specialFilenames() + { + $p = new \libraries\Pygments('/invalid/filepath', 'text/plain', 'foo.c'); + $this->t->is($p->autodetect_lexer(), 'c', "foo.c should be c"); + + $p = new \libraries\Pygments('/invalid/filepath', 'text/plain', 'PKGBUILD'); + $this->t->is($p->autodetect_lexer(), 'bash', "PKGBUILD should be bash"); + } + + public function test_autodetect_lexer_specialFilenamesBinaryShouldNotHighlight() + { + $p = new \libraries\Pygments('/invalid/filepath', 'application/octet-stream', 'foo.c'); + $this->t->is($p->autodetect_lexer(), false, "foo.c should not highlight if binary"); + + $p = new \libraries\Pygments('/invalid/filepath', 'application/octet-stream', 'PKGBUILD'); + $this->t->is($p->autodetect_lexer(), false, "PKGBUILD should not highlight if binary"); + } + + public function test_can_highlight_normalCase() + { + $p = new \libraries\Pygments('/invalid/filepath', 'text/plain', 'stdin'); + $this->t->is($p->can_highlight(), true, "text/plain can highlight"); + + $p = new \libraries\Pygments('/invalid/filepath', 'application/x-php', 'stdin'); + $this->t->is($p->can_highlight(), true, "application/x-php can highlight"); + + $p = new \libraries\Pygments('/invalid/filepath', 'application/octet-stream', 'stdin'); + $this->t->is($p->can_highlight(), false, "application/octet-stream can not highlight"); + } + + public function test_autodetect_lexer_canButShouldntHighlight() + { + $p = new \libraries\Pygments('/invalid/filepath', 'image/svg+xml', 'foo.svg'); + $this->t->is($p->autodetect_lexer(), false, "image/svg+xml should return false"); + } + + public function test_can_highlight_canButShouldntHighlight() + { + $p = new \libraries\Pygments('/invalid/filepath', 'image/svg+xml', 'foo.svg'); + $this->t->is($p->can_highlight(), true, "image/svg+xml can highlight"); + } + +} + diff --git a/application/test/tests/test_service_files.php b/application/test/tests/test_service_files.php new file mode 100644 index 000000000..21688230f --- /dev/null +++ b/application/test/tests/test_service_files.php @@ -0,0 +1,85 @@ + + * + * Licensed under AGPLv3 + * (see COPYING for full license text) + * + */ + +namespace test\tests; + +class test_service_files extends \test\Test { + + public function __construct() + { + parent::__construct(); + + $CI =& get_instance(); + $CI->load->model("muser"); + $CI->load->model("mfile"); + + } + + public function test_verify_uploaded_files_noFiles() + { + $a = array(); + try { + \service\files::verify_uploaded_files($a); + $this->t->fail("verify should error"); + } catch (\exceptions\UserInputException $e) { + $this->t->is($e->get_error_id(), "file/no-file", "verify should error"); + } + } + + public function test_verify_uploaded_files_normal() + { + $CI =& get_instance(); + $a = array( + array( + "name" => "foobar.txt", + "type" => "text/plain", + "tmp_name" => NULL, + "error" => UPLOAD_ERR_OK, + "size" => 1, + "formfield" => "file[1]", + ) + ); + + \service\files::verify_uploaded_files($a); + $this->t->pass("verify should work"); + } + + public function test_verify_uploaded_files_uploadError() + { + $CI =& get_instance(); + $a = array( + array( + "name" => "foobar.txt", + "type" => "text/plain", + "tmp_name" => NULL, + "error" => UPLOAD_ERR_NO_FILE, + "size" => 1, + "formfield" => "file[1]", + ) + ); + + try { + \service\files::verify_uploaded_files($a); + $this->t->fail("verify should error"); + } catch (\exceptions\UserInputException $e) { + $data = $e->get_data(); + $this->t->is($e->get_error_id(), "file/upload-verify", "verify should error"); + $this->t->is_deeply(array( + 'file[1]' => array( + 'filename' => 'foobar.txt', + 'formfield' => 'file[1]', + 'message' => 'No file was uploaded', + ), + ), $data, "expected data in exception"); + } + } + + +} + diff --git a/application/test/tests/test_service_files_valid_id.php b/application/test/tests/test_service_files_valid_id.php new file mode 100644 index 000000000..24886be43 --- /dev/null +++ b/application/test/tests/test_service_files_valid_id.php @@ -0,0 +1,115 @@ + + * + * Licensed under AGPLv3 + * (see COPYING for full license text) + * + */ + +namespace test\tests; + +class test_service_files_valid_id extends \test\Test { + private $model; + private $filedata; + private $config; + + public function __construct() + { + parent::__construct(); + + $CI =& get_instance(); + $CI->load->model("muser"); + $CI->load->model("mfile"); + + } + + public function init() + { + $this->model = \Mockery::mock("Mfile"); + $this->model->shouldReceive("delete_id")->never()->byDefault(); + $this->model->shouldReceive("delete_data_id")->never()->byDefault(); + $this->model->shouldReceive("file")->with("file-hash-1-1")->andReturn("/invalid/path/file-1")->byDefault(); + $this->model->shouldReceive("filemtime")->with("/invalid/path/file-1")->andReturn(500)->byDefault(); + $this->model->shouldReceive("filesize")->with("/invalid/path/file-1")->andReturn(50*1024)->byDefault(); + $this->model->shouldReceive("file_exists")->with("/invalid/path/file-1")->andReturn(true)->byDefault(); + + $this->filedata = array( + "data_id" => "file-hash-1-1", + "hash" => "file-hash-1", + "id" => "file-id-1", + "user" => 2, + "date" => 500, + ); + + $this->config = array( + "upload_max_age" => 20, + "sess_expiration" => 10, + "small_upload_size" => 10*1024, + ); + } + + public function cleanup() + { + \Mockery::close(); + } + + public function test_valid_id_keepNormalUpload() + { + $ret = \service\files::valid_id($this->filedata, $this->config, $this->model, 505); + $this->t->is($ret, true, "normal case should be valid"); + } + + public function test_valid_id_keepSmallUpload() + { + $this->model->shouldReceive("filesize")->with("/invalid/path/file-1")->once()->andReturn(50); + + $ret = \service\files::valid_id($this->filedata, $this->config, $this->model, 550); + $this->t->is($ret, true, "file is old, but small and should be kept"); + } + + public function test_valid_id_removeOldFile() + { + $this->model->shouldReceive("delete_data_id")->with("file-hash-1-1")->once(); + + $ret = \service\files::valid_id($this->filedata, $this->config, $this->model, 550); + $this->t->is($ret, false, "file is old and should be removed"); + } + + public function test_valid_id_removeOldUpload() + { + $this->model->shouldReceive("delete_id")->with("file-id-1")->once(); + $this->model->shouldReceive("filemtime")->with("/invalid/path/file-1")->once()->andReturn(540); + + $ret = \service\files::valid_id($this->filedata, $this->config, $this->model, 550); + $this->t->is($ret, false, "upload is old and should be removed"); + } + + public function test_valid_id_keepNormalUnownedFile() + { + $this->filedata["user"] = 0; + + $ret = \service\files::valid_id($this->filedata, $this->config, $this->model, 505); + $this->t->is($ret, true, "upload is unowned and should be kept"); + } + + public function test_valid_id_removeOldUnownedFile() + { + $this->model->shouldReceive("delete_id")->with("file-id-1")->once(); + $this->filedata["user"] = 0; + + $ret = \service\files::valid_id($this->filedata, $this->config, $this->model, 515); + $this->t->is($ret, false, "upload is old, unowned and should be removed"); + } + + public function test_valid_id_removeMissingFile() + { + $this->model->shouldReceive("file_exists")->with("/invalid/path/file-1")->once()->andReturn(false); + $this->model->shouldReceive("delete_data_id")->with("file-hash-1-1")->once(); + + $ret = \service\files::valid_id($this->filedata, $this->config, $this->model, 505); + $this->t->is($ret, false, "missing file should be removed"); + } + +} + diff --git a/application/tests/Test.php b/application/tests/Test.php deleted file mode 100644 index c11cd0cc4..000000000 --- a/application/tests/Test.php +++ /dev/null @@ -1,132 +0,0 @@ - - * - * Licensed under AGPLv3 - * (see COPYING for full license text) - * - */ - -namespace tests; - -require_once APPPATH."/third_party/test-more-php/Test-More-OO.php"; - -class TestMore extends \TestMore { - private $TestNamePrefix = ""; - - public function setTestNamePrefix($prefix) { - $this->TestNamePrefix = $prefix; - } - - public function ok ($Result = NULL, $TestName = NULL) { - return parent::ok($Result, $this->TestNamePrefix.$TestName); - } -} - -abstract class Test { - protected $t; - protected $server = ""; - - public function __construct() - { - $this->t = new TestMore(); - $this->t->plan("no_plan"); - } - - public function setServer($server) - { - $this->server = $server; - } - - // Method: POST, PUT, GET etc - // Data: array("param" => "value") ==> index.php?param=value - // Source: http://stackoverflow.com/a/9802854/953022 - protected function CallAPI($method, $url, $data = false) - { - $result = $this->SendHTTPRequest($method, $url, $data); - - $json = json_decode($result, true); - if ($json === NULL) { - $this->t->fail("json decode"); - $this->diagReply($result); - } - - return $json; - } - - protected function SendHTTPRequest($method, $url, $data = false) - { - $curl = curl_init(); - - switch ($method) { - case "POST": - curl_setopt($curl, CURLOPT_POST, 1); - - if ($data) - curl_setopt($curl, CURLOPT_POSTFIELDS, $data); - break; - case "PUT": - curl_setopt($curl, CURLOPT_PUT, 1); - break; - default: - if ($data) - $url = sprintf("%s?%s", $url, http_build_query($data)); - } - - curl_setopt($curl, CURLOPT_URL, $url); - curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); - curl_setopt($curl, CURLOPT_HTTPHEADER, array( - "Accept: application/json", - "Expect: ", - )); - - $result = curl_exec($curl); - - curl_close($curl); - return $result; - } - - protected function excpectStatus($testname, $reply, $status) - { - if (!isset($reply["status"]) || $reply["status"] != $status) { - $this->t->fail($testname); - $this->diagReply($reply); - } else { - $this->t->pass($testname); - } - return $reply; - } - - protected function expectSuccess($testname, $reply) - { - return $this->excpectStatus($testname, $reply, "success"); - } - - protected function expectError($testname, $reply) - { - return $this->excpectStatus($testname, $reply, "error"); - } - - protected function diagReply($reply) - { - $this->t->diag("Request got unexpected response:"); - $this->t->diag(var_export($reply, true)); - } - - public function init() - { - } - - public function cleanup() - { - } - - public function done_testing() - { - $this->t->done_testing(); - } - - public function setTestNamePrefix($prefix) { - $this->t->setTestNamePrefix($prefix); - } -} diff --git a/application/tests/test_api_v1.php b/application/tests/test_api_v1.php deleted file mode 100644 index 378f741de..000000000 --- a/application/tests/test_api_v1.php +++ /dev/null @@ -1,434 +0,0 @@ - - * - * Licensed under AGPLv3 - * (see COPYING for full license text) - * - */ - -namespace tests; - -class test_api_v1 extends Test { - - public function __construct() - { - parent::__construct(); - - $CI =& get_instance(); - $CI->load->model("muser"); - $CI->load->model("mfile"); - - } - - private function uploadFile($apikey, $file) - { - $ret = $this->CallAPI("POST", "$this->server/api/v1.1.0/file/upload", array( - "apikey" => $apikey, - "file[1]" => curl_file_create($file), - )); - $this->expectSuccess("upload file", $ret); - return $ret; - } - - private function createUser($counter) - { - $CI =& get_instance(); - $CI->db->insert("users", array( - 'username' => "testuser-api_v1-$counter", - 'password' => $CI->muser->hash_password("testpass$counter"), - 'email' => "testuser$counter@localhost.invalid", - 'referrer' => NULL - )); - - return $CI->db->insert_id(); - } - - private function createApikey($userid, $access_level = "apikey") - { - return \service\user::create_apikey($userid, "", $access_level); - } - - private function createUserAndApikey($access_level = "apikey") - { - static $counter = 100; - $counter++; - $userid = $this->createUser($counter); - return $this->createApikey($userid, $access_level); - } - - private function callEndpoint($verb, $endpoint, $data) - { - return $this->CallAPI($verb, "$this->server/api/v1.0.0/$endpoint", $data); - } - - public function test_callPrivateEndpointsWithoutApikey() - { - $endpoints = array( - "file/upload", - "file/history", - "file/delete", - "file/create_multipaste", - "user/apikeys", - "user/create_apikey", - "user/delete_apikey", - ); - foreach ($endpoints as $endpoint) { - $ret = $this->CallEndpoint("POST", $endpoint, array( - )); - $this->expectError("call $endpoint without apikey", $ret); - $this->t->is_deeply(array( - 'status' => 'error', - 'error_id' => 'api/not-authenticated', - 'message' => 'Not authenticated. FileBin requires you to have an account, please go to the homepage for more information.', - ), $ret, "expected error"); - } - } - - public function test_callEndpointsWithoutEnoughPermissions() - { - $testconfig = array( - array( - "apikey" => $this->createUserAndApikey('basic'), - "endpoints" => array( - "file/delete", - "file/history", - ), - ), - array( - "apikey" => $this->createUserAndApikey(), - "endpoints" => array( - "user/apikeys", - "user/create_apikey", - "user/delete_apikey", - ), - ), - ); - foreach ($testconfig as $test) { - foreach ($test['endpoints'] as $endpoint) { - $ret = $this->CallEndpoint("POST", $endpoint, array( - "apikey" => $test['apikey'], - )); - $this->expectError("call $endpoint without enough permissions", $ret); - $this->t->is_deeply(array( - 'status' => "error", - 'error_id' => "api/insufficient-permissions", - 'message' => "Access denied: Access level too low", - ), $ret, "expected permission error"); - } - } - } - - public function test_create_apikey_createNewKey() - { - $this->createUser(1); - $ret = $this->CallEndpoint("POST", "user/create_apikey", array( - "username" => "testuser-api_v1-1", - "password" => "testpass1", - "access_level" => "apikey", - "comment" => "main api key", - )); - $this->expectSuccess("create-apikey", $ret); - - $this->t->isnt($ret["data"]["new_key"], "", "apikey not empty"); - } - - public function test_apikeys_getApikey() - { - $userid = $this->createUser(2); - $apikey = $this->createApikey($userid); - $ret = $this->CallEndpoint("POST", "user/apikeys", array( - "username" => "testuser-api_v1-2", - "password" => "testpass2", - )); - $this->expectSuccess("get apikeys", $ret); - - $this->t->is($ret["data"]["apikeys"][$apikey]["key"], $apikey, "expected key 1"); - $this->t->is($ret["data"]["apikeys"][$apikey]["access_level"], "apikey", "expected key 1 acces_level"); - $this->t->is($ret["data"]["apikeys"][$apikey]["comment"], "", "expected key 1 comment"); - $this->t->ok(is_int($ret["data"]["apikeys"][$apikey]["created"]) , "expected key 1 creation time is int"); - } - - public function test_delete_apikey_deleteOwnKey() - { - $apikey = $this->createUserAndApikey("full"); - $ret = $this->CallEndpoint("POST", "user/delete_apikey", array( - "apikey" => $apikey, - "delete_key" => $apikey, - )); - $this->expectSuccess("delete apikey", $ret); - - $this->t->is($ret["data"]["deleted_keys"][$apikey]["key"], $apikey, "expected key"); - } - - public function test_delete_apikey_errorDeleteOtherUserKey() - { - $apikey = $this->createUserAndApikey("full"); - $apikey2 = $this->createUserAndApikey("full"); - $ret = $this->CallEndpoint("POST", "user/delete_apikey", array( - "apikey" => $apikey, - "delete_key" => $apikey2, - )); - $this->expectError("delete apikey of other user", $ret); - $this->t->is_deeply(array( - 'status' => 'error', - 'error_id' => 'user/delete_apikey/failed', - 'message' => 'Apikey deletion failed. Possibly wrong owner.', - ), $ret, "expected error"); - } - - public function test_authentication_invalidPassword() - { - $userid = $this->createUser(3); - $ret = $this->CallEndpoint("POST", "user/apikeys", array( - "username" => "testuser-api_v1-3", - "password" => "wrongpass", - )); - $this->expectError("invalid password", $ret); - - $this->t->is_deeply(array ( - 'status' => 'error', - 'error_id' => 'user/login-failed', - 'message' => 'Login failed', - ), $ret, "expected error"); - } - - public function test_authentication_invalidUser() - { - $userid = $this->createUser(4); - $ret = $this->CallEndpoint("POST", "user/apikeys", array( - "username" => "testuser-api_v1-invalid", - "password" => "testpass4", - )); - $this->expectError("invalid username", $ret); - - $this->t->is_deeply(array ( - 'status' => 'error', - 'error_id' => 'user/login-failed', - 'message' => 'Login failed', - ), $ret, "expected error"); - } - - public function test_history_empty() - { - $apikey = $this->createUserAndApikey(); - $ret = $this->CallEndpoint("POST", "file/history", array( - "apikey" => $apikey, - )); - $this->expectSuccess("get history", $ret); - - $this->t->ok(empty($ret["data"]["items"]), "items key exists and empty"); - $this->t->ok(empty($ret["data"]["multipaste_items"]), "multipaste_items key exists and empty"); - $this->t->is($ret["data"]["total_size"], 0, "total_size = 0 since no uploads"); - } - - public function test_get_config() - { - $ret = $this->CallEndpoint("GET", "file/get_config", array( - )); - $this->expectSuccess("get_config", $ret); - - $this->t->like($ret["data"]["upload_max_size"], '/[0-9]+/', "upload_max_size is int"); - $this->t->like($ret["data"]["max_files_per_request"], '/[0-9]+/', "max_files_per_request is int"); - } - - public function test_upload_uploadFile() - { - $apikey = $this->createUserAndApikey(); - $ret = $this->CallEndpoint("POST", "file/upload", array( - "apikey" => $apikey, - "file[1]" => curl_file_create("data/tests/small-file"), - )); - $this->expectSuccess("upload file", $ret); - - $this->t->ok(!empty($ret["data"]["ids"]), "got IDs"); - $this->t->ok(!empty($ret["data"]["urls"]), "got URLs"); - } - - public function test_upload_uploadFileSameMD5() - { - $apikey = $this->createUserAndApikey(); - $ret = $this->CallEndpoint("POST", "file/upload", array( - "apikey" => $apikey, - "file[1]" => curl_file_create("data/tests/message1.bin"), - "file[2]" => curl_file_create("data/tests/message2.bin"), - )); - $this->expectSuccess("upload file", $ret); - - $this->t->ok(!empty($ret["data"]["ids"]), "got IDs"); - $this->t->ok(!empty($ret["data"]["urls"]), "got URLs"); - - foreach ($ret["data"]["urls"] as $url) { - $data[] = $this->SendHTTPRequest("GET", $url, ''); - } - $this->t->ok($data[0] !== $data[1], 'Returned file contents should differ'); - } - - public function test_upload_uploadNothing() - { - $apikey = $this->createUserAndApikey(); - $ret = $this->CallEndpoint("POST", "file/upload", array( - "apikey" => $apikey, - )); - $this->expectError("upload no file", $ret); - $this->t->is_deeply(array( - 'status' => 'error', - 'error_id' => 'file/no-file', - 'message' => 'No file was uploaded or unknown error occurred.', - ), $ret, "expected reply"); - } - - public function test_history_notEmptyAfterUpload() - { - $apikey = $this->createUserAndApikey(); - $this->uploadFile($apikey, "data/tests/small-file"); - - $ret = $this->CallEndpoint("POST", "file/history", array( - "apikey" => $apikey, - )); - $this->expectSuccess("history not empty after upload", $ret); - - $this->t->ok(!empty($ret["data"]["items"]), "history not empty after upload (items)"); - $this->t->ok(empty($ret["data"]["multipaste_items"]), "didn't upload multipaste"); - $this->t->is($ret["data"]["total_size"], filesize("data/tests/small-file"), "total_size == uploaded file"); - } - - public function test_history_notSharedBetweenUsers() - { - $apikey = $this->createUserAndApikey(); - $apikey2 = $this->createUserAndApikey(); - $this->uploadFile($apikey, "data/tests/small-file"); - - $ret = $this->CallEndpoint("POST", "file/history", array( - "apikey" => $apikey2, - )); - $this->expectSuccess("get history", $ret); - - $this->t->ok(empty($ret["data"]["items"]), "items key exists and empty"); - $this->t->ok(empty($ret["data"]["multipaste_items"]), "multipaste_items key exists and empty"); - $this->t->is($ret["data"]["total_size"], 0, "total_size = 0 since no uploads"); - } - - public function test_delete_canDeleteUploaded() - { - $apikey = $this->createUserAndApikey(); - $ret = $this->uploadFile($apikey, "data/tests/small-file"); - $id = $ret["data"]["ids"][0]; - - $ret = $this->CallEndpoint("POST", "file/delete", array( - "apikey" => $apikey, - "ids[1]" => $id, - )); - $this->expectSuccess("delete uploaded file", $ret); - - $this->t->ok(empty($ret["data"]["errors"]), "no errors"); - $this->t->is_deeply(array( - $id => array( - "id" => $id - ) - ), $ret["data"]["deleted"], "deleted wanted ID"); - $this->t->is($ret["data"]["total_count"], 1, "total_count correct"); - $this->t->is($ret["data"]["deleted_count"], 1, "deleted_count correct"); - } - - public function test_delete_errorIfNotOwner() - { - $apikey = $this->createUserAndApikey(); - $apikey2 = $this->createUserAndApikey(); - $ret = $this->uploadFile($apikey, "data/tests/small-file"); - $id = $ret["data"]["ids"][0]; - - $ret = $this->CallEndpoint("POST", "file/delete", array( - "apikey" => $apikey2, - "ids[1]" => $id, - )); - $this->expectSuccess("delete file of someone else", $ret); - - $this->t->ok(empty($ret["data"]["deleted"]), "not deleted"); - $this->t->is_deeply(array( - $id => array( - "id" => $id, - "reason" => "wrong owner" - ) - ), $ret["data"]["errors"], "error wanted ID"); - $this->t->is($ret["data"]["total_count"], 1, "total_count correct"); - $this->t->is($ret["data"]["deleted_count"], 0, "deleted_count correct"); - } - - public function test_create_multipaste_canCreate() - { - $apikey = $this->createUserAndApikey("basic"); - $ret = $this->uploadFile($apikey, "data/tests/small-file"); - $id = $ret["data"]["ids"][0]; - - $ret = $this->uploadFile($apikey, "data/tests/small-file"); - $id2 = $ret["data"]["ids"][0]; - - $ret = $this->CallEndpoint("POST", "file/create_multipaste", array( - "apikey" => $apikey, - "ids[1]" => $id, - "ids[2]" => $id2, - )); - $this->expectSuccess("create multipaste", $ret); - - $this->t->isnt($ret["data"]["url_id"], "", "got a multipaste ID"); - $this->t->isnt($ret["data"]["url"], "", "got a multipaste URL"); - } - - public function test_create_multipaste_errorOnWrongID() - { - $apikey = $this->createUserAndApikey("basic"); - $ret = $this->uploadFile($apikey, "data/tests/small-file"); - $id = $ret["data"]["ids"][0]; - - $id2 = $id."invalid"; - $ret = $this->CallEndpoint("POST", "file/create_multipaste", array( - "apikey" => $apikey, - "ids[1]" => $id, - "ids[2]" => $id2, - )); - $this->expectError("create multipaste with wrong ID", $ret); - - $this->t->is_deeply(array( - 'status' => 'error', - 'error_id' => 'file/create_multipaste/verify-failed', - 'message' => 'Failed to verify ID(s)', - 'data' => - array ( - $id2 => - array ( - 'id' => $id2, - 'reason' => 'doesn\'t exist', - ), - ), - ), $ret, "expected error response"); - } - - public function test_create_multipaste_errorOnWrongOwner() - { - $apikey = $this->createUserAndApikey("basic"); - $apikey2 = $this->createUserAndApikey("basic"); - $ret = $this->uploadFile($apikey, "data/tests/small-file"); - $id = $ret["data"]["ids"][0]; - - $ret = $this->CallEndpoint("POST", "file/create_multipaste", array( - "apikey" => $apikey2, - "ids[1]" => $id, - )); - $this->expectError("create multipaste with wrong owner", $ret); - - $this->t->is_deeply(array( - 'status' => 'error', - 'error_id' => 'file/create_multipaste/verify-failed', - 'message' => 'Failed to verify ID(s)', - 'data' => - array ( - $id => - array ( - 'id' => $id, - 'reason' => 'not owned by you', - ), - ), - ), $ret, "expected error response"); - } -} diff --git a/application/tests/test_libraries_image.php b/application/tests/test_libraries_image.php deleted file mode 100644 index fb34d794e..000000000 --- a/application/tests/test_libraries_image.php +++ /dev/null @@ -1,38 +0,0 @@ - - * - * Licensed under AGPLv3 - * (see COPYING for full license text) - * - */ - -namespace tests; - -class test_libraries_image extends Test { - - public function __construct() - { - parent::__construct(); - } - - public function init() - { - } - - public function cleanup() - { - } - - public function test_type_supported_normalCase() - { - $this->t->is(\libraries\Image::type_supported('image/png'), true, 'image/png should be supported'); - $this->t->is(\libraries\Image::type_supported('image/jpeg'), true, 'image/jpeg should be supported'); - $this->t->is(\libraries\Image::type_supported('application/pdf'), true, 'application/pdf should be supported'); - - $this->t->is(\libraries\Image::type_supported('application/octet-stream'), false, 'application/octet-stream should not be supported'); - $this->t->is(\libraries\Image::type_supported('text/plain'), false, 'text/plain should not be supported'); - } - -} - diff --git a/application/tests/test_libraries_pygments.php b/application/tests/test_libraries_pygments.php deleted file mode 100644 index f88a4bcbd..000000000 --- a/application/tests/test_libraries_pygments.php +++ /dev/null @@ -1,86 +0,0 @@ - - * - * Licensed under AGPLv3 - * (see COPYING for full license text) - * - */ - -namespace tests; - -class test_libraries_pygments extends Test { - - public function __construct() - { - parent::__construct(); - } - - public function init() - { - } - - public function cleanup() - { - } - - public function test_autodetect_lexer_normalCase() - { - $p = new \libraries\Pygments('/invalid/filepath', 'text/plain', 'stdin'); - $this->t->is($p->autodetect_lexer(), 'text', "text/plain should be text"); - - $p = new \libraries\Pygments('/invalid/filepath', 'application/x-php', 'stdin'); - $this->t->is($p->autodetect_lexer(), 'php', "application/php should be php"); - - // This is from pygments and not our hardcoded list - $p = new \libraries\Pygments('/invalid/filepath', 'text/x-pascal', 'stdin'); - $this->t->is($p->autodetect_lexer(), 'delphi', "text/x-pascal should be delphi"); - - $p = new \libraries\Pygments('/invalid/filepath', 'application/octet-stream', 'stdin'); - $this->t->is($p->autodetect_lexer(), false, "application/octet-stream should return false"); - } - - public function test_autodetect_lexer_specialFilenames() - { - $p = new \libraries\Pygments('/invalid/filepath', 'text/plain', 'foo.c'); - $this->t->is($p->autodetect_lexer(), 'c', "foo.c should be c"); - - $p = new \libraries\Pygments('/invalid/filepath', 'text/plain', 'PKGBUILD'); - $this->t->is($p->autodetect_lexer(), 'bash', "PKGBUILD should be bash"); - } - - public function test_autodetect_lexer_specialFilenamesBinaryShouldNotHighlight() - { - $p = new \libraries\Pygments('/invalid/filepath', 'application/octet-stream', 'foo.c'); - $this->t->is($p->autodetect_lexer(), false, "foo.c should not highlight if binary"); - - $p = new \libraries\Pygments('/invalid/filepath', 'application/octet-stream', 'PKGBUILD'); - $this->t->is($p->autodetect_lexer(), false, "PKGBUILD should not highlight if binary"); - } - - public function test_can_highlight_normalCase() - { - $p = new \libraries\Pygments('/invalid/filepath', 'text/plain', 'stdin'); - $this->t->is($p->can_highlight(), true, "text/plain can highlight"); - - $p = new \libraries\Pygments('/invalid/filepath', 'application/x-php', 'stdin'); - $this->t->is($p->can_highlight(), true, "application/x-php can highlight"); - - $p = new \libraries\Pygments('/invalid/filepath', 'application/octet-stream', 'stdin'); - $this->t->is($p->can_highlight(), false, "application/octet-stream can not highlight"); - } - - public function test_autodetect_lexer_canButShouldntHighlight() - { - $p = new \libraries\Pygments('/invalid/filepath', 'image/svg+xml', 'foo.svg'); - $this->t->is($p->autodetect_lexer(), false, "image/svg+xml should return false"); - } - - public function test_can_highlight_canButShouldntHighlight() - { - $p = new \libraries\Pygments('/invalid/filepath', 'image/svg+xml', 'foo.svg'); - $this->t->is($p->can_highlight(), true, "image/svg+xml can highlight"); - } - -} - diff --git a/application/tests/test_service_files.php b/application/tests/test_service_files.php deleted file mode 100644 index 8789a9888..000000000 --- a/application/tests/test_service_files.php +++ /dev/null @@ -1,85 +0,0 @@ - - * - * Licensed under AGPLv3 - * (see COPYING for full license text) - * - */ - -namespace tests; - -class test_service_files extends Test { - - public function __construct() - { - parent::__construct(); - - $CI =& get_instance(); - $CI->load->model("muser"); - $CI->load->model("mfile"); - - } - - public function test_verify_uploaded_files_noFiles() - { - $a = array(); - try { - \service\files::verify_uploaded_files($a); - $this->t->fail("verify should error"); - } catch (\exceptions\UserInputException $e) { - $this->t->is($e->get_error_id(), "file/no-file", "verify should error"); - } - } - - public function test_verify_uploaded_files_normal() - { - $CI =& get_instance(); - $a = array( - array( - "name" => "foobar.txt", - "type" => "text/plain", - "tmp_name" => NULL, - "error" => UPLOAD_ERR_OK, - "size" => 1, - "formfield" => "file[1]", - ) - ); - - \service\files::verify_uploaded_files($a); - $this->t->pass("verify should work"); - } - - public function test_verify_uploaded_files_uploadError() - { - $CI =& get_instance(); - $a = array( - array( - "name" => "foobar.txt", - "type" => "text/plain", - "tmp_name" => NULL, - "error" => UPLOAD_ERR_NO_FILE, - "size" => 1, - "formfield" => "file[1]", - ) - ); - - try { - \service\files::verify_uploaded_files($a); - $this->t->fail("verify should error"); - } catch (\exceptions\UserInputException $e) { - $data = $e->get_data(); - $this->t->is($e->get_error_id(), "file/upload-verify", "verify should error"); - $this->t->is_deeply(array( - 'file[1]' => array( - 'filename' => 'foobar.txt', - 'formfield' => 'file[1]', - 'message' => 'No file was uploaded', - ), - ), $data, "expected data in exception"); - } - } - - -} - diff --git a/application/tests/test_service_files_valid_id.php b/application/tests/test_service_files_valid_id.php deleted file mode 100644 index c090dcbd9..000000000 --- a/application/tests/test_service_files_valid_id.php +++ /dev/null @@ -1,115 +0,0 @@ - - * - * Licensed under AGPLv3 - * (see COPYING for full license text) - * - */ - -namespace tests; - -class test_service_files_valid_id extends Test { - private $model; - private $filedata; - private $config; - - public function __construct() - { - parent::__construct(); - - $CI =& get_instance(); - $CI->load->model("muser"); - $CI->load->model("mfile"); - - } - - public function init() - { - $this->model = \Mockery::mock("Mfile"); - $this->model->shouldReceive("delete_id")->never()->byDefault(); - $this->model->shouldReceive("delete_data_id")->never()->byDefault(); - $this->model->shouldReceive("file")->with("file-hash-1-1")->andReturn("/invalid/path/file-1")->byDefault(); - $this->model->shouldReceive("filemtime")->with("/invalid/path/file-1")->andReturn(500)->byDefault(); - $this->model->shouldReceive("filesize")->with("/invalid/path/file-1")->andReturn(50*1024)->byDefault(); - $this->model->shouldReceive("file_exists")->with("/invalid/path/file-1")->andReturn(true)->byDefault(); - - $this->filedata = array( - "data_id" => "file-hash-1-1", - "hash" => "file-hash-1", - "id" => "file-id-1", - "user" => 2, - "date" => 500, - ); - - $this->config = array( - "upload_max_age" => 20, - "sess_expiration" => 10, - "small_upload_size" => 10*1024, - ); - } - - public function cleanup() - { - \Mockery::close(); - } - - public function test_valid_id_keepNormalUpload() - { - $ret = \service\files::valid_id($this->filedata, $this->config, $this->model, 505); - $this->t->is($ret, true, "normal case should be valid"); - } - - public function test_valid_id_keepSmallUpload() - { - $this->model->shouldReceive("filesize")->with("/invalid/path/file-1")->once()->andReturn(50); - - $ret = \service\files::valid_id($this->filedata, $this->config, $this->model, 550); - $this->t->is($ret, true, "file is old, but small and should be kept"); - } - - public function test_valid_id_removeOldFile() - { - $this->model->shouldReceive("delete_data_id")->with("file-hash-1-1")->once(); - - $ret = \service\files::valid_id($this->filedata, $this->config, $this->model, 550); - $this->t->is($ret, false, "file is old and should be removed"); - } - - public function test_valid_id_removeOldUpload() - { - $this->model->shouldReceive("delete_id")->with("file-id-1")->once(); - $this->model->shouldReceive("filemtime")->with("/invalid/path/file-1")->once()->andReturn(540); - - $ret = \service\files::valid_id($this->filedata, $this->config, $this->model, 550); - $this->t->is($ret, false, "upload is old and should be removed"); - } - - public function test_valid_id_keepNormalUnownedFile() - { - $this->filedata["user"] = 0; - - $ret = \service\files::valid_id($this->filedata, $this->config, $this->model, 505); - $this->t->is($ret, true, "upload is unowned and should be kept"); - } - - public function test_valid_id_removeOldUnownedFile() - { - $this->model->shouldReceive("delete_id")->with("file-id-1")->once(); - $this->filedata["user"] = 0; - - $ret = \service\files::valid_id($this->filedata, $this->config, $this->model, 515); - $this->t->is($ret, false, "upload is old, unowned and should be removed"); - } - - public function test_valid_id_removeMissingFile() - { - $this->model->shouldReceive("file_exists")->with("/invalid/path/file-1")->once()->andReturn(false); - $this->model->shouldReceive("delete_data_id")->with("file-hash-1-1")->once(); - - $ret = \service\files::valid_id($this->filedata, $this->config, $this->model, 505); - $this->t->is($ret, false, "missing file should be removed"); - } - -} - -- cgit v1.2.3-24-g4f1b