Add integration tests for user avatars
Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
This commit is contained in:
parent
184742e6ff
commit
2cc22a06b4
25
.drone.yml
25
.drone.yml
|
@ -857,6 +857,31 @@ trigger:
|
||||||
- pull_request
|
- pull_request
|
||||||
- push
|
- push
|
||||||
|
|
||||||
|
---
|
||||||
|
kind: pipeline
|
||||||
|
name: integration-avatar
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: submodules
|
||||||
|
image: docker:git
|
||||||
|
commands:
|
||||||
|
- git submodule update --init
|
||||||
|
- name: integration-auth
|
||||||
|
image: nextcloudci/integration-php7.3:integration-php7.3-2
|
||||||
|
commands:
|
||||||
|
- bash tests/drone-run-integration-tests.sh || exit 0
|
||||||
|
- ./occ maintenance:install --admin-pass=admin --data-dir=/dev/shm/nc_int
|
||||||
|
- cd build/integration
|
||||||
|
- ./run.sh features/avatar.feature
|
||||||
|
|
||||||
|
trigger:
|
||||||
|
branch:
|
||||||
|
- master
|
||||||
|
- stable*
|
||||||
|
event:
|
||||||
|
- pull_request
|
||||||
|
- push
|
||||||
|
|
||||||
---
|
---
|
||||||
kind: pipeline
|
kind: pipeline
|
||||||
name: integration-maintenance-mode
|
name: integration-maintenance-mode
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 2.4 KiB |
Binary file not shown.
After Width: | Height: | Size: 645 B |
|
@ -0,0 +1,135 @@
|
||||||
|
Feature: avatar
|
||||||
|
|
||||||
|
Background:
|
||||||
|
Given user "user0" exists
|
||||||
|
|
||||||
|
Scenario: get default user avatar
|
||||||
|
When user "user0" gets avatar for user "user0"
|
||||||
|
Then The following headers should be set
|
||||||
|
| Content-Type | image/png |
|
||||||
|
| X-NC-IsCustomAvatar | 0 |
|
||||||
|
And last avatar is a square of size 128
|
||||||
|
And last avatar is not a single color
|
||||||
|
|
||||||
|
Scenario: get default user avatar as an anonymous user
|
||||||
|
When user "anonymous" gets avatar for user "user0"
|
||||||
|
Then The following headers should be set
|
||||||
|
| Content-Type | image/png |
|
||||||
|
| X-NC-IsCustomAvatar | 0 |
|
||||||
|
And last avatar is a square of size 128
|
||||||
|
And last avatar is not a single color
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Scenario: get temporary user avatar before cropping it
|
||||||
|
Given Logging in using web as "user0"
|
||||||
|
And logged in user posts temporary avatar from file "data/green-square-256.png"
|
||||||
|
When logged in user gets temporary avatar
|
||||||
|
Then The following headers should be set
|
||||||
|
| Content-Type | image/png |
|
||||||
|
# "last avatar" also includes the last temporary avatar
|
||||||
|
And last avatar is a square of size 256
|
||||||
|
And last avatar is a single "#00FF00" color
|
||||||
|
|
||||||
|
Scenario: get user avatar before cropping it
|
||||||
|
Given Logging in using web as "user0"
|
||||||
|
And logged in user posts temporary avatar from file "data/green-square-256.png"
|
||||||
|
# Avatar needs to be cropped to finish setting it even if it is squared
|
||||||
|
When user "user0" gets avatar for user "user0"
|
||||||
|
Then The following headers should be set
|
||||||
|
| Content-Type | image/png |
|
||||||
|
| X-NC-IsCustomAvatar | 0 |
|
||||||
|
And last avatar is a square of size 128
|
||||||
|
And last avatar is not a single color
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Scenario: set user avatar from file
|
||||||
|
Given Logging in using web as "user0"
|
||||||
|
When 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 |
|
||||||
|
Then logged in user gets temporary avatar with 404
|
||||||
|
And user "user0" gets avatar for user "user0"
|
||||||
|
And The following headers should be set
|
||||||
|
| Content-Type | image/png |
|
||||||
|
| X-NC-IsCustomAvatar | 1 |
|
||||||
|
And last avatar is a square of size 128
|
||||||
|
And last avatar is a single "#FF0000" color
|
||||||
|
And user "anonymous" gets avatar for user "user0"
|
||||||
|
And The following headers should be set
|
||||||
|
| Content-Type | image/png |
|
||||||
|
| X-NC-IsCustomAvatar | 1 |
|
||||||
|
And last avatar is a square of size 128
|
||||||
|
And last avatar is a single "#FF0000" color
|
||||||
|
|
||||||
|
Scenario: set user avatar from internal path
|
||||||
|
Given user "user0" uploads file "data/coloured-pattern.png" to "/internal-coloured-pattern.png"
|
||||||
|
And Logging in using web as "user0"
|
||||||
|
When logged in user posts temporary avatar from internal path "internal-coloured-pattern.png"
|
||||||
|
And logged in user crops temporary avatar
|
||||||
|
| x | 704 |
|
||||||
|
| y | 320 |
|
||||||
|
| w | 64 |
|
||||||
|
| h | 64 |
|
||||||
|
Then logged in user gets temporary avatar with 404
|
||||||
|
And user "user0" gets avatar for user "user0" with size "64"
|
||||||
|
And The following headers should be set
|
||||||
|
| Content-Type | image/png |
|
||||||
|
| X-NC-IsCustomAvatar | 1 |
|
||||||
|
And last avatar is a square of size 64
|
||||||
|
And last avatar is a single "#00FF00" color
|
||||||
|
And user "anonymous" gets avatar for user "user0" with size "64"
|
||||||
|
And The following headers should be set
|
||||||
|
| Content-Type | image/png |
|
||||||
|
| X-NC-IsCustomAvatar | 1 |
|
||||||
|
And last avatar is a square of size 64
|
||||||
|
And last avatar is a single "#00FF00" color
|
||||||
|
|
||||||
|
Scenario: cropped user avatar needs to be squared
|
||||||
|
Given Logging in using web as "user0"
|
||||||
|
And logged in user posts temporary avatar from file "data/coloured-pattern.png"
|
||||||
|
When logged in user crops temporary avatar with 400
|
||||||
|
| x | 384 |
|
||||||
|
| y | 256 |
|
||||||
|
| w | 192 |
|
||||||
|
| h | 128 |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Scenario: delete user avatar
|
||||||
|
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 |
|
||||||
|
And user "user0" gets avatar for user "user0"
|
||||||
|
And The following headers should be set
|
||||||
|
| Content-Type | image/png |
|
||||||
|
| X-NC-IsCustomAvatar | 1 |
|
||||||
|
And last avatar is a square of size 128
|
||||||
|
And last avatar is a single "#FF0000" color
|
||||||
|
And user "anonymous" gets avatar for user "user0"
|
||||||
|
And The following headers should be set
|
||||||
|
| Content-Type | image/png |
|
||||||
|
| X-NC-IsCustomAvatar | 1 |
|
||||||
|
And last avatar is a square of size 128
|
||||||
|
And last avatar is a single "#FF0000" color
|
||||||
|
When logged in user deletes the user avatar
|
||||||
|
Then user "user0" gets avatar for user "user0"
|
||||||
|
And The following headers should be set
|
||||||
|
| Content-Type | image/png |
|
||||||
|
| X-NC-IsCustomAvatar | 0 |
|
||||||
|
And last avatar is a square of size 128
|
||||||
|
And last avatar is not a single color
|
||||||
|
And user "anonymous" gets avatar for user "user0"
|
||||||
|
And The following headers should be set
|
||||||
|
| Content-Type | image/png |
|
||||||
|
| X-NC-IsCustomAvatar | 0 |
|
||||||
|
And last avatar is a square of size 128
|
||||||
|
And last avatar is not a single color
|
|
@ -0,0 +1,208 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @copyright Copyright (c) 2020, Daniel Calviño Sánchez (danxuliu@gmail.com)
|
||||||
|
*
|
||||||
|
* @author Daniel Calviño Sánchez <danxuliu@gmail.com>
|
||||||
|
*
|
||||||
|
* @license GNU AGPL version 3 or any later version
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
use Behat\Gherkin\Node\TableNode;
|
||||||
|
use PHPUnit\Framework\Assert;
|
||||||
|
|
||||||
|
require __DIR__ . '/../../vendor/autoload.php';
|
||||||
|
|
||||||
|
trait Avatar {
|
||||||
|
|
||||||
|
/** @var string **/
|
||||||
|
private $lastAvatar;
|
||||||
|
|
||||||
|
/** @AfterScenario **/
|
||||||
|
public function cleanupLastAvatar() {
|
||||||
|
$this->lastAvatar = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getLastAvatar() {
|
||||||
|
$this->lastAvatar = '';
|
||||||
|
|
||||||
|
$body = $this->response->getBody();
|
||||||
|
while (!$body->eof()) {
|
||||||
|
$this->lastAvatar .= $body->read(8192);
|
||||||
|
}
|
||||||
|
$body->close();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @When user :user gets avatar for user :userAvatar
|
||||||
|
*
|
||||||
|
* @param string $user
|
||||||
|
* @param string $userAvatar
|
||||||
|
*/
|
||||||
|
public function userGetsAvatarForUser(string $user, string $userAvatar) {
|
||||||
|
$this->userGetsAvatarForUserWithSize($user, $userAvatar, '128');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @When user :user gets avatar for user :userAvatar with size :size
|
||||||
|
*
|
||||||
|
* @param string $user
|
||||||
|
* @param string $userAvatar
|
||||||
|
* @param string $size
|
||||||
|
*/
|
||||||
|
public function userGetsAvatarForUserWithSize(string $user, string $userAvatar, string $size) {
|
||||||
|
$this->asAn($user);
|
||||||
|
$this->sendingToDirectUrl('GET', '/index.php/avatar/' . $userAvatar . '/' . $size);
|
||||||
|
$this->theHTTPStatusCodeShouldBe('200');
|
||||||
|
|
||||||
|
$this->getLastAvatar();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @When logged in user gets temporary avatar
|
||||||
|
*/
|
||||||
|
public function loggedInUserGetsTemporaryAvatar() {
|
||||||
|
$this->loggedInUserGetsTemporaryAvatarWith('200');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @When logged in user gets temporary avatar with :statusCode
|
||||||
|
*
|
||||||
|
* @param string $statusCode
|
||||||
|
*/
|
||||||
|
public function loggedInUserGetsTemporaryAvatarWith(string $statusCode) {
|
||||||
|
$this->sendingAToWithRequesttoken('GET', '/index.php/avatar/tmp');
|
||||||
|
$this->theHTTPStatusCodeShouldBe($statusCode);
|
||||||
|
|
||||||
|
$this->getLastAvatar();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @When logged in user posts temporary avatar from file :source
|
||||||
|
*
|
||||||
|
* @param string $source
|
||||||
|
*/
|
||||||
|
public function loggedInUserPostsTemporaryAvatarFromFile(string $source) {
|
||||||
|
$file = \GuzzleHttp\Psr7\stream_for(fopen($source, 'r'));
|
||||||
|
|
||||||
|
$this->sendingAToWithRequesttoken('POST', '/index.php/avatar',
|
||||||
|
[
|
||||||
|
'multipart' => [
|
||||||
|
[
|
||||||
|
'name' => 'files[]',
|
||||||
|
'contents' => $file
|
||||||
|
]
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
$this->theHTTPStatusCodeShouldBe('200');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @When logged in user posts temporary avatar from internal path :path
|
||||||
|
*
|
||||||
|
* @param string $path
|
||||||
|
*/
|
||||||
|
public function loggedInUserPostsTemporaryAvatarFromInternalPath(string $path) {
|
||||||
|
$this->sendingAToWithRequesttoken('POST', '/index.php/avatar?path=' . $path);
|
||||||
|
$this->theHTTPStatusCodeShouldBe('200');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @When logged in user crops temporary avatar
|
||||||
|
*
|
||||||
|
* @param TableNode $crop
|
||||||
|
*/
|
||||||
|
public function loggedInUserCropsTemporaryAvatar(TableNode $crop) {
|
||||||
|
$this->loggedInUserCropsTemporaryAvatarWith('200', $crop);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @When logged in user crops temporary avatar with :statusCode
|
||||||
|
*
|
||||||
|
* @param string $statusCode
|
||||||
|
* @param TableNode $crop
|
||||||
|
*/
|
||||||
|
public function loggedInUserCropsTemporaryAvatarWith(string $statusCode, TableNode $crop) {
|
||||||
|
$parameters = [];
|
||||||
|
foreach ($crop->getRowsHash() as $key => $value) {
|
||||||
|
$parameters[] = 'crop[' . $key . ']=' . $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->sendingAToWithRequesttoken('POST', '/index.php/avatar/cropped?' . implode('&', $parameters));
|
||||||
|
$this->theHTTPStatusCodeShouldBe($statusCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @When logged in user deletes the user avatar
|
||||||
|
*/
|
||||||
|
public function loggedInUserDeletesTheUserAvatar() {
|
||||||
|
$this->sendingAToWithRequesttoken('DELETE', '/index.php/avatar');
|
||||||
|
$this->theHTTPStatusCodeShouldBe('200');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Then last avatar is a square of size :size
|
||||||
|
*
|
||||||
|
* @param string size
|
||||||
|
*/
|
||||||
|
public function lastAvatarIsASquareOfSize(string $size) {
|
||||||
|
list($width, $height) = getimagesizefromstring($this->lastAvatar);
|
||||||
|
|
||||||
|
Assert::assertEquals($width, $height, 'Avatar is not a square');
|
||||||
|
Assert::assertEquals($size, $width);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Then last avatar is not a single color
|
||||||
|
*/
|
||||||
|
public function lastAvatarIsNotASingleColor() {
|
||||||
|
Assert::assertEquals(null, $this->getColorFromLastAvatar());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Then last avatar is a single :color color
|
||||||
|
*
|
||||||
|
* @param string $color
|
||||||
|
* @param string $size
|
||||||
|
*/
|
||||||
|
public function lastAvatarIsASingleColor(string $color) {
|
||||||
|
Assert::assertEquals($color, $this->getColorFromLastAvatar());
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getColorFromLastAvatar() {
|
||||||
|
$image = imagecreatefromstring($this->lastAvatar);
|
||||||
|
|
||||||
|
$firstPixelColor = imagecolorat($image, 0, 0);
|
||||||
|
|
||||||
|
for ($i = 0; $i < imagesx($image); $i++) {
|
||||||
|
for ($j = 0; $j < imagesx($image); $j++) {
|
||||||
|
$currentPixelColor = imagecolorat($image, $i, $j);
|
||||||
|
|
||||||
|
if ($firstPixelColor !== $currentPixelColor) {
|
||||||
|
imagedestroy($image);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -44,6 +44,7 @@ require __DIR__ . '/../../vendor/autoload.php';
|
||||||
|
|
||||||
trait BasicStructure {
|
trait BasicStructure {
|
||||||
use Auth;
|
use Auth;
|
||||||
|
use Avatar;
|
||||||
use Download;
|
use Download;
|
||||||
use Mail;
|
use Mail;
|
||||||
use Trashbin;
|
use Trashbin;
|
||||||
|
|
Loading…
Reference in New Issue