Add integration tests for resized user avatars
Even on solid color images the resizing can cause some small artifacts that slightly modify the color of certain pixels. Due to this now the color comparison is no longer strict but fuzzy. Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
This commit is contained in:
parent
2cc22a06b4
commit
1552add4ca
|
@ -133,3 +133,35 @@ Feature: avatar
|
|||
| X-NC-IsCustomAvatar | 0 |
|
||||
And last avatar is a square of size 128
|
||||
And last avatar is not a single color
|
||||
|
||||
|
||||
|
||||
Scenario: get user avatar with a larger size than the original one
|
||||
Given Logging in using web as "user0"
|
||||
And logged in user posts temporary avatar from file "data/coloured-pattern.png"
|
||||
And logged in user crops temporary avatar
|
||||
| x | 384 |
|
||||
| y | 256 |
|
||||
| w | 128 |
|
||||
| h | 128 |
|
||||
When user "user0" gets avatar for user "user0" with size "192"
|
||||
Then The following headers should be set
|
||||
| Content-Type | image/png |
|
||||
| X-NC-IsCustomAvatar | 1 |
|
||||
And last avatar is a square of size 192
|
||||
And last avatar is a single "#FF0000" color
|
||||
|
||||
Scenario: get user avatar with a smaller size than the original one
|
||||
Given Logging in using web as "user0"
|
||||
And logged in user posts temporary avatar from file "data/coloured-pattern.png"
|
||||
And logged in user crops temporary avatar
|
||||
| x | 384 |
|
||||
| y | 256 |
|
||||
| w | 128 |
|
||||
| h | 128 |
|
||||
When user "user0" gets avatar for user "user0" with size "96"
|
||||
Then The following headers should be set
|
||||
| Content-Type | image/png |
|
||||
| X-NC-IsCustomAvatar | 1 |
|
||||
And last avatar is a square of size 96
|
||||
And last avatar is a single "#FF0000" color
|
||||
|
|
|
@ -179,19 +179,50 @@ trait Avatar {
|
|||
* @param string $size
|
||||
*/
|
||||
public function lastAvatarIsASingleColor(string $color) {
|
||||
Assert::assertEquals($color, $this->getColorFromLastAvatar());
|
||||
$expectedColor = $this->hexStringToRgbColor($color);
|
||||
$colorFromLastAvatar = $this->getColorFromLastAvatar();
|
||||
|
||||
Assert::assertTrue($this->isSameColor($expectedColor, $colorFromLastAvatar),
|
||||
$this->rgbColorToHexString($colorFromLastAvatar) . ' does not match expected ' . $color);
|
||||
}
|
||||
|
||||
private function hexStringToRgbColor($hexString) {
|
||||
// Strip initial "#"
|
||||
$hexString = substr($hexString, 1);
|
||||
|
||||
$rgbColorInt = hexdec($hexString);
|
||||
|
||||
// RGBA hex strings are not supported; the given string is assumed to be
|
||||
// an RGB hex string.
|
||||
return [
|
||||
'red' => ($rgbColorInt >> 16) & 0xFF,
|
||||
'green' => ($rgbColorInt >> 8) & 0xFF,
|
||||
'blue' => $rgbColorInt & 0xFF,
|
||||
'alpha' => 0
|
||||
];
|
||||
}
|
||||
|
||||
private function rgbColorToHexString($rgbColor) {
|
||||
$rgbColorInt = ($rgbColor['red'] << 16) + ($rgbColor['green'] << 8) + ($rgbColor['blue']);
|
||||
|
||||
return '#' . str_pad(strtoupper(dechex($rgbColorInt)), 6, '0', STR_PAD_LEFT);
|
||||
}
|
||||
|
||||
private function getColorFromLastAvatar() {
|
||||
$image = imagecreatefromstring($this->lastAvatar);
|
||||
|
||||
$firstPixelColor = imagecolorat($image, 0, 0);
|
||||
$firstPixelColorIndex = imagecolorat($image, 0, 0);
|
||||
$firstPixelColor = imagecolorsforindex($image, $firstPixelColorIndex);
|
||||
|
||||
for ($i = 0; $i < imagesx($image); $i++) {
|
||||
for ($j = 0; $j < imagesx($image); $j++) {
|
||||
$currentPixelColor = imagecolorat($image, $i, $j);
|
||||
$currentPixelColorIndex = imagecolorat($image, $i, $j);
|
||||
$currentPixelColor = imagecolorsforindex($image, $currentPixelColorIndex);
|
||||
|
||||
if ($firstPixelColor !== $currentPixelColor) {
|
||||
// The colors are compared with a small allowed delta, as even
|
||||
// on solid color images the resizing can cause some small
|
||||
// artifacts that slightly modify the color of certain pixels.
|
||||
if (!$this->isSameColor($firstPixelColor, $currentPixelColor)) {
|
||||
imagedestroy($image);
|
||||
|
||||
return null;
|
||||
|
@ -201,8 +232,26 @@ trait Avatar {
|
|||
|
||||
imagedestroy($image);
|
||||
|
||||
// Assume that the image is a truecolor image and thus the index is the
|
||||
// RGB value of the pixel as an integer.
|
||||
return '#' . str_pad(strtoupper(dechex($firstPixelColor)), 6, '0', STR_PAD_LEFT);
|
||||
return $firstPixelColor;
|
||||
}
|
||||
|
||||
private function isSameColor(array $firstColor, array $secondColor, int $allowedDelta = 1) {
|
||||
if ($this->isSameColorComponent($firstColor['red'], $secondColor['red'], $allowedDelta) &&
|
||||
$this->isSameColorComponent($firstColor['green'], $secondColor['green'], $allowedDelta) &&
|
||||
$this->isSameColorComponent($firstColor['blue'], $secondColor['blue'], $allowedDelta) &&
|
||||
$this->isSameColorComponent($firstColor['alpha'], $secondColor['alpha'], $allowedDelta)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private function isSameColorComponent(int $firstColorComponent, int $secondColorComponent, int $allowedDelta) {
|
||||
if ($firstColorComponent >= ($secondColorComponent - $allowedDelta) &&
|
||||
$firstColorComponent <= ($secondColorComponent + $allowedDelta)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue