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
|
||||
- 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
|
||||
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 {
|
||||
use Auth;
|
||||
use Avatar;
|
||||
use Download;
|
||||
use Mail;
|
||||
use Trashbin;
|
||||
|
|
Loading…
Reference in New Issue