From b553b43b685f03c8a849d272fbcdd0e8189e6edb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Thu, 3 Dec 2020 13:07:54 +0100 Subject: [PATCH 1/5] Make possible to send requests as anonymous users in integration tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Until now requests always had "auth" headers either for an admin or a regular user, depending on the value of "currentUser". Now, if "currentUser" starts by "anonymous" no "auth" header is sent, which makes possible to also test requests with users not logged in. Signed-off-by: Daniel Calviño Sánchez --- build/integration/features/bootstrap/BasicStructure.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build/integration/features/bootstrap/BasicStructure.php b/build/integration/features/bootstrap/BasicStructure.php index eed0f173ced46..2c08d6ff03304 100644 --- a/build/integration/features/bootstrap/BasicStructure.php +++ b/build/integration/features/bootstrap/BasicStructure.php @@ -178,7 +178,7 @@ public function sendingToWith($verb, $url, $body) { $options = []; if ($this->currentUser === 'admin') { $options['auth'] = $this->adminUser; - } else { + } elseif (strpos($this->currentUser, 'anonymous') !== 0) { $options['auth'] = [$this->currentUser, $this->regularUser]; } $options['headers'] = [ @@ -218,7 +218,7 @@ public function sendingToWithDirectUrl($verb, $url, $body) { $options = []; if ($this->currentUser === 'admin') { $options['auth'] = $this->adminUser; - } else { + } elseif (strpos($this->currentUser, 'anonymous') !== 0) { $options['auth'] = [$this->currentUser, $this->regularUser]; } if ($body instanceof TableNode) { From 184742e6ff1fe27ebc663dd1adff9ae87408d87d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Thu, 3 Dec 2020 13:11:19 +0100 Subject: [PATCH 2/5] Make possible to set body in requesttoken requests in integration tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit "sendingAToWithRequesttoken" needs to be used to test some non OCS endpoints which require the request token to be sent in the request. Now it is possible to specify the body (or, rather, additional contents beside the cookies and the request token) for those requests, as it will be needed for example to upload an avatar. Signed-off-by: Daniel Calviño Sánchez --- .../features/bootstrap/BasicStructure.php | 24 +++++++++++++------ 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/build/integration/features/bootstrap/BasicStructure.php b/build/integration/features/bootstrap/BasicStructure.php index 2c08d6ff03304..4775a23b90265 100644 --- a/build/integration/features/bootstrap/BasicStructure.php +++ b/build/integration/features/bootstrap/BasicStructure.php @@ -307,21 +307,31 @@ public function loggingInUsingWebAs($user) { * @When Sending a :method to :url with requesttoken * @param string $method * @param string $url + * @param TableNode|array|null $body */ - public function sendingAToWithRequesttoken($method, $url) { + public function sendingAToWithRequesttoken($method, $url, $body = null) { $baseUrl = substr($this->baseUrl, 0, -5); + $options = [ + 'cookies' => $this->cookieJar, + 'headers' => [ + 'requesttoken' => $this->requestToken + ], + ]; + + if ($body instanceof TableNode) { + $fd = $body->getRowsHash(); + $options['form_params'] = $fd; + } elseif ($body) { + $options = array_merge($options, $body); + } + $client = new Client(); try { $this->response = $client->request( $method, $baseUrl . $url, - [ - 'cookies' => $this->cookieJar, - 'headers' => [ - 'requesttoken' => $this->requestToken - ] - ] + $options ); } catch (ClientException $e) { $this->response = $e->getResponse(); From 2cc22a06b4d56e1d46d1de45993b3149455c3bb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Thu, 3 Dec 2020 14:19:43 +0100 Subject: [PATCH 3/5] Add integration tests for user avatars MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Daniel Calviño Sánchez --- .drone.yml | 25 +++ build/integration/data/coloured-pattern.png | Bin 0 -> 2447 bytes build/integration/data/green-square-256.png | Bin 0 -> 645 bytes build/integration/features/avatar.feature | 135 ++++++++++++ .../integration/features/bootstrap/Avatar.php | 208 ++++++++++++++++++ .../features/bootstrap/BasicStructure.php | 1 + 6 files changed, 369 insertions(+) create mode 100644 build/integration/data/coloured-pattern.png create mode 100644 build/integration/data/green-square-256.png create mode 100644 build/integration/features/avatar.feature create mode 100644 build/integration/features/bootstrap/Avatar.php diff --git a/.drone.yml b/.drone.yml index aa718998203d5..e9cacb376fc9d 100644 --- a/.drone.yml +++ b/.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 diff --git a/build/integration/data/coloured-pattern.png b/build/integration/data/coloured-pattern.png new file mode 100644 index 0000000000000000000000000000000000000000..cf43787f3fda7b081bb113e6843fa332c4a5108a GIT binary patch literal 2447 zcmeAS@N?(olHy`uVBq!ia0y~yU;#3j7&w@K)a3P@?|>9%fk$L90|U1(2s1Lwnj--e zWH0gbb!C6T!^9&ab9IW|380W{W=KSdbAE1aYF-JD%fR4Vl$uzQnxasiS(2gP?&%wl zqL<1JG>_HO#WAGf*4vwmyayBnSPs@TuS22ImLZ0r zdEy)!i-(lIb7~DNI&@DtZ;mON*vHE ziVP$|GwGp1nwv-nJ9vByHaC$FpAEn$V_-}G>Y%G9cs?`#<`S-nXuG%zVg9HN) w1GTxdF%`+ZNKBgegxUdu;a*yVI>eF~?g#~@|DmDUoS^jK>FVdQ&MBb@061uAZ~y=R literal 0 HcmV?d00001 diff --git a/build/integration/features/avatar.feature b/build/integration/features/avatar.feature new file mode 100644 index 0000000000000..8580471ef5512 --- /dev/null +++ b/build/integration/features/avatar.feature @@ -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 diff --git a/build/integration/features/bootstrap/Avatar.php b/build/integration/features/bootstrap/Avatar.php new file mode 100644 index 0000000000000..215a3386ab8bc --- /dev/null +++ b/build/integration/features/bootstrap/Avatar.php @@ -0,0 +1,208 @@ + + * + * @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 . + * + */ + +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); + } +} diff --git a/build/integration/features/bootstrap/BasicStructure.php b/build/integration/features/bootstrap/BasicStructure.php index 4775a23b90265..ac5530be5a5ea 100644 --- a/build/integration/features/bootstrap/BasicStructure.php +++ b/build/integration/features/bootstrap/BasicStructure.php @@ -44,6 +44,7 @@ trait BasicStructure { use Auth; + use Avatar; use Download; use Mail; use Trashbin; From 1552add4caaa5239e67d416dd75c4d7ca9085419 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Fri, 4 Dec 2020 04:28:51 +0100 Subject: [PATCH 4/5] Add integration tests for resized user avatars MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- build/integration/features/avatar.feature | 32 ++++++++++ .../integration/features/bootstrap/Avatar.php | 63 ++++++++++++++++--- 2 files changed, 88 insertions(+), 7 deletions(-) diff --git a/build/integration/features/avatar.feature b/build/integration/features/avatar.feature index 8580471ef5512..579417844efdf 100644 --- a/build/integration/features/avatar.feature +++ b/build/integration/features/avatar.feature @@ -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 diff --git a/build/integration/features/bootstrap/Avatar.php b/build/integration/features/bootstrap/Avatar.php index 215a3386ab8bc..90cc36067bf7f 100644 --- a/build/integration/features/bootstrap/Avatar.php +++ b/build/integration/features/bootstrap/Avatar.php @@ -179,19 +179,50 @@ public function lastAvatarIsNotASingleColor() { * @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 @@ private function getColorFromLastAvatar() { 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; } } From b4b3276a5be575d6edefca1214c38c2bd0f0b4e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Mon, 7 Dec 2020 01:39:36 +0100 Subject: [PATCH 5/5] Add integration tests for getting guest avatars MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Daniel Calviño Sánchez --- build/integration/features/avatar.feature | 16 ++++++++++++++++ build/integration/features/bootstrap/Avatar.php | 14 ++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/build/integration/features/avatar.feature b/build/integration/features/avatar.feature index 579417844efdf..f7926615c011f 100644 --- a/build/integration/features/avatar.feature +++ b/build/integration/features/avatar.feature @@ -165,3 +165,19 @@ Feature: avatar | X-NC-IsCustomAvatar | 1 | And last avatar is a square of size 96 And last avatar is a single "#FF0000" color + + + + Scenario: get default guest avatar + When user "user0" gets avatar for guest "guest0" + Then The following headers should be set + | Content-Type | image/png | + And last avatar is a square of size 128 + And last avatar is not a single color + + Scenario: get default guest avatar as an anonymous user + When user "anonymous" gets avatar for guest "guest0" + Then The following headers should be set + | Content-Type | image/png | + And last avatar is a square of size 128 + And last avatar is not a single color diff --git a/build/integration/features/bootstrap/Avatar.php b/build/integration/features/bootstrap/Avatar.php index 90cc36067bf7f..388715340c6e5 100644 --- a/build/integration/features/bootstrap/Avatar.php +++ b/build/integration/features/bootstrap/Avatar.php @@ -71,6 +71,20 @@ public function userGetsAvatarForUserWithSize(string $user, string $userAvatar, $this->getLastAvatar(); } + /** + * @When user :user gets avatar for guest :guestAvatar + * + * @param string $user + * @param string $guestAvatar + */ + public function userGetsAvatarForGuest(string $user, string $guestAvatar) { + $this->asAn($user); + $this->sendingToDirectUrl('GET', '/index.php/avatar/guest/' . $guestAvatar . '/128'); + $this->theHTTPStatusCodeShouldBe('201'); + + $this->getLastAvatar(); + } + /** * @When logged in user gets temporary avatar */