Consolidate List Users API params
Replace search, limit, offset, cursor, cursorDirection, and orderType params with a single queries param since the Queries V2 change now allows for different types of queries.
This commit is contained in:
parent
753aebccab
commit
f0d66985f7
|
@ -10,6 +10,7 @@ use Appwrite\Event\Audit as EventAudit;
|
|||
use Appwrite\Network\Validator\Email;
|
||||
use Appwrite\Stats\Stats;
|
||||
use Appwrite\Utopia\Database\Validator\CustomId;
|
||||
use Appwrite\Utopia\Database\Validator\Queries\Users;
|
||||
use Appwrite\Utopia\Response;
|
||||
use Utopia\App;
|
||||
use Utopia\Audit\Audit;
|
||||
|
@ -107,43 +108,44 @@ App::get('/v1/users')
|
|||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_USER_LIST)
|
||||
->param('queries', [], new Users(), 'Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/databases#querying-documents). Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' queries are allowed, each ' . APP_LIMIT_ARRAY_ELEMENT_SIZE . ' characters long. You may filter on the following attributes: ' . implode(', ', Users::ALLOWED_ATTRIBUTES), true)
|
||||
->param('search', '', new Text(256), 'Search term to filter your list results. Max length: 256 chars.', true)
|
||||
->param('limit', 25, new Range(0, 100), 'Maximum number of users to return in response. By default will return maximum 25 results. Maximum of 100 results allowed per request.', true)
|
||||
->param('offset', 0, new Range(0, APP_LIMIT_COUNT), 'Offset value. The default value is 0. Use this param to manage pagination. [learn more about pagination](https://appwrite.io/docs/pagination)', true)
|
||||
->param('cursor', '', new UID(), 'ID of the user used as the starting point for the query, excluding the user itself. Should be used for efficient pagination when working with large sets of data. [learn more about pagination](https://appwrite.io/docs/pagination)', true)
|
||||
->param('cursorDirection', Database::CURSOR_AFTER, new WhiteList([Database::CURSOR_AFTER, Database::CURSOR_BEFORE]), 'Direction of the cursor, can be either \'before\' or \'after\'.', true)
|
||||
->param('orderType', Database::ORDER_ASC, new WhiteList([Database::ORDER_ASC, Database::ORDER_DESC], true), 'Order result by ASC or DESC order.', true)
|
||||
->inject('response')
|
||||
->inject('dbForProject')
|
||||
->inject('usage')
|
||||
->action(function (string $search, int $limit, int $offset, string $cursor, string $cursorDirection, string $orderType, Response $response, Database $dbForProject, Stats $usage) {
|
||||
->action(function (array $queries, string $search, Response $response, Database $dbForProject, Stats $usage) {
|
||||
|
||||
$filterQueries = [];
|
||||
$queries = Query::parseQueries($queries);
|
||||
|
||||
if (!empty($search)) {
|
||||
$filterQueries[] = Query::search('search', $search);
|
||||
$queries[] = Query::search('search', $search);
|
||||
}
|
||||
|
||||
$queries = [];
|
||||
$queries[] = Query::limit($limit);
|
||||
$queries[] = Query::offset($offset);
|
||||
$queries[] = $orderType === Database::ORDER_ASC ? Query::orderAsc('') : Query::orderDesc('');
|
||||
if (!empty($cursor)) {
|
||||
$cursorDocument = $dbForProject->getDocument('users', $cursor);
|
||||
// Set default limit
|
||||
$queries[] = Query::limit(25);
|
||||
|
||||
// Get cursor document if there was a cursor query
|
||||
$cursor = Query::getByType($queries, Query::TYPE_CURSORAFTER, Query::TYPE_CURSORBEFORE)[0] ?? null;
|
||||
if ($cursor !== null) {
|
||||
/** @var Query $cursor */
|
||||
$userId = $cursor->getValue();
|
||||
$cursorDocument = $dbForProject->getDocument('users', $userId);
|
||||
|
||||
if ($cursorDocument->isEmpty()) {
|
||||
throw new Exception(Exception::GENERAL_CURSOR_NOT_FOUND, "User '{$cursor}' for the 'cursor' value not found.");
|
||||
throw new Exception(Exception::GENERAL_CURSOR_NOT_FOUND, "User '{$userId}' for the 'cursor' value not found.");
|
||||
}
|
||||
|
||||
$queries[] = $cursorDirection === Database::CURSOR_AFTER ? Query::cursorAfter($cursorDocument) : Query::cursorBefore($cursorDocument);
|
||||
$cursor->setValue($cursorDocument);
|
||||
}
|
||||
|
||||
$filterQueries = Query::groupByType($queries)['filters'];
|
||||
|
||||
$usage
|
||||
->setParam('users.read', 1)
|
||||
;
|
||||
|
||||
$response->dynamic(new Document([
|
||||
'users' => $dbForProject->find('users', \array_merge($filterQueries, $queries)),
|
||||
'users' => $dbForProject->find('users', $queries),
|
||||
'total' => $dbForProject->count('users', $filterQueries, APP_LIMIT_COUNT),
|
||||
]), Response::MODEL_USER_LIST);
|
||||
});
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
<?php
|
||||
|
||||
namespace Appwrite\Utopia\Database\Validator\Queries;
|
||||
|
||||
use Utopia\Config\Config;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Database\Validator\Queries as QueriesValidator;
|
||||
use Utopia\Database\Validator\Query as QueryValidator;
|
||||
|
||||
class Collection extends QueriesValidator
|
||||
{
|
||||
/**
|
||||
* Expression constructor
|
||||
*
|
||||
* @param string $collection
|
||||
* @param string[] $allowedAttributes
|
||||
*/
|
||||
public function __construct(string $collection, array $allowedAttributes)
|
||||
{
|
||||
$collection = Config::getParam('collections', [])[$collection];
|
||||
// array for constant lookup time
|
||||
$allowedAttributesLookup = [];
|
||||
foreach ($allowedAttributes as $attribute) {
|
||||
$allowedAttributesLookup[$attribute] = true;
|
||||
}
|
||||
|
||||
$attributes = [];
|
||||
foreach ($collection['attributes'] as $attribute) {
|
||||
$key = $attribute['$id'];
|
||||
if (!isset($allowedAttributesLookup[$key])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$attributes[] = new Document([
|
||||
'key' => $key,
|
||||
'type' => $attribute['type'],
|
||||
'array' => $attribute['array'],
|
||||
]);
|
||||
}
|
||||
|
||||
$indexes = [];
|
||||
foreach ($allowedAttributes as $attribute) {
|
||||
$indexes[] = new Document([
|
||||
'status' => 'available',
|
||||
'type' => Database::INDEX_KEY,
|
||||
'attributes' => [$attribute]
|
||||
]);
|
||||
}
|
||||
$indexes[] = new Document([
|
||||
'status' => 'available',
|
||||
'type' => Database::INDEX_FULLTEXT,
|
||||
'attributes' => ['search']
|
||||
]);
|
||||
|
||||
parent::__construct(new QueryValidator($attributes), $attributes, $indexes, true);
|
||||
}
|
||||
}
|
28
src/Appwrite/Utopia/Database/Validator/Queries/Users.php
Normal file
28
src/Appwrite/Utopia/Database/Validator/Queries/Users.php
Normal file
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
namespace Appwrite\Utopia\Database\Validator\Queries;
|
||||
|
||||
use Appwrite\Utopia\Database\Validator\Queries\Collection;
|
||||
|
||||
class Users extends Collection
|
||||
{
|
||||
public const ALLOWED_ATTRIBUTES = [
|
||||
'name',
|
||||
'email',
|
||||
'phone',
|
||||
'status',
|
||||
'passwordUpdate',
|
||||
'registration',
|
||||
'emailVerification',
|
||||
'phoneVerification',
|
||||
];
|
||||
|
||||
/**
|
||||
* Expression constructor
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct('users', self::ALLOWED_ATTRIBUTES);
|
||||
}
|
||||
}
|
|
@ -614,7 +614,7 @@ class AccountCustomClientTest extends Scope
|
|||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey'],
|
||||
], [
|
||||
'search' => $newName
|
||||
'search' => $newName,
|
||||
]);
|
||||
|
||||
$this->assertEquals($response['headers']['status-code'], 200);
|
||||
|
@ -628,7 +628,7 @@ class AccountCustomClientTest extends Scope
|
|||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey'],
|
||||
], [
|
||||
'search' => $id
|
||||
'search' => $id,
|
||||
]);
|
||||
|
||||
$this->assertEquals($response['headers']['status-code'], 200);
|
||||
|
@ -654,7 +654,8 @@ class AccountCustomClientTest extends Scope
|
|||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey'],
|
||||
], [
|
||||
'search' => '"' . $email . '"'
|
||||
'search' => '"' . $email . '"',
|
||||
|
||||
]);
|
||||
|
||||
$this->assertEquals($response['headers']['status-code'], 200);
|
||||
|
@ -668,7 +669,7 @@ class AccountCustomClientTest extends Scope
|
|||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey'],
|
||||
], [
|
||||
'search' => $id
|
||||
'search' => $id,
|
||||
]);
|
||||
|
||||
$this->assertEquals($response['headers']['status-code'], 200);
|
||||
|
|
|
@ -80,11 +80,145 @@ trait UsersBase
|
|||
$this->assertEquals($response['body']['users'][0]['$id'], $data['userId']);
|
||||
$this->assertEquals($response['body']['users'][1]['$id'], 'user1');
|
||||
|
||||
$user1 = $response['body']['users'][1];
|
||||
|
||||
$response = $this->client->call(Client::METHOD_GET, '/users', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'cursor' => $response['body']['users'][0]['$id']
|
||||
'queries' => ['equal("name", "' . $user1['name'] . '")']
|
||||
]);
|
||||
|
||||
$this->assertEquals($response['headers']['status-code'], 200);
|
||||
$this->assertNotEmpty($response['body']);
|
||||
$this->assertNotEmpty($response['body']['users']);
|
||||
$this->assertCount(1, $response['body']['users']);
|
||||
$this->assertEquals($response['body']['users'][0]['name'], $user1['name']);
|
||||
|
||||
$response = $this->client->call(Client::METHOD_GET, '/users', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['equal("email", "' . $user1['email'] . '")']
|
||||
]);
|
||||
|
||||
$this->assertEquals($response['headers']['status-code'], 200);
|
||||
$this->assertNotEmpty($response['body']);
|
||||
$this->assertNotEmpty($response['body']['users']);
|
||||
$this->assertCount(1, $response['body']['users']);
|
||||
$this->assertEquals($response['body']['users'][0]['email'], $user1['email']);
|
||||
|
||||
$response = $this->client->call(Client::METHOD_GET, '/users', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['equal("status", true)']
|
||||
]);
|
||||
|
||||
$this->assertEquals($response['headers']['status-code'], 200);
|
||||
$this->assertNotEmpty($response['body']);
|
||||
$this->assertNotEmpty($response['body']['users']);
|
||||
$this->assertCount(2, $response['body']['users']);
|
||||
$this->assertEquals($response['body']['users'][0]['$id'], $data['userId']);
|
||||
$this->assertEquals($response['body']['users'][0]['status'], $user1['status']);
|
||||
$this->assertEquals($response['body']['users'][1]['$id'], $user1['$id']);
|
||||
$this->assertEquals($response['body']['users'][1]['status'], $user1['status']);
|
||||
|
||||
$response = $this->client->call(Client::METHOD_GET, '/users', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['equal("status", false)']
|
||||
]);
|
||||
|
||||
$this->assertEquals($response['headers']['status-code'], 200);
|
||||
$this->assertNotEmpty($response['body']);
|
||||
$this->assertEmpty($response['body']['users']);
|
||||
$this->assertCount(0, $response['body']['users']);
|
||||
|
||||
$response = $this->client->call(Client::METHOD_GET, '/users', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['equal("passwordUpdate", "' . $user1['passwordUpdate'] . '")']
|
||||
]);
|
||||
|
||||
$this->assertEquals($response['headers']['status-code'], 200);
|
||||
$this->assertNotEmpty($response['body']);
|
||||
$this->assertNotEmpty($response['body']['users']);
|
||||
$this->assertCount(1, $response['body']['users']);
|
||||
$this->assertEquals($response['body']['users'][0]['passwordUpdate'], $user1['passwordUpdate']);
|
||||
|
||||
$response = $this->client->call(Client::METHOD_GET, '/users', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['equal("registration", "' . $user1['registration'] . '")']
|
||||
]);
|
||||
|
||||
$this->assertEquals($response['headers']['status-code'], 200);
|
||||
$this->assertNotEmpty($response['body']);
|
||||
$this->assertNotEmpty($response['body']['users']);
|
||||
$this->assertCount(1, $response['body']['users']);
|
||||
$this->assertEquals($response['body']['users'][0]['registration'], $user1['registration']);
|
||||
|
||||
$response = $this->client->call(Client::METHOD_GET, '/users', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['equal("emailVerification", false)']
|
||||
]);
|
||||
|
||||
$this->assertEquals($response['headers']['status-code'], 200);
|
||||
$this->assertNotEmpty($response['body']);
|
||||
$this->assertNotEmpty($response['body']['users']);
|
||||
$this->assertCount(2, $response['body']['users']);
|
||||
$this->assertEquals($response['body']['users'][0]['$id'], $data['userId']);
|
||||
$this->assertEquals($response['body']['users'][0]['status'], $user1['status']);
|
||||
$this->assertEquals($response['body']['users'][1]['$id'], $user1['$id']);
|
||||
$this->assertEquals($response['body']['users'][1]['status'], $user1['status']);
|
||||
|
||||
$response = $this->client->call(Client::METHOD_GET, '/users', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['equal("emailVerification", true)']
|
||||
]);
|
||||
|
||||
$this->assertEquals($response['headers']['status-code'], 200);
|
||||
$this->assertNotEmpty($response['body']);
|
||||
$this->assertEmpty($response['body']['users']);
|
||||
$this->assertCount(0, $response['body']['users']);
|
||||
|
||||
$response = $this->client->call(Client::METHOD_GET, '/users', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['equal("phoneVerification", false)']
|
||||
]);
|
||||
|
||||
$this->assertEquals($response['headers']['status-code'], 200);
|
||||
$this->assertNotEmpty($response['body']);
|
||||
$this->assertEmpty($response['body']['users']);
|
||||
$this->assertCount(0, $response['body']['users']);
|
||||
|
||||
$response = $this->client->call(Client::METHOD_GET, '/users', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['equal("phoneVerification", true)']
|
||||
]);
|
||||
|
||||
$this->assertEquals($response['headers']['status-code'], 200);
|
||||
$this->assertNotEmpty($response['body']);
|
||||
$this->assertEmpty($response['body']['users']);
|
||||
$this->assertCount(0, $response['body']['users']);
|
||||
|
||||
$response = $this->client->call(Client::METHOD_GET, '/users', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['cursorAfter("' . $data['userId'] . '")']
|
||||
]);
|
||||
|
||||
$this->assertEquals($response['headers']['status-code'], 200);
|
||||
|
@ -97,8 +231,7 @@ trait UsersBase
|
|||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'cursor' => 'user1',
|
||||
'cursorDirection' => Database::CURSOR_BEFORE
|
||||
'queries' => ['cursorBefore("user1")']
|
||||
]);
|
||||
|
||||
$this->assertEquals($response['headers']['status-code'], 200);
|
||||
|
@ -114,7 +247,7 @@ trait UsersBase
|
|||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'search' => 'Ronaldo'
|
||||
'search' => "Ronaldo",
|
||||
]);
|
||||
$this->assertEquals($response['headers']['status-code'], 200);
|
||||
$this->assertNotEmpty($response['body']);
|
||||
|
@ -126,7 +259,7 @@ trait UsersBase
|
|||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'search' => 'cristiano.ronaldo@manchester-united.co.uk'
|
||||
'search' => "cristiano.ronaldo@manchester-united.co.uk",
|
||||
]);
|
||||
$this->assertEquals($response['headers']['status-code'], 200);
|
||||
$this->assertNotEmpty($response['body']);
|
||||
|
@ -138,7 +271,7 @@ trait UsersBase
|
|||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'search' => 'cristiano.ronaldo'
|
||||
'search' => "cristiano.ronaldo",
|
||||
]);
|
||||
$this->assertEquals($response['headers']['status-code'], 200);
|
||||
$this->assertNotEmpty($response['body']);
|
||||
|
@ -150,7 +283,7 @@ trait UsersBase
|
|||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'search' => 'manchester'
|
||||
'search' => "manchester",
|
||||
]);
|
||||
$this->assertEquals($response['headers']['status-code'], 200);
|
||||
$this->assertNotEmpty($response['body']);
|
||||
|
@ -162,7 +295,7 @@ trait UsersBase
|
|||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'search' => 'united.co.uk'
|
||||
'search' => "united.co.uk",
|
||||
]);
|
||||
|
||||
$this->assertEquals($response['headers']['status-code'], 200);
|
||||
|
@ -176,7 +309,7 @@ trait UsersBase
|
|||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'search' => 'man'
|
||||
'search' => "man",
|
||||
]);
|
||||
|
||||
$this->assertEquals($response['headers']['status-code'], 200);
|
||||
|
@ -190,7 +323,7 @@ trait UsersBase
|
|||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'search' => $data['userId']
|
||||
'search' => $data['userId'],
|
||||
]);
|
||||
|
||||
$this->assertEquals($response['headers']['status-code'], 200);
|
||||
|
@ -206,7 +339,7 @@ trait UsersBase
|
|||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'cursor' => 'unknown'
|
||||
'queries' => ['cursorAfter("unknown")']
|
||||
]);
|
||||
|
||||
$this->assertEquals(400, $response['headers']['status-code']);
|
||||
|
@ -297,7 +430,7 @@ trait UsersBase
|
|||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'search' => $newName
|
||||
'search' => $newName,
|
||||
]);
|
||||
|
||||
$this->assertEquals($response['headers']['status-code'], 200);
|
||||
|
@ -310,7 +443,7 @@ trait UsersBase
|
|||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'search' => $id
|
||||
'search' => $id,
|
||||
]);
|
||||
|
||||
$this->assertEquals($response['headers']['status-code'], 200);
|
||||
|
@ -364,7 +497,7 @@ trait UsersBase
|
|||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'search' => $newEmail
|
||||
'search' => $newEmail,
|
||||
]);
|
||||
|
||||
$this->assertEquals($response['headers']['status-code'], 200);
|
||||
|
@ -377,7 +510,7 @@ trait UsersBase
|
|||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'search' => $id
|
||||
'search' => $id,
|
||||
]);
|
||||
|
||||
$this->assertEquals($response['headers']['status-code'], 200);
|
||||
|
@ -565,7 +698,7 @@ trait UsersBase
|
|||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'offset' => 1
|
||||
'queries' => ['offset(1)']
|
||||
]);
|
||||
|
||||
$this->assertEquals($logs['headers']['status-code'], 200);
|
||||
|
@ -576,8 +709,10 @@ trait UsersBase
|
|||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'offset' => 1,
|
||||
'limit' => 1
|
||||
'queries' => [
|
||||
'offset(1)',
|
||||
'limit(1)',
|
||||
]
|
||||
]);
|
||||
|
||||
$this->assertEquals($logs['headers']['status-code'], 200);
|
||||
|
|
Loading…
Reference in a new issue