mirror of
https://github.com/appwrite/appwrite.git
synced 2026-05-26 13:51:13 +00:00
Fix request fetching
This commit is contained in:
+95
-14
@@ -152,7 +152,7 @@ abstract class Scope extends TestCase
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use assertLastRequest instead. Used only historically in webhook tests
|
||||
* @deprecated Use getLastRequestForProject instead. Used only historically in webhook tests
|
||||
*/
|
||||
protected function getLastRequest(): array
|
||||
{
|
||||
@@ -163,31 +163,112 @@ abstract class Scope extends TestCase
|
||||
* Get the last webhook request for a specific project.
|
||||
* Polls with retry to handle parallel test race conditions.
|
||||
*/
|
||||
protected function getLastRequestForProject(string $projectId, int $maxAttempts = 10, int $delayMs = 500): array
|
||||
{
|
||||
$hostname = 'request-catcher-webhook';
|
||||
protected function getLastRequestForProject(
|
||||
string $projectId,
|
||||
string $type = self::REQUEST_TYPE_WEBHOOK,
|
||||
array $queryParams = [],
|
||||
int $maxAttempts = 10,
|
||||
int $delayMs = 500,
|
||||
?callable $probe = null
|
||||
): array {
|
||||
$hostname = match ($type) {
|
||||
self::REQUEST_TYPE_WEBHOOK => 'request-catcher-webhook',
|
||||
self::REQUEST_TYPE_SMS => 'request-catcher-sms',
|
||||
default => throw new \Exception('Invalid request catcher type.'),
|
||||
};
|
||||
$enforceProjectId = $type === self::REQUEST_TYPE_WEBHOOK;
|
||||
|
||||
if (empty($queryParams)) {
|
||||
$queryParams = [
|
||||
'header_X-Appwrite-Webhook-Project-Id' => $projectId,
|
||||
];
|
||||
}
|
||||
|
||||
$query = http_build_query($queryParams);
|
||||
|
||||
sleep(2);
|
||||
|
||||
for ($attempt = 0; $attempt < $maxAttempts; $attempt++) {
|
||||
$request = json_decode(file_get_contents('http://' . $hostname . ':5000/__last_request__'), true);
|
||||
if ($request) {
|
||||
$request['data'] = json_decode($request['data'], true);
|
||||
$requests = json_decode(file_get_contents('http://' . $hostname . ':5000/__find_request__?' . $query), true);
|
||||
if (is_array($requests)) {
|
||||
for ($i = count($requests) - 1; $i >= 0; $i--) {
|
||||
$request = $this->decodeRequestData($requests[$i]);
|
||||
if ($probe !== null) {
|
||||
try {
|
||||
$probe($request);
|
||||
return $request;
|
||||
} catch (\Throwable $error) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
$requestProjectId = $request['headers']['X-Appwrite-Webhook-Project-Id'] ?? '';
|
||||
if ($requestProjectId === $projectId) {
|
||||
return $request;
|
||||
if ($enforceProjectId) {
|
||||
$requestProjectId = $request['headers']['X-Appwrite-Webhook-Project-Id'] ?? '';
|
||||
if ($requestProjectId === $projectId) {
|
||||
return $request;
|
||||
}
|
||||
} else {
|
||||
return $request;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
usleep($delayMs * 1000);
|
||||
}
|
||||
|
||||
$request = json_decode(file_get_contents('http://' . $hostname . ':5000/__last_request__'), true);
|
||||
if ($request) {
|
||||
$request['data'] = json_decode($request['data'], true);
|
||||
$requests = json_decode(file_get_contents('http://' . $hostname . ':5000/__find_request__?' . $query), true);
|
||||
if (is_array($requests)) {
|
||||
for ($i = count($requests) - 1; $i >= 0; $i--) {
|
||||
$request = $this->decodeRequestData($requests[$i]);
|
||||
if ($probe !== null) {
|
||||
try {
|
||||
$probe($request);
|
||||
return $request;
|
||||
} catch (\Throwable $error) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if ($enforceProjectId) {
|
||||
$requestProjectId = $request['headers']['X-Appwrite-Webhook-Project-Id'] ?? '';
|
||||
if ($requestProjectId === $projectId) {
|
||||
return $request;
|
||||
}
|
||||
} else {
|
||||
return $request;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $request ?? [];
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
protected function decodeRequestData(array $request): array
|
||||
{
|
||||
if (!array_key_exists('data', $request)) {
|
||||
return $request;
|
||||
}
|
||||
|
||||
if (is_array($request['data'])) {
|
||||
return $request;
|
||||
}
|
||||
|
||||
if (!is_string($request['data']) || $request['data'] === '') {
|
||||
return $request;
|
||||
}
|
||||
|
||||
$decoded = json_decode($request['data'], true);
|
||||
if (json_last_error() === JSON_ERROR_NONE) {
|
||||
$request['data'] = $decoded;
|
||||
return $request;
|
||||
}
|
||||
|
||||
parse_str($request['data'], $parsed);
|
||||
if (!empty($parsed)) {
|
||||
$request['data'] = $parsed;
|
||||
}
|
||||
|
||||
return $request;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -2530,14 +2530,23 @@ class AccountCustomClientTest extends Scope
|
||||
|
||||
$userId = $response['body']['userId'];
|
||||
|
||||
$smsRequest = $this->assertLastRequest(function (array $request) use ($number) {
|
||||
$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);
|
||||
$smsRequest = $this->getLastRequestForProject(
|
||||
$this->getProject()['$id'],
|
||||
Scope::REQUEST_TYPE_SMS,
|
||||
[
|
||||
'header_X-Username' => 'username',
|
||||
'header_X-Key' => 'password',
|
||||
'method' => 'POST',
|
||||
],
|
||||
probe: function (array $request) use ($number) {
|
||||
$this->assertEquals('Appwrite Mock Message Sender', $request['headers']['User-Agent'] ?? null);
|
||||
$this->assertEquals('username', $request['headers']['X-Username'] ?? null);
|
||||
$this->assertEquals('password', $request['headers']['X-Key'] ?? null);
|
||||
$this->assertEquals('POST', $request['method'] ?? null);
|
||||
$this->assertEquals('+123456789', $request['data']['from'] ?? null);
|
||||
$this->assertEquals($number, $request['data']['to'] ?? null);
|
||||
}
|
||||
);
|
||||
|
||||
$data['token'] = $smsRequest['data']['message'];
|
||||
$data['id'] = $userId;
|
||||
@@ -2887,15 +2896,30 @@ class AccountCustomClientTest extends Scope
|
||||
|
||||
$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));
|
||||
$phone = $data['phone'] ?? '';
|
||||
$smsQuery = [
|
||||
'header_X-Username' => 'username',
|
||||
'header_X-Key' => 'password',
|
||||
'method' => 'POST',
|
||||
];
|
||||
|
||||
// Ensure we are not using token from last sms login
|
||||
$tokenRecievedAt = $request['time'];
|
||||
$this->assertGreaterThan($tokenCreatedAt, $tokenRecievedAt);
|
||||
}, Scope::REQUEST_TYPE_SMS);
|
||||
$smsRequest = $this->getLastRequestForProject(
|
||||
$this->getProject()['$id'],
|
||||
Scope::REQUEST_TYPE_SMS,
|
||||
$smsQuery,
|
||||
probe: function (array $request) use ($tokenCreatedAt, $phone) {
|
||||
$this->assertArrayHasKey('data', $request);
|
||||
$this->assertArrayHasKey('time', $request);
|
||||
$this->assertArrayHasKey('message', $request['data'], "Last request missing message: " . \json_encode($request));
|
||||
if (!empty($phone)) {
|
||||
$this->assertEquals($phone, $request['data']['to'] ?? null);
|
||||
}
|
||||
|
||||
// Ensure we are not using token from last sms login
|
||||
$tokenRecievedAt = $request['time'];
|
||||
$this->assertGreaterThan($tokenCreatedAt, $tokenRecievedAt);
|
||||
}
|
||||
);
|
||||
|
||||
/**
|
||||
* Test for FAILURE
|
||||
|
||||
Reference in New Issue
Block a user