From 609a7b275f4736db9b91619bf40df71fe6eccea4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julius=20H=C3=A4rtl?= Date: Wed, 30 Dec 2020 17:02:25 +0100 Subject: [PATCH] Integration tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Julius Härtl --- tests/data/test.txt | 1 + tests/integration/config/behat.yml | 6 +- tests/integration/features/acl.feature | 37 ++-- .../features/bootstrap/BoardContext.php | 125 +++++++++++++ .../features/bootstrap/CardContext.php | 96 ++++++++++ .../features/bootstrap/FeatureContext.php | 174 ------------------ .../features/bootstrap/RequestTrait.php | 127 +++++++++++++ .../features/bootstrap/ServerContext.php | 33 ++++ tests/integration/features/decks.feature | 24 +-- tests/integration/features/sharing.feature | 19 ++ tests/integration/run.sh | 2 +- 11 files changed, 438 insertions(+), 206 deletions(-) create mode 100644 tests/data/test.txt create mode 100644 tests/integration/features/bootstrap/BoardContext.php create mode 100644 tests/integration/features/bootstrap/CardContext.php delete mode 100644 tests/integration/features/bootstrap/FeatureContext.php create mode 100644 tests/integration/features/bootstrap/RequestTrait.php create mode 100644 tests/integration/features/bootstrap/ServerContext.php create mode 100644 tests/integration/features/sharing.feature diff --git a/tests/data/test.txt b/tests/data/test.txt new file mode 100644 index 000000000..802992c42 --- /dev/null +++ b/tests/data/test.txt @@ -0,0 +1 @@ +Hello world diff --git a/tests/integration/config/behat.yml b/tests/integration/config/behat.yml index f557adde8..0c083eca0 100644 --- a/tests/integration/config/behat.yml +++ b/tests/integration/config/behat.yml @@ -4,9 +4,11 @@ default: paths: - '%paths.base%/../features/' contexts: - - FeatureContext: + - ServerContext: baseUrl: http://localhost:8080/index.php/ocs/ admin: - admin - admin - regular_user_password: 123456 \ No newline at end of file + regular_user_password: 123456 + - BoardContext: + baseUrl: http://localhost:8080/ diff --git a/tests/integration/features/acl.feature b/tests/integration/features/acl.feature index 9ee4c1ebe..d431d5b87 100644 --- a/tests/integration/features/acl.feature +++ b/tests/integration/features/acl.feature @@ -10,27 +10,36 @@ Feature: acl And group "group1" exists Given user "user1" belongs to group "group1" - Scenario: Request the main frontend page - Given Logging in using web as "user0" - When Sending a "GET" to "/index.php/apps/deck" without requesttoken - Then the HTTP status code should be "200" - Scenario: Fetch the board list Given Logging in using web as "user0" - When Sending a "GET" to "/index.php/apps/deck/boards" with requesttoken - Then the HTTP status code should be "200" - And the Content-Type should be "application/json; charset=utf-8" + When fetching the board list + Then the response should have a status code "200" + And the response Content-Type should be "application/json; charset=utf-8" Scenario: Fetch board details of owned board Given Logging in using web as "admin" And creates a board named "MyPrivateAdminBoard" with color "fafafa" - When "admin" fetches the board named "MyPrivateAdminBoard" - Then the HTTP status code should be "200" - And the Content-Type should be "application/json; charset=utf-8" + When fetches the board named "MyPrivateAdminBoard" + Then the response should have a status code "200" + And the response Content-Type should be "application/json; charset=utf-8" Scenario: Fetch board details of an other users board Given Logging in using web as "admin" And creates a board named "MyPrivateAdminBoard" with color "fafafa" - When "user0" fetches the board named "MyPrivateAdminBoard" - Then the HTTP status code should be "403" - And the Content-Type should be "application/json; charset=utf-8" \ No newline at end of file + Given Logging in using web as "user0" + When fetches the board named "MyPrivateAdminBoard" + Then the response should have a status code "403" + And the response Content-Type should be "application/json; charset=utf-8" + + Scenario: Share a board + Given Logging in using web as "user0" + And creates a board named "Shared board" with color "fafafa" + And shares the board with user "user1" + Then the HTTP status code should be "200" + Given Logging in using web as "user1" + When fetches the board named "Shared board" + And the current user should have read permissions on the board + And the current user should have write permissions on the board + And the current user should have share permissions on the board + And the current user should have manage permissions on the board + Then the HTTP status code should be "200" diff --git a/tests/integration/features/bootstrap/BoardContext.php b/tests/integration/features/bootstrap/BoardContext.php new file mode 100644 index 000000000..b71ca1d15 --- /dev/null +++ b/tests/integration/features/bootstrap/BoardContext.php @@ -0,0 +1,125 @@ +sendJSONrequest('POST', '/index.php/apps/deck/boards', [ + 'title' => $title, + 'color' => $color + ]); + $this->response->getBody()->seek(0); + $this->board = json_decode((string)$this->response->getBody(), true); + + } + + /** + * @When /^fetches the board named "([^"]*)"$/ + */ + public function fetchesTheBoardNamed($boardName) { + $this->sendJSONrequest('GET', '/index.php/apps/deck/boards/' . $this->board['id'], []); + $this->response->getBody()->seek(0); + $this->board = json_decode((string)$this->response->getBody(), true); + } + + /** + * @When shares the board with user :user + */ + public function sharesTheBoardWithUser($user) + { + $this->sendJSONrequest('POST', '/index.php/apps/deck/boards/' . $this->board['id'] . '/acl', [ + 'type' => 0, + 'participant' => $user, + 'permissionEdit' => true, + 'permissionShare' => true, + 'permissionManage' => true, + ]); + } + + + /** + * @When /^fetching the board list$/ + */ + public function fetchingTheBoardList() { + $this->sendJSONrequest('GET', '/index.php/apps/deck/boards'); + } + + /** + * @When /^fetching the board with id "([^"]*)"$/ + */ + public function fetchingTheBoardWithId($id) { + $this->sendJSONrequest('GET', '/index.php/apps/deck/boards/' . $id); + } + + /** + * @Given /^create a stack named "([^"]*)"$/ + */ + public function createAStackNamed($name) { + $this->sendJSONrequest('POST', '/index.php/apps/deck/stacks', [ + 'title' => $name, + 'boardId' => $this->board['id'] + ]); + $this->response->getBody()->seek(0); + $this->stack = json_decode((string)$this->response->getBody(), true); + } + + /** + * @Given /^create a card named "([^"]*)"$/ + */ + public function createACardNamed($name) { + $this->sendJSONrequest('POST', '/index.php/apps/deck/cards', [ + 'title' => $name, + 'stackId' => $this->stack['id'] + ]); + $this->response->getBody()->seek(0); + $this->card = json_decode((string)$this->response->getBody(), true); + } + + /** + * @Given /^the current user should have read permissions on the board$/ + */ + public function theCurrentUserShouldHaveReadPermissionsOnTheBoard() { + Assert::assertTrue($this->board['permissions']['PERMISSION_READ']); + } + + /** + * @Given /^the current user should have write permissions on the board$/ + */ + public function theCurrentUserShouldHaveWritePermissionsOnTheBoard() { + Assert::assertTrue($this->board['permissions']['PERMISSION_EDIT']); + } + + /** + * @Given /^the current user should have share permissions on the board$/ + */ + public function theCurrentUserShouldHaveSharePermissionsOnTheBoard() { + Assert::assertTrue($this->board['permissions']['PERMISSION_SHARE']); + } + + /** + * @Given /^the current user should have manage permissions on the board$/ + */ + public function theCurrentUserShouldHaveManagePermissionsOnTheBoard() { + Assert::assertTrue($this->board['permissions']['PERMISSION_MANAGE']); + } + +} diff --git a/tests/integration/features/bootstrap/CardContext.php b/tests/integration/features/bootstrap/CardContext.php new file mode 100644 index 000000000..53ae99a1c --- /dev/null +++ b/tests/integration/features/bootstrap/CardContext.php @@ -0,0 +1,96 @@ +sendJSONrequest('POST', '/index.php/apps/deck/boards', [ + 'title' => $title, + 'color' => $color + ]); + $this->response->getBody()->seek(0); + $this->board = json_decode((string)$this->response->getBody(), true); + + } + + /** + * @When /^fetches the board named "([^"]*)"$/ + */ + public function fetchesTheBoardNamed($boardName) { + $this->sendJSONrequest('GET', '/index.php/apps/deck/boards/' . $this->board['id'], []); + $this->response->getBody()->seek(0); + $this->board = json_decode((string)$this->response->getBody(), true); + } + + /** + * @When shares the board with user :user + */ + public function sharesTheBoardWithUser($user) + { + $this->sendJSONrequest('POST', '/index.php/apps/deck/boards/' . $this->board['id'] . '/acl', [ + 'type' => 0, + 'participant' => $user, + 'permissionEdit' => true, + 'permissionShare' => true, + 'permissionManage' => true, + ]); + } + + /** + * @Given /^the current user should have read permissions on the board$/ + */ + public function theCurrentUserShouldHaveReadPermissionsOnTheBoard() { + Assert::assertTrue($this->board['permissions']['PERMISSION_READ']); + } + + /** + * @Given /^the current user should have write permissions on the board$/ + */ + public function theCurrentUserShouldHaveWritePermissionsOnTheBoard() { + Assert::assertTrue($this->board['permissions']['PERMISSION_EDIT']); + } + + /** + * @Given /^the current user should have share permissions on the board$/ + */ + public function theCurrentUserShouldHaveSharePermissionsOnTheBoard() { + Assert::assertTrue($this->board['permissions']['PERMISSION_SHARE']); + } + + /** + * @Given /^the current user should have manage permissions on the board$/ + */ + public function theCurrentUserShouldHaveManagePermissionsOnTheBoard() { + Assert::assertTrue($this->board['permissions']['PERMISSION_MANAGE']); + } + + /** + * @When /^fetching the board list$/ + */ + public function fetchingTheBoardList() { + $this->sendJSONrequest('GET', '/index.php/apps/deck/boards'); + } + + /** + * @When /^fetching the board with id "([^"]*)"$/ + */ + public function fetchingTheBoardWithId($id) { + $this->sendJSONrequest('GET', '/index.php/apps/deck/boards/' . $id); + } + +} diff --git a/tests/integration/features/bootstrap/FeatureContext.php b/tests/integration/features/bootstrap/FeatureContext.php deleted file mode 100644 index a6edbbe53..000000000 --- a/tests/integration/features/bootstrap/FeatureContext.php +++ /dev/null @@ -1,174 +0,0 @@ -sendJSONrequest($method, $url, json_decode($data)); - } - - - /** - * @When :user creates a new deck with name :name - */ - public function createsANewDeckWithName($user, $content) { - $client = new GuzzleHttp\Client(); - $this->response = $client->post( - 'http://localhost:8080/index.php/apps/deck/boards', - [ - 'form_params' => [ - 'name' => $name, - ], - 'auth' => [ - $this->mappedUserId, - 'test', - ], - ] - ); - } - - /** - * @Then the response should have a status code :code - * @param string $code - * @throws InvalidArgumentException - */ - public function theResponseShouldHaveAStatusCode($code) { - $currentCode = $this->response->getStatusCode(); - if ($currentCode !== (int)$code) { - throw new InvalidArgumentException( - sprintf( - 'Expected %s as code got %s', - $code, - $currentCode - ) - ); - } - } - - /** - * @Then the response should be a JSON array with the following mandatory values - * @param TableNode $table - * @throws InvalidArgumentException - */ - public function theResponseShouldBeAJsonArrayWithTheFollowingMandatoryValues(TableNode $table) { - $expectedValues = $table->getColumnsHash(); - $realResponseArray = json_decode($this->response->getBody()->getContents(), true); - - foreach ($expectedValues as $value) { - if ((string)$realResponseArray[$value['key']] !== (string)$value['value']) { - throw new InvalidArgumentException( - sprintf( - 'Expected %s for key %s got %s', - (string)$value['value'], - $value['key'], - (string)$realResponseArray[$value['key']] - ) - ); - } - } - } - - /** - * @Then the response should be a JSON array with a length of :length - * @param int $length - * @throws InvalidArgumentException - */ - public function theResponseShouldBeAJsonArrayWithALengthOf($length) { - $realResponseArray = json_decode($this->response->getBody()->getContents(), true); - PHPUnit_Framework_Assert::assertEquals($realResponseArray, "foo"); - if ((int)count($realResponseArray) !== (int)$length) { - throw new InvalidArgumentException( - sprintf( - 'Expected %d as length got %d', - $length, - count($realResponseArray) - ) - ); - } - } - - /** - * @Then /^I should get:$/ - * - * @param PyStringNode $string - * @throws \Exception - */ - public function iShouldGet(PyStringNode $string) { - if ((string) $string !== trim($this->cliOutput)) { - throw new Exception(sprintf( - 'Expected "%s" but received "%s".', - $string, - $this->cliOutput - )); - } - - return; - } - - private function sendJSONrequest($method, $url, $data) { - $baseUrl = substr($this->baseUrl, 0, -5); - - $client = new Client; - try { - $this->response = $client->request( - $method, - $baseUrl . $url, - [ - 'cookies' => $this->cookieJar, - 'json' => $data, - 'headers' => [ - 'requesttoken' => $this->requestToken - ] - ] - ); - } catch (ClientException $e) { - $this->response = $e->getResponse(); - } - } - - /** - * @Given /^creates a board named "([^"]*)" with color "([^"]*)"$/ - */ - public function createsABoardNamedWithColor($title, $color) { - $this->sendJSONrequest('POST', '/index.php/apps/deck/boards', [ - 'title' => $title, - 'color' => $color - ] - ); - $response = json_decode($this->response->getBody()->getContents(), true); - $this->lastInsertIds[$title] = $response['id']; - } - - /** - * @When /^"([^"]*)" fetches the board named "([^"]*)"$/ - */ - public function fetchesTheBoardNamed($user, $boardName) { - $this->loggingInUsingWebAs($user); - $id = $this->lastInsertIds[$boardName]; - $this->sendJSONrequest('GET', '/index.php/apps/deck/boards/'.$id, []); - } -} diff --git a/tests/integration/features/bootstrap/RequestTrait.php b/tests/integration/features/bootstrap/RequestTrait.php new file mode 100644 index 000000000..cd136fe97 --- /dev/null +++ b/tests/integration/features/bootstrap/RequestTrait.php @@ -0,0 +1,127 @@ +baseUrl = $baseUrl; + $this->adminUser = $admin; + $this->regularUser = $regular_user_password; + } + + /** @var ServerContext */ + private $serverContext; + + /** @BeforeScenario */ + public function gatherContexts(BeforeScenarioScope $scope) + { + $environment = $scope->getEnvironment(); + + $this->serverContext = $environment->getContext('ServerContext'); + } + + /** + * @Then the response should have a status code :code + * @param string $code + * @throws InvalidArgumentException + */ + public function theResponseShouldHaveStatusCode($code) { + $currentCode = $this->response->getStatusCode(); + if ($currentCode !== (int)$code) { + throw new InvalidArgumentException( + sprintf( + 'Expected %s as code got %s', + $code, + $currentCode + ) + ); + } + } + + /** + * @Then /^the response Content-Type should be "([^"]*)"$/ + * @param string $contentType + */ + public function theResponseContentTypeShouldbe($contentType) { + Assert::assertEquals($contentType, $this->response->getHeader('Content-Type')[0]); + } + + /** + * @Then the response should be a JSON array with the following mandatory values + * @param TableNode $table + * @throws InvalidArgumentException + */ + public function theResponseShouldBeAJsonArrayWithTheFollowingMandatoryValues(TableNode $table) { + $this->response->getBody()->seek(0); + $expectedValues = $table->getColumnsHash(); + $realResponseArray = json_decode($this->response->getBody()->getContents(), true); + foreach ($expectedValues as $value) { + if ((string)$realResponseArray[$value['key']] !== (string)$value['value']) { + throw new InvalidArgumentException( + sprintf( + 'Expected %s for key %s got %s', + (string)$value['value'], + $value['key'], + (string)$realResponseArray[$value['key']] + ) + ); + } + } + } + + /** + * @Then the response should be a JSON array with a length of :length + * @param int $length + * @throws InvalidArgumentException + */ + public function theResponseShouldBeAJsonArrayWithALengthOf($length) { + $this->response->getBody()->seek(0); + $realResponseArray = json_decode($this->response->getBody()->getContents(), true); + if ((int)count($realResponseArray) !== (int)$length) { + throw new InvalidArgumentException( + sprintf( + 'Expected %d as length got %d', + $length, + count($realResponseArray) + ) + ); + } + } + + private function sendJSONrequest($method, $url, $data = []) { + + $client = new Client; + try { + $this->response = $client->request( + $method, + $this->baseUrl . $url, + [ + 'cookies' => $this->serverContext->getCookieJar(), + 'json' => $data, + 'headers' => [ + 'requesttoken' => $this->serverContext->getReqestToken() + ] + ] + ); + } catch (ClientException $e) { + $this->response = $e->getResponse(); + } + } +} diff --git a/tests/integration/features/bootstrap/ServerContext.php b/tests/integration/features/bootstrap/ServerContext.php new file mode 100644 index 000000000..2923f93f1 --- /dev/null +++ b/tests/integration/features/bootstrap/ServerContext.php @@ -0,0 +1,33 @@ +cookieJar; + } + + public function getReqestToken(): string { + return $this->requestToken; + } +} diff --git a/tests/integration/features/decks.feature b/tests/integration/features/decks.feature index 405e0b823..3617792b8 100644 --- a/tests/integration/features/decks.feature +++ b/tests/integration/features/decks.feature @@ -10,27 +10,21 @@ Feature: decks Scenario: Fetch the board list Given Logging in using web as "admin" - When Sending a "GET" to "/index.php/apps/deck/boards" with requesttoken - Then the HTTP status code should be "200" - And the Content-Type should be "application/json; charset=utf-8" + When fetching the board list + Then the response should have a status code "200" + And the response Content-Type should be "application/json; charset=utf-8" Scenario: Fetch board details of a nonexisting board Given Logging in using web as "admin" - When Sending a "GET" to "/index.php/apps/deck/boards/13379" with requesttoken - Then the HTTP status code should be "403" - And the Content-Type should be "application/json; charset=utf-8" + When fetching the board with id "99999999" + Then the response should have a status code "403" + And the response Content-Type should be "application/json; charset=utf-8" Scenario: Create a new board Given Logging in using web as "admin" - When Sending a "POST" to "/index.php/apps/deck/boards" with JSON - """ - { - "title": "MyBoard", - "color": "000000" - } - """ - Then the HTTP status code should be "200" - And the Content-Type should be "application/json; charset=utf-8" + When creates a board named "MyBoard" with color "000000" + Then the response should have a status code "200" + And the response Content-Type should be "application/json; charset=utf-8" And the response should be a JSON array with the following mandatory values |key|value| |title|MyBoard| diff --git a/tests/integration/features/sharing.feature b/tests/integration/features/sharing.feature new file mode 100644 index 000000000..3df624e64 --- /dev/null +++ b/tests/integration/features/sharing.feature @@ -0,0 +1,19 @@ +Feature: File sharing + + Background: + Given user "admin" exists + And user "user0" exists + And user "user1" exists + #And user "user2" exists + #Given group "group0" exists + #And group "group1" exists + #Given user "user1" belongs to group "group1" + + Scenario: Share a file with a card + Given Logging in using web as "admin" + And creates a board named "Shared board" with color "fafafa" + And shares the board with user "user1" + Then the HTTP status code should be "200" + Given Logging in using web as "user1" + And create a stack named "Stack" + And create a card named "Test" diff --git a/tests/integration/run.sh b/tests/integration/run.sh index 63a733723..8268f1d0f 100755 --- a/tests/integration/run.sh +++ b/tests/integration/run.sh @@ -36,7 +36,7 @@ echo $PHPPID export TEST_SERVER_URL="http://localhost:$PORT/ocs/" -vendor/bin/behat +vendor/bin/behat $SCENARIO_TO_RUN RESULT=$? kill $PHPPID