mirror of
https://github.com/appwrite/appwrite
synced 2026-05-23 00:49:02 +00:00
Merge pull request #10066 from appwrite/fix-account-test-flakyness
Fix: flakyness of account tests
This commit is contained in:
commit
718cefdd94
9 changed files with 74 additions and 43 deletions
|
|
@ -36,7 +36,8 @@ App::setMode(System::getEnv('_APP_ENV', App::MODE_TYPE_PRODUCTION));
|
|||
if (!App::isProduction()) {
|
||||
// Allow specific domains to skip public domain validation in dev environment
|
||||
// Useful for existing tests involving webhooks
|
||||
PublicDomain::allow(['request-catcher']);
|
||||
PublicDomain::allow(['request-catcher-sms']);
|
||||
PublicDomain::allow(['request-catcher-webhook']);
|
||||
}
|
||||
$register->set('logger', function () {
|
||||
// Register error logger
|
||||
|
|
|
|||
51
composer.lock
generated
51
composer.lock
generated
|
|
@ -1463,16 +1463,16 @@
|
|||
},
|
||||
{
|
||||
"name": "open-telemetry/sem-conv",
|
||||
"version": "1.32.0",
|
||||
"version": "1.32.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/opentelemetry-php/sem-conv.git",
|
||||
"reference": "16585cc0dbc3032a318e274043454679430d2ebf"
|
||||
"reference": "94daa85ea61a8e2b7e1b0af6be0e875bedda7c22"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/opentelemetry-php/sem-conv/zipball/16585cc0dbc3032a318e274043454679430d2ebf",
|
||||
"reference": "16585cc0dbc3032a318e274043454679430d2ebf",
|
||||
"url": "https://api.github.com/repos/opentelemetry-php/sem-conv/zipball/94daa85ea61a8e2b7e1b0af6be0e875bedda7c22",
|
||||
"reference": "94daa85ea61a8e2b7e1b0af6be0e875bedda7c22",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -1516,7 +1516,7 @@
|
|||
"issues": "https://github.com/open-telemetry/opentelemetry-php/issues",
|
||||
"source": "https://github.com/open-telemetry/opentelemetry-php"
|
||||
},
|
||||
"time": "2025-05-05T03:58:53+00:00"
|
||||
"time": "2025-06-24T02:32:27+00:00"
|
||||
},
|
||||
{
|
||||
"name": "paragonie/constant_time_encoding",
|
||||
|
|
@ -2327,21 +2327,20 @@
|
|||
},
|
||||
{
|
||||
"name": "ramsey/uuid",
|
||||
"version": "4.8.1",
|
||||
"version": "4.9.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/ramsey/uuid.git",
|
||||
"reference": "fdf4dd4e2ff1813111bd0ad58d7a1ddbb5b56c28"
|
||||
"reference": "4e0e23cc785f0724a0e838279a9eb03f28b092a0"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/ramsey/uuid/zipball/fdf4dd4e2ff1813111bd0ad58d7a1ddbb5b56c28",
|
||||
"reference": "fdf4dd4e2ff1813111bd0ad58d7a1ddbb5b56c28",
|
||||
"url": "https://api.github.com/repos/ramsey/uuid/zipball/4e0e23cc785f0724a0e838279a9eb03f28b092a0",
|
||||
"reference": "4e0e23cc785f0724a0e838279a9eb03f28b092a0",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"brick/math": "^0.8.8 || ^0.9 || ^0.10 || ^0.11 || ^0.12 || ^0.13",
|
||||
"ext-json": "*",
|
||||
"php": "^8.0",
|
||||
"ramsey/collection": "^1.2 || ^2.0"
|
||||
},
|
||||
|
|
@ -2400,9 +2399,9 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/ramsey/uuid/issues",
|
||||
"source": "https://github.com/ramsey/uuid/tree/4.8.1"
|
||||
"source": "https://github.com/ramsey/uuid/tree/4.9.0"
|
||||
},
|
||||
"time": "2025-06-01T06:28:46+00:00"
|
||||
"time": "2025-06-25T14:20:11+00:00"
|
||||
},
|
||||
{
|
||||
"name": "spomky-labs/otphp",
|
||||
|
|
@ -3494,16 +3493,16 @@
|
|||
},
|
||||
{
|
||||
"name": "utopia-php/database",
|
||||
"version": "0.71.7",
|
||||
"version": "0.71.8",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/database.git",
|
||||
"reference": "aa0116b2380125907fc18c82662be8e74c54091f"
|
||||
"reference": "7dff6b67a54f1a7f9d3f210db4c6e40d7052b79e"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/database/zipball/aa0116b2380125907fc18c82662be8e74c54091f",
|
||||
"reference": "aa0116b2380125907fc18c82662be8e74c54091f",
|
||||
"url": "https://api.github.com/repos/utopia-php/database/zipball/7dff6b67a54f1a7f9d3f210db4c6e40d7052b79e",
|
||||
"reference": "7dff6b67a54f1a7f9d3f210db4c6e40d7052b79e",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -3544,9 +3543,9 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/database/issues",
|
||||
"source": "https://github.com/utopia-php/database/tree/0.71.7"
|
||||
"source": "https://github.com/utopia-php/database/tree/0.71.8"
|
||||
},
|
||||
"time": "2025-06-17T23:59:10+00:00"
|
||||
"time": "2025-06-26T14:48:17+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/detector",
|
||||
|
|
@ -3943,16 +3942,16 @@
|
|||
},
|
||||
{
|
||||
"name": "utopia-php/messaging",
|
||||
"version": "0.18.0",
|
||||
"version": "0.18.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/messaging.git",
|
||||
"reference": "c151aa5d4d475c788ca15c210b5b2017e21c41d6"
|
||||
"reference": "5d1245207a61d7ca065daddad7ac5f1d5640152f"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/messaging/zipball/c151aa5d4d475c788ca15c210b5b2017e21c41d6",
|
||||
"reference": "c151aa5d4d475c788ca15c210b5b2017e21c41d6",
|
||||
"url": "https://api.github.com/repos/utopia-php/messaging/zipball/5d1245207a61d7ca065daddad7ac5f1d5640152f",
|
||||
"reference": "5d1245207a61d7ca065daddad7ac5f1d5640152f",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -3988,9 +3987,9 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/messaging/issues",
|
||||
"source": "https://github.com/utopia-php/messaging/tree/0.18.0"
|
||||
"source": "https://github.com/utopia-php/messaging/tree/0.18.1"
|
||||
},
|
||||
"time": "2025-05-15T05:00:03+00:00"
|
||||
"time": "2025-06-26T18:26:07+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/migration",
|
||||
|
|
@ -8237,7 +8236,7 @@
|
|||
],
|
||||
"aliases": [],
|
||||
"minimum-stability": "stable",
|
||||
"stability-flags": {},
|
||||
"stability-flags": [],
|
||||
"prefer-stable": false,
|
||||
"prefer-lowest": false,
|
||||
"platform": {
|
||||
|
|
@ -8261,5 +8260,5 @@
|
|||
"platform-overrides": {
|
||||
"php": "8.3"
|
||||
},
|
||||
"plugin-api-version": "2.6.0"
|
||||
"plugin-api-version": "2.3.0"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -323,7 +323,8 @@ services:
|
|||
depends_on:
|
||||
- redis
|
||||
- mariadb
|
||||
- request-catcher
|
||||
- request-catcher-sms
|
||||
- request-catcher-webhook
|
||||
environment:
|
||||
- _APP_ENV
|
||||
- _APP_WORKER_PER_CORE
|
||||
|
|
@ -1075,15 +1076,24 @@ services:
|
|||
networks:
|
||||
- appwrite
|
||||
|
||||
request-catcher: # used mainly for dev tests
|
||||
request-catcher-webhook: # used mainly for dev tests (mock HTTP webhook)
|
||||
image: appwrite/requestcatcher:1.0.0
|
||||
container_name: appwrite-requestcatcher
|
||||
container_name: appwrite-requestcatcher-webhook
|
||||
<<: *x-logging
|
||||
ports:
|
||||
- "9504:5000"
|
||||
networks:
|
||||
- appwrite
|
||||
|
||||
request-catcher-sms: # used mainly for dev tests (mock SMS auth secret)
|
||||
image: appwrite/requestcatcher:1.0.0
|
||||
container_name: appwrite-requestcatcher-sms
|
||||
<<: *x-logging
|
||||
ports:
|
||||
- "9507:5000"
|
||||
networks:
|
||||
- appwrite
|
||||
|
||||
adminer:
|
||||
image: adminer
|
||||
container_name: appwrite-adminer
|
||||
|
|
|
|||
|
|
@ -426,7 +426,7 @@ class Messaging extends Action
|
|||
$credentials = $provider->getAttribute('credentials');
|
||||
|
||||
return match ($provider->getAttribute('provider')) {
|
||||
'mock' => new Mock('username', 'password'),
|
||||
'mock' => (new Mock('username', 'password'))->setEndpoint('http://request-catcher-sms:5000/'),
|
||||
'twilio' => new Twilio(
|
||||
$credentials['accountSid'] ?? '',
|
||||
$credentials['authToken'] ?? '',
|
||||
|
|
|
|||
|
|
@ -188,9 +188,9 @@ class Executor
|
|||
array $headers,
|
||||
float $cpus,
|
||||
int $memory,
|
||||
string $runtimeEntrypoint = '',
|
||||
bool $logging,
|
||||
int $requestTimeout = null
|
||||
string $runtimeEntrypoint = '',
|
||||
?int $requestTimeout = null
|
||||
) {
|
||||
if (empty($headers['host'])) {
|
||||
$headers['host'] = System::getEnv('_APP_DOMAIN', '');
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ class HTTPTest extends Scope
|
|||
'origin' => 'http://localhost',
|
||||
]));
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
$this->assertEquals(200, $response['headers']['status-code'], "Simple GET /robots.txt HTTP request failed: " . \json_encode($response));
|
||||
$this->assertStringContainsString('# robotstxt.org/', $response['body']);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -140,7 +140,7 @@ trait ProjectCustom
|
|||
'teams.*',
|
||||
'users.*'
|
||||
],
|
||||
'url' => 'http://request-catcher:5000/webhook',
|
||||
'url' => 'http://request-catcher-webhook:5000/',
|
||||
'security' => false,
|
||||
]);
|
||||
|
||||
|
|
|
|||
|
|
@ -13,6 +13,9 @@ abstract class Scope extends TestCase
|
|||
use Retryable;
|
||||
use Async;
|
||||
|
||||
public const REQUEST_TYPE_WEBHOOK = 'webhook';
|
||||
public const REQUEST_TYPE_SMS = 'sms';
|
||||
|
||||
protected ?Client $client = null;
|
||||
protected string $endpoint = 'http://localhost/v1';
|
||||
|
||||
|
|
@ -76,10 +79,16 @@ abstract class Scope extends TestCase
|
|||
return [];
|
||||
}
|
||||
|
||||
protected function assertLastRequest(callable $probe, $timeoutMs = 20_000, $waitMs = 500): array
|
||||
protected function assertLastRequest(callable $probe, string $type, $timeoutMs = 20_000, $waitMs = 500): array
|
||||
{
|
||||
$this->assertEventually(function () use (&$request, $probe) {
|
||||
$request = json_decode(file_get_contents('http://request-catcher:5000/__last_request__'), true);
|
||||
$hostname = match ($type) {
|
||||
'webhook' => 'request-catcher-webhook',
|
||||
'sms' => 'request-catcher-sms',
|
||||
default => throw new \Exception('Invalid request catcher type.'),
|
||||
};
|
||||
|
||||
$this->assertEventually(function () use (&$request, $probe, $hostname) {
|
||||
$request = json_decode(file_get_contents('http://' . $hostname . ':5000/__last_request__'), true);
|
||||
$request['data'] = json_decode($request['data'], true);
|
||||
|
||||
call_user_func($probe, $request);
|
||||
|
|
@ -88,11 +97,16 @@ abstract class Scope extends TestCase
|
|||
return $request;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use assertLastRequest instead. Used only historically in webhook tests
|
||||
*/
|
||||
protected function getLastRequest(): array
|
||||
{
|
||||
$hostname = 'request-catcher-webhook';
|
||||
|
||||
sleep(2);
|
||||
|
||||
$request = json_decode(file_get_contents('http://request-catcher:5000/__last_request__'), true);
|
||||
$request = json_decode(file_get_contents('http://' . $hostname . ':5000/__last_request__'), true);
|
||||
$request['data'] = json_decode($request['data'], true);
|
||||
|
||||
return $request;
|
||||
|
|
|
|||
|
|
@ -2065,14 +2065,13 @@ class AccountCustomClientTest extends Scope
|
|||
$userId = $response['body']['userId'];
|
||||
|
||||
$smsRequest = $this->assertLastRequest(function (array $request) use ($number) {
|
||||
$this->assertEquals('http://request-catcher:5000/mock-sms', $request['url']);
|
||||
$this->assertEquals('Appwrite Mock Message Sender', $request['headers']['User-Agent']);
|
||||
$this->assertEquals('username', $request['headers']['X-Username']);
|
||||
$this->assertEquals('password', $request['headers']['X-Key']);
|
||||
$this->assertEquals('POST', $request['method']);
|
||||
$this->assertEquals('+123456789', $request['data']['from']);
|
||||
$this->assertEquals($number, $request['data']['to']);
|
||||
});
|
||||
}, Scope::REQUEST_TYPE_SMS);
|
||||
|
||||
$data['token'] = $smsRequest['data']['message'];
|
||||
$data['id'] = $userId;
|
||||
|
|
@ -2416,13 +2415,21 @@ class AccountCustomClientTest extends Scope
|
|||
|
||||
$this->assertEquals(201, $response['headers']['status-code']);
|
||||
$this->assertNotEmpty($response['body']['$id']);
|
||||
$this->assertNotEmpty($response['body']['$createdAt']);
|
||||
$this->assertEmpty($response['body']['secret']);
|
||||
$this->assertTrue((new DatetimeValidator())->isValid($response['body']['expire']));
|
||||
|
||||
$smsRequest = $this->assertLastRequest(function ($request) {
|
||||
$tokenCreatedAt = $response['body']['$createdAt'];
|
||||
|
||||
$smsRequest = $this->assertLastRequest(function ($request) use ($tokenCreatedAt) {
|
||||
$this->assertArrayHasKey('data', $request);
|
||||
$this->assertArrayHasKey('time', $request);
|
||||
$this->assertArrayHasKey('message', $request['data'], "Last request missing message: " . \json_encode($request));
|
||||
});
|
||||
|
||||
// Ensure we are not using token from last sms login
|
||||
$tokenRecievedAt = $request['time'];
|
||||
$this->assertGreaterThan($tokenCreatedAt, $tokenRecievedAt);
|
||||
}, Scope::REQUEST_TYPE_SMS);
|
||||
|
||||
/**
|
||||
* Test for FAILURE
|
||||
|
|
|
|||
Loading…
Reference in a new issue