Add “codeception/module-rest” for test REST API modules (#4960)

This commit is contained in:
Yuriy Bakhtin 2021-03-18 11:48:52 +03:00 committed by GitHub
parent 3e7d39cffe
commit eec1c57af3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 484 additions and 2 deletions

View File

@ -77,12 +77,13 @@
"codeception/codeception": "^4.0",
"codeception/module-asserts": "^1.0",
"codeception/module-filesystem": "^1.0",
"codeception/module-rest": "^1.2",
"codeception/module-webdriver": "^1.1",
"codeception/module-yii2": "^1.0",
"codeception/specify": "^1.0",
"codeception/verify": "~0.5.0 || ~1.1.0",
"symfony/browser-kit": ">=2.7 <=4.2.4",
"phpcompatibility/php-compatibility": "*",
"symfony/browser-kit": ">=2.7 <=4.2.4",
"yiisoft/yii2-debug": "~2.1.0",
"yiisoft/yii2-faker": "~2.0.0",
"yiisoft/yii2-gii": "~2.1.0"

194
composer.lock generated
View File

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "11c96d6ac2179c290c81f666f319ac5f",
"content-hash": "8ce4dc3e98c455997a22f12c165d2cd9",
"packages": [
{
"name": "bower-asset/bootstrap",
@ -7860,6 +7860,60 @@
},
"time": "2020-10-24T14:46:40+00:00"
},
{
"name": "codeception/module-rest",
"version": "1.2.8",
"source": {
"type": "git",
"url": "https://github.com/Codeception/module-rest.git",
"reference": "4c8c6bd75f67a25ff91bdce0d6c135c5e7aa5e10"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Codeception/module-rest/zipball/4c8c6bd75f67a25ff91bdce0d6c135c5e7aa5e10",
"reference": "4c8c6bd75f67a25ff91bdce0d6c135c5e7aa5e10",
"shasum": ""
},
"require": {
"codeception/codeception": "^4.0",
"justinrainbow/json-schema": "~5.2.9",
"php": ">=5.6.0 <9.0",
"softcreatr/jsonpath": "^0.5 || ^0.7"
},
"require-dev": {
"codeception/lib-innerbrowser": "^1.0",
"codeception/util-universalframework": "^1.0"
},
"suggest": {
"aws/aws-sdk-php": "For using AWS Auth"
},
"type": "library",
"autoload": {
"classmap": [
"src/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Gintautas Miselis"
}
],
"description": "REST module for Codeception",
"homepage": "http://codeception.com/",
"keywords": [
"codeception",
"rest"
],
"support": {
"issues": "https://github.com/Codeception/module-rest/issues",
"source": "https://github.com/Codeception/module-rest/tree/1.2.8"
},
"time": "2021-03-02T06:47:59+00:00"
},
{
"name": "codeception/module-webdriver",
"version": "1.2.0",
@ -8186,6 +8240,76 @@
},
"time": "2020-09-30T07:37:11+00:00"
},
{
"name": "justinrainbow/json-schema",
"version": "5.2.10",
"source": {
"type": "git",
"url": "https://github.com/justinrainbow/json-schema.git",
"reference": "2ba9c8c862ecd5510ed16c6340aa9f6eadb4f31b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/justinrainbow/json-schema/zipball/2ba9c8c862ecd5510ed16c6340aa9f6eadb4f31b",
"reference": "2ba9c8c862ecd5510ed16c6340aa9f6eadb4f31b",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"require-dev": {
"friendsofphp/php-cs-fixer": "~2.2.20||~2.15.1",
"json-schema/json-schema-test-suite": "1.2.0",
"phpunit/phpunit": "^4.8.35"
},
"bin": [
"bin/validate-json"
],
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "5.0.x-dev"
}
},
"autoload": {
"psr-4": {
"JsonSchema\\": "src/JsonSchema/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Bruno Prieto Reis",
"email": "bruno.p.reis@gmail.com"
},
{
"name": "Justin Rainbow",
"email": "justin.rainbow@gmail.com"
},
{
"name": "Igor Wiedler",
"email": "igor@wiedler.ch"
},
{
"name": "Robert Schönthal",
"email": "seroscho@googlemail.com"
}
],
"description": "A library to validate a json schema.",
"homepage": "https://github.com/justinrainbow/json-schema",
"keywords": [
"json",
"schema"
],
"support": {
"issues": "https://github.com/justinrainbow/json-schema/issues",
"source": "https://github.com/justinrainbow/json-schema/tree/5.2.10"
},
"time": "2020-05-27T16:41:55+00:00"
},
{
"name": "opis/closure",
"version": "3.6.1",
@ -8469,6 +8593,74 @@
},
"time": "2019-03-08T08:55:37+00:00"
},
{
"name": "softcreatr/jsonpath",
"version": "0.7.3",
"source": {
"type": "git",
"url": "https://github.com/SoftCreatR/JSONPath.git",
"reference": "e3ae75112a5247e3b27a7e0e72155eae261d8c72"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/SoftCreatR/JSONPath/zipball/e3ae75112a5247e3b27a7e0e72155eae261d8c72",
"reference": "e3ae75112a5247e3b27a7e0e72155eae261d8c72",
"shasum": ""
},
"require": {
"ext-json": "*",
"php": ">=7.1"
},
"conflict": {
"phpunit/phpunit": "<7.0 || >= 10.0"
},
"replace": {
"flow/jsonpath": "*"
},
"require-dev": {
"phpunit/phpunit": ">=7.0",
"roave/security-advisories": "dev-master",
"squizlabs/php_codesniffer": "^3.5"
},
"type": "library",
"autoload": {
"psr-4": {
"Flow\\JSONPath\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Stephen Frank",
"email": "stephen@flowsa.com",
"homepage": "https://prismaticbytes.com",
"role": "Developer"
},
{
"name": "Sascha Greuel",
"email": "hello@1-2.dev",
"homepage": "http://1-2.dev",
"role": "Developer"
}
],
"description": "JSONPath implementation for parsing, searching and flattening arrays",
"support": {
"email": "hello@1-2.dev",
"forum": "https://github.com/SoftCreatR/JSONPath/discussions",
"issues": "https://github.com/SoftCreatR/JSONPath/issues",
"source": "https://github.com/SoftCreatR/JSONPath"
},
"funding": [
{
"url": "https://github.com/softcreatr",
"type": "github"
}
],
"time": "2021-03-08T14:18:21+00:00"
},
{
"name": "squizlabs/php_codesniffer",
"version": "3.5.8",

View File

@ -0,0 +1,206 @@
<?php
use Codeception\Util\HttpCode;
use humhub\modules\rest\definitions\UserDefinitions;
use humhub\modules\user\models\User;
use yii\data\Pagination;
use yii\web\Link;
/**
* Inherited Methods
* @method void wantToTest($text)
* @method void wantTo($text)
* @method void execute($callable)
* @method void expectTo($prediction)
* @method void expect($prediction)
* @method void amGoingTo($argumentation)
* @method void am($role)
* @method void lookForwardTo($achieveValue)
* @method void comment($description)
* @method \Codeception\Lib\Friend haveFriend($name, $actorClass = NULL)
*
* @SuppressWarnings(PHPMD)
*/
class ApiTester extends \Codeception\Actor
{
use _generated\ApiTesterActions;
public function amAdmin()
{
$this->amUser('Admin', 'test');
}
public function amUser1()
{
$this->amUser('User1', '123qwe');
}
public function amUser2()
{
$this->amUser('User2', '123qwe');
}
public function amUser3()
{
$this->amUser('User3', '123qwe');
}
public function amUser($user = null, $password = null)
{
$this->amHttpAuthenticated($user, $password);
}
public function seeSuccessResponseContainsJson($json = [])
{
$this->seeResponseCodeIs(HttpCode::OK);
$this->seeResponseIsJson();
$this->seeResponseContainsJson($json);
}
public function seeForbiddenResponseContainsJson($json = [])
{
$this->seeResponseCodeIs(HttpCode::FORBIDDEN);
$this->seeResponseIsJson();
$this->seeResponseContainsJson($json);
}
public function seeBadResponseContainsJson($json = [])
{
$this->seeResponseCodeIs(HttpCode::BAD_REQUEST);
$this->seeResponseIsJson();
$this->seeResponseContainsJson($json);
}
/**
* Send GET API Request and check a response contains the results
*
* @param string $url
* @param array $jsonResults
* @param array $paginationParams
*/
public function seePaginationGetResponse($url, $jsonResults = [], $paginationParams = [])
{
$this->sendGet($url);
$this->seePaginationResponseContainsJson($url, $jsonResults, $paginationParams);
}
/**
* Send POST API Request and check a response contains the results
*
* @param string $url
* @param array $postData
* @param array $jsonResults
* @param array $paginationParams
*/
public function seePaginationPostResponse($url, $postData, $jsonResults = [], $paginationParams = [])
{
$this->sendPost($url, $postData);
$this->seePaginationResponseContainsJson($url, $jsonResults, $paginationParams);
}
/**
* Send PUT API Request and check a response contains the results
*
* @param string $url
* @param array $putData
* @param array $jsonResults
* @param array $paginationParams
*/
public function seePaginationPutResponse($url, $putData, $jsonResults = [], $paginationParams = [])
{
$this->sendPut($url, $putData);
$this->seePaginationResponseContainsJson($url, $jsonResults, $paginationParams);
}
/**
* Send DELETE API Request and check a response contains the results
*
* @param string $url
* @param array $jsonResults
* @param array $paginationParams
*/
public function seePaginationDeleteResponse($url, $jsonResults = [], $paginationParams = [])
{
$this->sendDelete($url);
$this->seePaginationResponseContainsJson($url, $jsonResults, $paginationParams);
}
/**
* Send GET API Request and check a response contains the results
*
* @param string $url
* @param array $jsonResults
* @param array $paginationParams Possible keys: 'total', 'page', 'pages'
*/
public function seePaginationResponseContainsJson($url, $jsonResults = [], $paginationParams = [])
{
$json = array_merge([
'total' => count($jsonResults),
'page' => 1,
'pages' => 1,
], $paginationParams);
$json['links'] = $this->getPaginationUrls($url, $json);
$json['results'] = $jsonResults;
$this->seeSuccessResponseContainsJson($json);
}
/**
* Get pagination URLs, Used to check JSON response
*
* @param string $url
* @param array $params Possible keys: 'page', 'pages'
* @return string[]
*/
protected function getPaginationUrls($url, $params)
{
$links = [Link::REL_SELF => $this->getPaginationUrl($url, $params['page'])];
if ($params['pages'] > 0) {
$links[Pagination::LINK_FIRST] = $this->getPaginationUrl($url, 0);
$links[Pagination::LINK_LAST] = $this->getPaginationUrl($url, $params['pages'] - 1);
if ($params['page'] > 1) {
$links[Pagination::LINK_PREV] = $this->getPaginationUrl($url, $params['page'] - 1);
}
if ($params['page'] < $params['pages'] - 1) {
$links[Pagination::LINK_NEXT] = $this->getPaginationUrl($url, $params['page'] + 1);
}
}
return $links;
}
/**
* @param string $url
* @param int $page
* @return string
*/
protected function getPaginationUrl($url, $page = 1)
{
return '/api/v1/' . trim($url, '/') . '?page=' . (empty($page) ? 1 : $page) . '&per-page=100';
}
/**
* Get users definitions by usernames or ids
*
* @param array $users Usernames or Ids
* @return array
*/
public function seeUserDefinitions($users)
{
$userDefinitions = [];
foreach ($users as $userIdOrUsername) {
$user = User::find()
->where(['id' => $userIdOrUsername])
->orWhere(['username' => $userIdOrUsername])
->one();
if ($user) {
$userDefinitions[] = UserDefinitions::getUser($user);
}
}
$this->seeSuccessResponseContainsJson($userDefinitions);
}
}

View File

@ -0,0 +1,34 @@
<?php
namespace tests\codeception\_support;
use humhub\modules\rest\Module;
use Yii;
class HumHubApiTestCest
{
public function _before()
{
$this->enableRestModule();
}
protected function enableRestModule()
{
/* @var Module $module */
$module = Yii::$app->getModule('rest');
if (!$module) {
return false;
}
Yii::$app->moduleManager->enableModules(['rest']);
$module->settings->set('enabledForAllUsers', true);
$module->settings->set('enableBasicAuth', true);
}
protected function isRestModuleEnabled(): bool
{
$enabledModules = Yii::$app->moduleManager->getEnabledModules();
return isset($enabledModules['rest']);
}
}

View File

@ -0,0 +1,19 @@
# Codeception Test Suite Configuration
# suite for REST API tests.
# RUN `build` COMMAND AFTER ADDING/REMOVING MODULES.
actor: ApiTester
class_name: ApiTester
modules:
enabled:
- REST
- Yii2
- tests\codeception\_support\DynamicFixtureHelper
config:
REST:
url: 'http://localhost:8080/api/v1/'
depends: Yii2
part: Json
Yii2:
configFile: 'codeception/config/api.php'

View File

@ -0,0 +1,3 @@
<?php
$config = require(dirname(__DIR__) . '/config/api.php');
new humhub\components\Application($config);

View File

@ -0,0 +1,27 @@
<?php
/**
* Application configuration for api tests
*/
$testConfig = [
'class' => 'humhub\components\Application',
'components' => [
'urlManager' => [
'showScriptName' => false,
'enablePrettyUrl' => true,
],
],
];
defined('YII_APP_BASE_PATH') or define('YII_APP_BASE_PATH', dirname(dirname(dirname(dirname(__DIR__)))));
return yii\helpers\ArrayHelper::merge(
// Common Config
require(YII_APP_BASE_PATH . '/humhub/config/common.php'),
// Web Config
require(YII_APP_BASE_PATH . '/humhub/config/web.php'),
// Test Common Config
require(__DIR__ . '/config.php'),
// API Test Config
$testConfig
);