From 3291e7e9a1fab328e87746b620506357aab5dcd7 Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Wed, 9 Jul 2025 17:56:40 +0200 Subject: [PATCH 1/4] update TODO --- TODO | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TODO b/TODO index a623fd7..6039309 100644 --- a/TODO +++ b/TODO @@ -50,8 +50,8 @@ - [v] WAC-viewer - [v] CORS for all - [v] Initialize storage +- [v] Notifications - [-] API for storage creation -- [-] Notifications ------ Test suites ----- - [v] webid From 31591e8ab65913029cfd5989bf91edf471449bec Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Wed, 9 Jul 2025 18:37:15 +0200 Subject: [PATCH 2/4] add Server tests --- TODO | 2 +- tests/phpunit/ServerTest.php | 170 +++++++++++++++++++++++++++++++++++ 2 files changed, 171 insertions(+), 1 deletion(-) create mode 100644 tests/phpunit/ServerTest.php diff --git a/TODO b/TODO index 6039309..6dfbdc2 100644 --- a/TODO +++ b/TODO @@ -72,7 +72,7 @@ - [v] Mailer - [v] MailTemplateGenerator - [v] MailTemplates -- [ ] Server +- [v] Server - [ ] StorageServer - [-] SolidNotifications - [-] SolidPubSub diff --git a/tests/phpunit/ServerTest.php b/tests/phpunit/ServerTest.php new file mode 100644 index 0000000..5d31306 --- /dev/null +++ b/tests/phpunit/ServerTest.php @@ -0,0 +1,170 @@ + "world"]); + } + } + + class MockResponse { + public function getStatusCode() { + return 200; + } + public function getBody() { + return new MockBody(); + } + public function getHeaders() { + return [ + "Foo" => ["Bar", "Blah"] + ]; + } + } + + class ServerTest extends \PHPUnit\Framework\TestCase + { + public static $headers = []; + public static $keys; + + protected function setUp(): void + { + $statements = [ + 'DROP TABLE IF EXISTS clients', + 'CREATE TABLE clients ( + clientId VARCHAR(255) NOT NULL PRIMARY KEY, + origin TEXT NOT NULL, + clientData TEXT NOT NULL + )' + ]; + + Db::connect(); + try { + // create tables + foreach($statements as $statement){ + Db::$pdo->exec($statement); + } + } catch(\PDOException $e) { + echo $e->getMessage(); + } + + ClientRegistration::saveClientRegistration([ + "client_id" => "1234", + "origin" => "https://example.com", + "redirect_uris" => ["https://example.com"], + "client_name" => "Client name" + ]); + } + + public function testGenerateKeySet() { + $keys = Server::generateKeySet(); + $this->assertTrue(isset($keys['encryptionKey'])); + $this->assertTrue(isset($keys['publicKey'])); + $this->assertTrue(isset($keys['privateKey'])); + $this->assertMatchesRegularExpression("/BEGIN PUBLIC KEY/", $keys['publicKey']); + $this->assertMatchesRegularExpression("/BEGIN PRIVATE KEY/", $keys['privateKey']); + } + + + public function testGetAuthServer() { + $authServer = Server::getAuthServer(); + $this->assertInstanceOf('\Pdsinterop\Solid\Auth\Server', $authServer); + } + + public function testGetAuthServerConfig() { + $authServerConfig = Server::getAuthServerConfig(); + $this->assertInstanceOf('\Pdsinterop\Solid\Auth\Config', $authServerConfig); + } + + public function testGetConfigClient() { + $configClient = Server::getConfigClient(); + $this->assertInstanceOf('\Pdsinterop\Solid\Auth\Config\Client', $configClient); + } + + public function testGetConfigClientWithGetId() { + $_GET['client_id'] = '1234'; + $configClient = Server::getConfigClient(); + $this->assertInstanceOf('\Pdsinterop\Solid\Auth\Config\Client', $configClient); + } + + public function testGetConfigClientWithPostd() { + $_POST['client_id'] = '1234'; + $configClient = Server::getConfigClient(); + $this->assertInstanceOf('\Pdsinterop\Solid\Auth\Config\Client', $configClient); + } + public function testGetDpop() { + $dpop = Server::getDpop(); + $this->assertInstanceOf('\Pdsinterop\Solid\Auth\Utils\Dpop', $dpop); + } + public function testGetBearer() { + $bearer = Server::getBearer(); + $this->assertInstanceOf('\Pdsinterop\Solid\Auth\Utils\Bearer', $bearer); + } + public function testGetEndpoints() { + $endpoints = Server::getEndpoints(); + $this->assertEquals($endpoints["issuer"], "https://example.com"); + $this->assertEquals($endpoints["jwks_uri"], "https://example.com/jwks/"); + $this->assertEquals($endpoints["check_session_iframe"], "https://example.com/session/"); + $this->assertEquals($endpoints["end_session_endpoint"], "https://example.com/logout/"); + $this->assertEquals($endpoints["authorization_endpoint"], "https://example.com/authorize/"); + $this->assertEquals($endpoints["token_endpoint"], "https://example.com/token/"); + $this->assertEquals($endpoints["userinfo_endpoint"], "https://example.com/userinfo/"); + $this->assertEquals($endpoints["registration_endpoint"], "https://example.com/register/"); + } + + public function testGetKeys() { + $keys = Server::getKeys(); + $this->assertTrue(isset($keys['encryptionKey'])); + $this->assertTrue(isset($keys['publicKey'])); + $this->assertTrue(isset($keys['privateKey'])); + $this->assertMatchesRegularExpression("/BEGIN PUBLIC KEY/", $keys['publicKey']); + $this->assertMatchesRegularExpression("/BEGIN PRIVATE KEY/", $keys['privateKey']); + } + + public function testGetTokenGenerator() { + $tokenGenerator = Server::getTokenGenerator(); + $this->assertInstanceOf('\Pdsinterop\Solid\Auth\TokenGenerator', $tokenGenerator); + } + + public function testRespond() { + $response = new MockResponse(); + ob_start(); + Server::respond($response); + $sentBody = ob_get_contents(); + ob_end_clean(); + $this->assertTrue(in_array("HTTP/1.1 200", ServerTest::$headers)); + $this->assertTrue(in_array("Foo:Bar", ServerTest::$headers)); + $this->assertTrue(in_array("Foo:Blah", ServerTest::$headers)); + + $this->assertEquals($sentBody, "{\n \"Hello\": \"world\"\n}"); + } + } + From c2122cb8c848d1c1be0592a92fd2053ca48f90c2 Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Wed, 9 Jul 2025 19:12:25 +0200 Subject: [PATCH 3/4] add tests for StorageServer --- TODO | 2 +- tests/phpunit/StorageServerTest.php | 161 ++++++++++++++++++++++++++++ 2 files changed, 162 insertions(+), 1 deletion(-) create mode 100644 tests/phpunit/StorageServerTest.php diff --git a/TODO b/TODO index 6dfbdc2..b86f4d5 100644 --- a/TODO +++ b/TODO @@ -73,6 +73,6 @@ - [v] MailTemplateGenerator - [v] MailTemplates - [v] Server -- [ ] StorageServer +- [v] StorageServer - [-] SolidNotifications - [-] SolidPubSub diff --git a/tests/phpunit/StorageServerTest.php b/tests/phpunit/StorageServerTest.php new file mode 100644 index 0000000..980e82b --- /dev/null +++ b/tests/phpunit/StorageServerTest.php @@ -0,0 +1,161 @@ + "world"]); + } + } + + class MockResponse { + public function getStatusCode() { + return 200; + } + public function getBody() { + return new MockBody(); + } + public function getHeaders() { + return [ + "Foo" => ["Bar", "Blah"] + ]; + } + } + + class StorageServerTest extends \PHPUnit\Framework\TestCase + { + public static $headers = []; + public static $createdUser; + + protected function setUp(): void + { + $statements = [ + 'DROP TABLE IF EXISTS allowedClients', + 'DROP TABLE IF EXISTS userStorage', + 'DROP TABLE IF EXISTS users', + 'CREATE TABLE IF NOT EXISTS allowedClients ( + userId VARCHAR(255) NOT NULL PRIMARY KEY, + clientId VARCHAR(255) NOT NULL + )', + 'CREATE TABLE IF NOT EXISTS userStorage ( + userId VARCHAR(255) NOT NULL PRIMARY KEY, + storageUrl VARCHAR(255) NOT NULL + )', + 'CREATE TABLE IF NOT EXISTS users ( + user_id VARCHAR(255) NOT NULL PRIMARY KEY, + email TEXT NOT NULL, + password TEXT NOT NULL, + data TEXT + )', + ]; + + Db::connect(); + try { + // create tables + foreach($statements as $statement){ + Db::$pdo->exec($statement); + } + } catch(\PDOException $e) { + echo $e->getMessage(); + } + + $newUser = [ + "password" => "hello123!@#ABC", + "email" => "alice@example.com", + "hello" => "world" + ]; + self::$createdUser = User::createUser($newUser); + $_SERVER['REQUEST_URI'] = "/test/"; + $_SERVER['REQUEST_SCHEME'] = "https"; + $_SERVER['SERVER_NAME'] = "storage-" . self::$createdUser['userId'] . ".example.com"; + } + + public function testGetFileSystem() { + $filesystem = StorageServer::getFileSystem(); + $this->assertInstanceOf('\League\Flysystem\Filesystem', $filesystem); + } + + + public function testRespond() { + $response = new MockResponse(); + ob_start(); + StorageServer::respond($response); + $sentBody = ob_get_contents(); + ob_end_clean(); + $this->assertTrue(in_array("HTTP/1.1 200", StorageServerTest::$headers)); + $this->assertTrue(in_array("Foo:Bar", StorageServerTest::$headers)); + $this->assertTrue(in_array("Foo:Blah", StorageServerTest::$headers)); + + $this->assertEquals($sentBody, "{\"Hello\":\"world\"}"); + } + + public function testGetOwner() { + $owner = StorageServer::getOwner(); + $this->assertEquals(self::$createdUser['webId'], $owner['webId']); + $this->assertEquals(self::$createdUser['email'], $owner['email']); + } + + public function testGetOwnerWebId() { + $webId = StorageServer::getOwnerWebId(); + $this->assertEquals(self::$createdUser['webId'], $webId); + } + + public function testGenerateDefaultAcl() { + $defaultAcl = StorageServer::generateDefaultAcl(); + $this->assertTrue(strpos($defaultAcl, self::$createdUser['webId']) > 0); + $this->assertMatchesRegularExpression("/@prefix/", $defaultAcl); + } + + public function testGeneratePublicAppendAcl() { + $publicAppendAcl = StorageServer::generatePublicAppendAcl(); + $this->assertTrue(strpos($publicAppendAcl, self::$createdUser['webId']) > 0); + $this->assertMatchesRegularExpression("/@prefix/", $publicAppendAcl); + } + + public function testGeneratePublicReadAcl() { + $publicReadAcl = StorageServer::generatePublicReadAcl(); + $this->assertTrue(strpos($publicReadAcl, self::$createdUser['webId']) > 0); + $this->assertMatchesRegularExpression("/@prefix/", $publicReadAcl); + } + + public function testGenerateDefaultPrivateTypeIndex() { + $privateTypeIndex = StorageServer::generateDefaultPrivateTypeIndex(); + $this->assertTrue(strpos($privateTypeIndex, "UnlistedDocument") > 0); + $this->assertMatchesRegularExpression("/@prefix/", $privateTypeIndex); + } + + public function testGenerateDefaultPublicTypeIndex() { + $publicTypeIndex = StorageServer::generateDefaultPublicTypeIndex(); + $this->assertTrue(strpos($publicTypeIndex, "ListedDocument") > 0); + $this->assertMatchesRegularExpression("/@prefix/", $publicTypeIndex); + } + + public function testGenerateDefaultPreferences() { + $preferences = StorageServer::generateDefaultPreferences(); + $this->assertTrue(strpos($preferences, "ConfigurationFile") > 0); + $this->assertMatchesRegularExpression("/@prefix/", $preferences); + } + + /* + Currently untested: + public static function getWebId($rawRequest) { + public static function initializeStorage() { + */ + } + From 5ec42b41b4fd746f5b3218d57a3ba66006632b4d Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Wed, 9 Jul 2025 19:23:05 +0200 Subject: [PATCH 4/4] move mocks to test-config --- tests/phpunit/MiddlewareTest.php | 7 +--- tests/phpunit/ServerTest.php | 65 +++++------------------------ tests/phpunit/StorageServerTest.php | 37 +--------------- tests/phpunit/test-config.php | 57 ++++++++++++++++++++++++- 4 files changed, 70 insertions(+), 96 deletions(-) diff --git a/tests/phpunit/MiddlewareTest.php b/tests/phpunit/MiddlewareTest.php index 08cf7ec..ca741c6 100644 --- a/tests/phpunit/MiddlewareTest.php +++ b/tests/phpunit/MiddlewareTest.php @@ -1,12 +1,9 @@ "world"]); - } - } - - class MockResponse { - public function getStatusCode() { - return 200; - } - public function getBody() { - return new MockBody(); - } - public function getHeaders() { - return [ - "Foo" => ["Bar", "Blah"] - ]; - } - } - class ServerTest extends \PHPUnit\Framework\TestCase { public static $headers = []; @@ -130,14 +85,14 @@ public function testGetBearer() { } public function testGetEndpoints() { $endpoints = Server::getEndpoints(); - $this->assertEquals($endpoints["issuer"], "https://example.com"); - $this->assertEquals($endpoints["jwks_uri"], "https://example.com/jwks/"); - $this->assertEquals($endpoints["check_session_iframe"], "https://example.com/session/"); - $this->assertEquals($endpoints["end_session_endpoint"], "https://example.com/logout/"); - $this->assertEquals($endpoints["authorization_endpoint"], "https://example.com/authorize/"); - $this->assertEquals($endpoints["token_endpoint"], "https://example.com/token/"); - $this->assertEquals($endpoints["userinfo_endpoint"], "https://example.com/userinfo/"); - $this->assertEquals($endpoints["registration_endpoint"], "https://example.com/register/"); + $this->assertEquals($endpoints["issuer"], "https://solid.example.com"); + $this->assertEquals($endpoints["jwks_uri"], "https://solid.example.com/jwks/"); + $this->assertEquals($endpoints["check_session_iframe"], "https://solid.example.com/session/"); + $this->assertEquals($endpoints["end_session_endpoint"], "https://solid.example.com/logout/"); + $this->assertEquals($endpoints["authorization_endpoint"], "https://solid.example.com/authorize/"); + $this->assertEquals($endpoints["token_endpoint"], "https://solid.example.com/token/"); + $this->assertEquals($endpoints["userinfo_endpoint"], "https://solid.example.com/userinfo/"); + $this->assertEquals($endpoints["registration_endpoint"], "https://solid.example.com/register/"); } public function testGetKeys() { diff --git a/tests/phpunit/StorageServerTest.php b/tests/phpunit/StorageServerTest.php index 980e82b..0de276f 100644 --- a/tests/phpunit/StorageServerTest.php +++ b/tests/phpunit/StorageServerTest.php @@ -1,42 +1,9 @@ "world"]); - } - } - - class MockResponse { - public function getStatusCode() { - return 200; - } - public function getBody() { - return new MockBody(); - } - public function getHeaders() { - return [ - "Foo" => ["Bar", "Blah"] - ]; - } - } + use Pdsinterop\PhpSolid\StorageServer; class StorageServerTest extends \PHPUnit\Framework\TestCase { diff --git a/tests/phpunit/test-config.php b/tests/phpunit/test-config.php index e634ab1..f91f9ac 100644 --- a/tests/phpunit/test-config.php +++ b/tests/phpunit/test-config.php @@ -6,4 +6,59 @@ const BANNED_PASSWORDS = []; const MINIMUM_PASSWORD_ENTROPY = 10; const BASEDOMAIN = "solid.example.com"; -const BASEURL = "https://solid.example.com"; \ No newline at end of file +const BASEURL = "https://solid.example.com"; +const PUBSUB_SERVER = "https://localhost:1234"; +const KEYDIR = "php://memory/"; +const STORAGEBASE = "."; + +function header($header) { + if (class_exists('Pdsinterop\PhpSolid\MiddleWareTest')) { + MiddleWareTest::$headers[] = $header; + } + if (class_exists('Pdsinterop\PhpSolid\ServerTest')) { + ServerTest::$headers[] = $header; + } + if (class_exists('Pdsinterop\PhpSolid\StorageServerTest')) { + StorageServerTest::$headers[] = $header; + } +} + +function file_get_contents($file) { + if (class_exists('Pdsinterop\PhpSolid\ServerTest')) { + if(!isset(ServerTest::$keys)) { + ServerTest::$keys = Server::generateKeySet(); + } + if (preg_match("/encryption/", $file)) { + return ServerTest::$keys['encryptionKey']; + } + if (preg_match("/public/", $file)) { + return ServerTest::$keys['publicKey']; + } + if (preg_match("/private/", $file)) { + return ServerTest::$keys['privateKey']; + } + } +} + +class MockBody { + public function rewind() { + return true; + } + public function getContents() { + return json_encode(["Hello" => "world"]); + } +} + +class MockResponse { + public function getStatusCode() { + return 200; + } + public function getBody() { + return new MockBody(); + } + public function getHeaders() { + return [ + "Foo" => ["Bar", "Blah"] + ]; + } +}