mirror of
https://github.com/appwrite/appwrite
synced 2026-05-24 09:28:40 +00:00
Refactor avatar screenshot handling and add comprehensive tests for various header and parameter validations
This commit is contained in:
parent
6cc5d1595d
commit
f35b80ba1a
2 changed files with 292 additions and 11 deletions
|
|
@ -23,7 +23,6 @@ use Utopia\Fetch\Client;
|
|||
use Utopia\Image\Image;
|
||||
use Utopia\Logger\Logger;
|
||||
use Utopia\System\System;
|
||||
use Utopia\Validator\AnyOf;
|
||||
use Utopia\Validator\Assoc;
|
||||
use Utopia\Validator\Boolean;
|
||||
use Utopia\Validator\HexColor;
|
||||
|
|
@ -699,16 +698,11 @@ App::get('/v1/avatars/screenshot')
|
|||
$client->setTimeout(30);
|
||||
$client->addHeader('content-type', Client::CONTENT_TYPE_APPLICATION_JSON);
|
||||
|
||||
// Ensure headers is always an associative array (object)
|
||||
if (!is_array($headers)) {
|
||||
// Convert indexed array to empty array (should not happen due to Assoc validator)
|
||||
if (is_array($headers) && count($headers) > 0 && array_keys($headers) === range(0, count($headers) - 1)) {
|
||||
$headers = [];
|
||||
}
|
||||
|
||||
// Convert to associative array if it's a regular array
|
||||
if (is_array($headers) && array_keys($headers) === range(0, count($headers) - 1)) {
|
||||
$headers = [];
|
||||
}
|
||||
|
||||
|
||||
// Create a new object to ensure proper JSON serialization
|
||||
$headersObject = new \stdClass();
|
||||
foreach ($headers as $key => $value) {
|
||||
|
|
@ -725,12 +719,12 @@ App::get('/v1/avatars/screenshot')
|
|||
'scale' => $scale,
|
||||
'headers' => $headersObject
|
||||
];
|
||||
|
||||
|
||||
// Ensure the entire config is properly serialized as JSON
|
||||
// This is a workaround to ensure headers are sent as an object
|
||||
$configJson = json_encode($config, JSON_FORCE_OBJECT);
|
||||
$configObject = json_decode($configJson, false); // false to keep objects as objects
|
||||
|
||||
|
||||
// Convert back to array for the fetch method, but ensure headers remains an object
|
||||
$config = [
|
||||
'url' => $configObject->url,
|
||||
|
|
|
|||
|
|
@ -558,4 +558,291 @@ trait AvatarsBase
|
|||
$this->assertEquals('PNG', $image->getImageFormat());
|
||||
$this->assertEquals(strlen(\file_get_contents(__DIR__ . '/../../../resources/initials.png')), strlen($response['body']));
|
||||
}
|
||||
|
||||
public function testGetScreenshot(): array
|
||||
{
|
||||
/**
|
||||
* Test for SUCCESS
|
||||
*/
|
||||
$response = $this->client->call(Client::METHOD_GET, '/avatars/screenshot', [
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], [
|
||||
'url' => 'https://appwrite.io',
|
||||
'width' => 800,
|
||||
'height' => 600,
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
$this->assertEquals('image/png', $response['headers']['content-type']);
|
||||
$this->assertNotEmpty($response['body']);
|
||||
|
||||
$response = $this->client->call(Client::METHOD_GET, '/avatars/screenshot', [
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], [
|
||||
'url' => 'https://appwrite.io',
|
||||
'width' => 800,
|
||||
'height' => 600,
|
||||
'headers' => [
|
||||
'User-Agent' => 'Mozilla/5.0 (compatible; AppwriteBot/1.0)',
|
||||
'Accept' => 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8'
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
$this->assertEquals('image/png', $response['headers']['content-type']);
|
||||
$this->assertNotEmpty($response['body']);
|
||||
|
||||
/**
|
||||
* Test for FAILURE - Invalid headers parameter types
|
||||
*/
|
||||
|
||||
// Test with string headers (should fail)
|
||||
$response = $this->client->call(Client::METHOD_GET, '/avatars/screenshot', [
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], [
|
||||
'url' => 'https://appwrite.io',
|
||||
'width' => 800,
|
||||
'height' => 600,
|
||||
'headers' => 'invalid-headers-string',
|
||||
]);
|
||||
$this->assertEquals(400, $response['headers']['status-code']);
|
||||
|
||||
// Test with numeric headers (should fail)
|
||||
$response = $this->client->call(Client::METHOD_GET, '/avatars/screenshot', [
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], [
|
||||
'url' => 'https://appwrite.io',
|
||||
'width' => 800,
|
||||
'height' => 600,
|
||||
'headers' => 123,
|
||||
]);
|
||||
$this->assertEquals(400, $response['headers']['status-code']);
|
||||
|
||||
// Test with boolean headers (should fail)
|
||||
$response = $this->client->call(Client::METHOD_GET, '/avatars/screenshot', [
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], [
|
||||
'url' => 'https://appwrite.io',
|
||||
'width' => 800,
|
||||
'height' => 600,
|
||||
'headers' => true,
|
||||
]);
|
||||
$this->assertEquals(400, $response['headers']['status-code']);
|
||||
|
||||
// Test with null headers - framework converts null to empty array, so this passes
|
||||
// Skipping this test as null is converted to [] by the framework before validation
|
||||
|
||||
// Test with regular array (indexed array) - should fail
|
||||
$response = $this->client->call(Client::METHOD_GET, '/avatars/screenshot', [
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], [
|
||||
'url' => 'https://appwrite.io',
|
||||
'width' => 800,
|
||||
'height' => 600,
|
||||
'headers' => ['value1', 'value2', 'value3'], // Indexed array
|
||||
]);
|
||||
$this->assertEquals(400, $response['headers']['status-code']);
|
||||
|
||||
// Test with mixed array (some numeric keys) - Assoc validator allows this
|
||||
// Mixed arrays are considered associative by the Assoc validator
|
||||
$response = $this->client->call(Client::METHOD_GET, '/avatars/screenshot', [
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], [
|
||||
'url' => 'https://appwrite.io',
|
||||
'width' => 800,
|
||||
'height' => 600,
|
||||
'headers' => ['User-Agent' => 'MyApp', 'value2', 'Accept' => 'text/html'], // Mixed array
|
||||
]);
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
|
||||
// Test with empty array (should pass - empty associative array)
|
||||
$response = $this->client->call(Client::METHOD_GET, '/avatars/screenshot', [
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], [
|
||||
'url' => 'https://appwrite.io',
|
||||
'width' => 800,
|
||||
'height' => 600,
|
||||
'headers' => [], // Empty associative array should pass
|
||||
]);
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
|
||||
// Test with valid headers object (should pass)
|
||||
$response = $this->client->call(Client::METHOD_GET, '/avatars/screenshot', [
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], [
|
||||
'url' => 'https://appwrite.io',
|
||||
'width' => 800,
|
||||
'height' => 600,
|
||||
'headers' => [
|
||||
'User-Agent' => 'MyApp/1.0',
|
||||
'Accept' => 'text/html,application/xhtml+xml',
|
||||
'Accept-Language' => 'en-US,en;q=0.9'
|
||||
],
|
||||
]);
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
|
||||
// Test with headers containing special characters (should pass)
|
||||
$response = $this->client->call(Client::METHOD_GET, '/avatars/screenshot', [
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], [
|
||||
'url' => 'https://appwrite.io',
|
||||
'width' => 800,
|
||||
'height' => 600,
|
||||
'headers' => [
|
||||
'X-Custom-Header' => 'custom-value',
|
||||
'Authorization' => 'Bearer token123',
|
||||
'Content-Type' => 'application/json'
|
||||
],
|
||||
]);
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
|
||||
/**
|
||||
* Test for FAILURE - Invalid URL parameter
|
||||
*/
|
||||
$response = $this->client->call(Client::METHOD_GET, '/avatars/screenshot', [
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], [
|
||||
'url' => 'invalid-url',
|
||||
'width' => 800,
|
||||
'height' => 600,
|
||||
]);
|
||||
$this->assertEquals(400, $response['headers']['status-code']);
|
||||
|
||||
$response = $this->client->call(Client::METHOD_GET, '/avatars/screenshot', [
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], [
|
||||
'url' => 'ftp://example.com', // Non-HTTP/HTTPS URL
|
||||
'width' => 800,
|
||||
'height' => 600,
|
||||
]);
|
||||
$this->assertEquals(400, $response['headers']['status-code']);
|
||||
|
||||
/**
|
||||
* Test for FAILURE - Invalid viewport parameter
|
||||
*/
|
||||
$response = $this->client->call(Client::METHOD_GET, '/avatars/screenshot', [
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], [
|
||||
'url' => 'https://appwrite.io',
|
||||
'viewport' => 'invalid-viewport',
|
||||
'width' => 800,
|
||||
'height' => 600,
|
||||
]);
|
||||
$this->assertEquals(400, $response['headers']['status-code']);
|
||||
|
||||
$response = $this->client->call(Client::METHOD_GET, '/avatars/screenshot', [
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], [
|
||||
'url' => 'https://appwrite.io',
|
||||
'viewport' => '2000x1000', // Too large
|
||||
'width' => 800,
|
||||
'height' => 600,
|
||||
]);
|
||||
$this->assertEquals(400, $response['headers']['status-code']);
|
||||
|
||||
/**
|
||||
* Test for FAILURE - Invalid width/height parameters
|
||||
*/
|
||||
$response = $this->client->call(Client::METHOD_GET, '/avatars/screenshot', [
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], [
|
||||
'url' => 'https://appwrite.io',
|
||||
'width' => 0, // Invalid width
|
||||
'height' => 600,
|
||||
]);
|
||||
$this->assertEquals(400, $response['headers']['status-code']);
|
||||
|
||||
$response = $this->client->call(Client::METHOD_GET, '/avatars/screenshot', [
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], [
|
||||
'url' => 'https://appwrite.io',
|
||||
'width' => 800,
|
||||
'height' => 3000, // Invalid height
|
||||
]);
|
||||
$this->assertEquals(400, $response['headers']['status-code']);
|
||||
|
||||
/**
|
||||
* Test for FAILURE - Invalid scale parameter
|
||||
*/
|
||||
$response = $this->client->call(Client::METHOD_GET, '/avatars/screenshot', [
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], [
|
||||
'url' => 'https://appwrite.io',
|
||||
'width' => 800,
|
||||
'height' => 600,
|
||||
'scale' => 0.5, // Too small
|
||||
]);
|
||||
$this->assertEquals(400, $response['headers']['status-code']);
|
||||
|
||||
$response = $this->client->call(Client::METHOD_GET, '/avatars/screenshot', [
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], [
|
||||
'url' => 'https://appwrite.io',
|
||||
'width' => 800,
|
||||
'height' => 600,
|
||||
'scale' => 10, // Too large
|
||||
]);
|
||||
$this->assertEquals(400, $response['headers']['status-code']);
|
||||
|
||||
/**
|
||||
* Test for FAILURE - Invalid sleep parameter
|
||||
*/
|
||||
$response = $this->client->call(Client::METHOD_GET, '/avatars/screenshot', [
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], [
|
||||
'url' => 'https://appwrite.io',
|
||||
'width' => 800,
|
||||
'height' => 600,
|
||||
'sleep' => -1, // Negative sleep
|
||||
]);
|
||||
$this->assertEquals(400, $response['headers']['status-code']);
|
||||
|
||||
$response = $this->client->call(Client::METHOD_GET, '/avatars/screenshot', [
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], [
|
||||
'url' => 'https://appwrite.io',
|
||||
'width' => 800,
|
||||
'height' => 600,
|
||||
'sleep' => 15, // Too large
|
||||
]);
|
||||
$this->assertEquals(400, $response['headers']['status-code']);
|
||||
|
||||
/**
|
||||
* Test for FAILURE - Invalid quality parameter
|
||||
*/
|
||||
$response = $this->client->call(Client::METHOD_GET, '/avatars/screenshot', [
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], [
|
||||
'url' => 'https://appwrite.io',
|
||||
'width' => 800,
|
||||
'height' => 600,
|
||||
'quality' => -2, // Too small
|
||||
]);
|
||||
$this->assertEquals(400, $response['headers']['status-code']);
|
||||
|
||||
$response = $this->client->call(Client::METHOD_GET, '/avatars/screenshot', [
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], [
|
||||
'url' => 'https://appwrite.io',
|
||||
'width' => 800,
|
||||
'height' => 600,
|
||||
'quality' => 150, // Too large
|
||||
]);
|
||||
$this->assertEquals(400, $response['headers']['status-code']);
|
||||
|
||||
/**
|
||||
* Test for FAILURE - Invalid output parameter
|
||||
*/
|
||||
$response = $this->client->call(Client::METHOD_GET, '/avatars/screenshot', [
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], [
|
||||
'url' => 'https://appwrite.io',
|
||||
'width' => 800,
|
||||
'height' => 600,
|
||||
'output' => 'invalid-format',
|
||||
]);
|
||||
$this->assertEquals(400, $response['headers']['status-code']);
|
||||
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue