Integration tests

Signed-off-by: Julius Härtl <jus@bitgrid.net>
This commit is contained in:
Julius Härtl
2020-12-30 17:02:25 +01:00
parent db2ceae720
commit 609a7b275f
11 changed files with 438 additions and 206 deletions

View File

@@ -0,0 +1,125 @@
<?php
use Behat\Behat\Context\Context;
use Behat\Gherkin\Node\TableNode;
use GuzzleHttp\Client;
use Behat\Gherkin\Node\PyStringNode;
use GuzzleHttp\Exception\ClientException;
use PHPUnit\Framework\Assert;
require_once __DIR__ . '/../../vendor/autoload.php';
class BoardContext implements Context {
use RequestTrait;
/** @var array Last board response */
private $board = null;
/** @var array last stack response */
private $stack = null;
/** @var array last card response */
private $card = null;
/**
* @Given /^creates a board named "([^"]*)" with color "([^"]*)"$/
*/
public function createsABoardNamedWithColor($title, $color) {
$this->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']);
}
}

View File

@@ -0,0 +1,96 @@
<?php
use Behat\Behat\Context\Context;
use Behat\Gherkin\Node\TableNode;
use GuzzleHttp\Client;
use Behat\Gherkin\Node\PyStringNode;
use GuzzleHttp\Exception\ClientException;
use PHPUnit\Framework\Assert;
require_once __DIR__ . '/../../vendor/autoload.php';
class BoardContext implements Context {
use RequestTrait;
/** @var array Last board response */
private $board = null;
/**
* @Given /^creates a board named "([^"]*)" with color "([^"]*)"$/
*/
public function createsABoardNamedWithColor($title, $color) {
$this->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);
}
}

View File

@@ -1,174 +0,0 @@
<?php
use Behat\Behat\Context\Context;
use Behat\Gherkin\Node\TableNode;
use GuzzleHttp\Client;
use Behat\Gherkin\Node\PyStringNode;
use GuzzleHttp\Exception\ClientException;
require_once __DIR__ . '/../../vendor/autoload.php';
class FeatureContext implements Context {
use WebDav;
/** @var string */
private $mappedUserId;
private $lastInsertIds = [];
/**
* @BeforeSuite
*/
public static function addFilesToSkeleton() {
}
/**
* @When :user requests the deck list
*/
/**
* @When Sending a :method to :url with JSON
*/
public function sendingAToWithJSON($method, $url, \Behat\Gherkin\Node\PyStringNode $data) {
$this->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, []);
}
}

View File

@@ -0,0 +1,127 @@
<?php
use Behat\Behat\Context\Context;
use Behat\Behat\Hook\Scope\BeforeScenarioScope;
use Behat\Gherkin\Node\TableNode;
use GuzzleHttp\Client;
use Behat\Gherkin\Node\PyStringNode;
use GuzzleHttp\Cookie\CookieJar;
use GuzzleHttp\Exception\ClientException;
use PHPUnit\Framework\Assert;
require_once __DIR__ . '/../../vendor/autoload.php';
trait RequestTrait {
private $baseUrl;
private $adminUser;
private $regularUser;
private $cookieJar;
private $response;
public function __construct($baseUrl, $admin = 'admin', $regular_user_password = '123456') {
$this->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();
}
}
}

View File

@@ -0,0 +1,33 @@
<?php
use Behat\Behat\Context\Context;
use Behat\Gherkin\Node\TableNode;
use GuzzleHttp\Client;
use Behat\Gherkin\Node\PyStringNode;
use GuzzleHttp\Cookie\CookieJar;
use GuzzleHttp\Exception\ClientException;
require_once __DIR__ . '/../../vendor/autoload.php';
class ServerContext implements Context {
use WebDav;
/** @var string */
private $mappedUserId;
private $lastInsertIds = [];
/**
* @BeforeSuite
*/
public static function addFilesToSkeleton() {
}
public function getCookieJar(): CookieJar {
return $this->cookieJar;
}
public function getReqestToken(): string {
return $this->requestToken;
}
}