Merge branch 'addTests' into 'master'

Ajout de tests

See merge request tykayn/date-poll-api!3
This commit is contained in:
ty kayn 2020-06-10 17:50:01 +02:00
commit edd62826f7
18 changed files with 664 additions and 10 deletions

6
.env.test Normal file
View File

@ -0,0 +1,6 @@
# define your env variables for the test env here
KERNEL_CLASS='App\Kernel'
APP_SECRET='$ecretf0rt3st'
SYMFONY_DEPRECATIONS_HELPER=999999
PANTHER_APP_ENV=panther
ADMIN_TOKEN=testAdminToken

6
.gitignore vendored
View File

@ -29,3 +29,9 @@ public/polyfills-es2018.js
public/polyfills-es5.js
public/scripts.js
public/styles.css
###> symfony/phpunit-bridge ###
.phpunit
.phpunit.result.cache
/phpunit.xml
###< symfony/phpunit-bridge ###

13
bin/phpunit Executable file
View File

@ -0,0 +1,13 @@
#!/usr/bin/env php
<?php
if (!file_exists(dirname(__DIR__).'/vendor/symfony/phpunit-bridge/bin/simple-phpunit.php')) {
echo "Unable to find the `simple-phpunit.php` script in `vendor/symfony/phpunit-bridge/bin/`.\n";
exit(1);
}
if (false === getenv('SYMFONY_PHPUNIT_DIR')) {
putenv('SYMFONY_PHPUNIT_DIR='.__DIR__.'/.phpunit');
}
require dirname(__DIR__).'/vendor/symfony/phpunit-bridge/bin/simple-phpunit.php';

View File

@ -31,7 +31,12 @@
"symfony/yaml": "4.3.*"
},
"require-dev": {
"ext-mbstring": "*",
"ext-pdo_sqlite": "*",
"doctrine/doctrine-fixtures-bundle": "^3.2",
"liip/test-fixtures-bundle": "^1.0.0",
"symfony/browser-kit": "4.3.*",
"symfony/phpunit-bridge": "^5.0",
"symfony/web-server-bundle": "4.3.*"
},
"config": {

266
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": "7dc6a4d93376a4f198327681d2f6fae2",
"content-hash": "7c5bdef20c7e94f4117ae2b1ef35f486",
"packages": [
{
"name": "doctrine/annotations",
@ -6499,6 +6499,262 @@
],
"time": "2019-11-13T15:46:58+00:00"
},
{
"name": "liip/test-fixtures-bundle",
"version": "1.8.0",
"source": {
"type": "git",
"url": "https://github.com/liip/LiipTestFixturesBundle.git",
"reference": "44f60a776a1f71a1e6800bd9a7e0076b454f35c8"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/liip/LiipTestFixturesBundle/zipball/44f60a776a1f71a1e6800bd9a7e0076b454f35c8",
"reference": "44f60a776a1f71a1e6800bd9a7e0076b454f35c8",
"shasum": ""
},
"require": {
"doctrine/common": "^2.0",
"php": "^7.1",
"symfony/framework-bundle": "^3.4 || ^4.1 || ^5.0"
},
"require-dev": {
"doctrine/data-fixtures": "^1.3",
"doctrine/doctrine-bundle": "^1.8 | ^2.0",
"doctrine/doctrine-fixtures-bundle": "^3.0.2",
"doctrine/orm": "^2.6",
"monolog/monolog": "~1.11 | ^2.0",
"phpunit/phpunit": "^7.5 || ^8.0",
"symfony/monolog-bridge": ">=3",
"symfony/monolog-bundle": "^3.2",
"symfony/phpunit-bridge": "^3.4 || ^4.1 || ^5.0",
"theofidry/alice-data-fixtures": "^1.0.1"
},
"suggest": {
"doctrine/dbal": "Required when using the fixture loading functionality with an ORM and SQLite",
"doctrine/doctrine-fixtures-bundle": "Required when using the fixture loading functionality",
"doctrine/orm": "Required when using the fixture loading functionality with an ORM and SQLite",
"hautelook/alice-bundle": "Required when using loadFixtureFiles functionality with custom providers",
"theofidry/alice-data-fixtures": "Required when using loadFixtureFiles functionality"
},
"type": "symfony-bundle",
"extra": {
"branch-alias": {
"dev-master": "1.x-dev"
}
},
"autoload": {
"psr-4": {
"Liip\\TestFixturesBundle\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Liip AG",
"homepage": "http://www.liip.ch/"
},
{
"name": "Community contributions",
"homepage": "https://github.com/liip/LiipTestFixturesBundle/contributors"
}
],
"description": "This bundles enables efficient loading of Doctrine fixtures in functional test-cases for Symfony applications",
"keywords": [
"fixtures",
"symfony",
"testing"
],
"time": "2020-04-27T10:24:37+00:00"
},
{
"name": "symfony/browser-kit",
"version": "v4.3.11",
"source": {
"type": "git",
"url": "https://github.com/symfony/browser-kit.git",
"reference": "66d301ce3458b522e3b1f2a76ecfccd1834dcf90"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/browser-kit/zipball/66d301ce3458b522e3b1f2a76ecfccd1834dcf90",
"reference": "66d301ce3458b522e3b1f2a76ecfccd1834dcf90",
"shasum": ""
},
"require": {
"php": "^7.1.3",
"symfony/dom-crawler": "~3.4|~4.0"
},
"require-dev": {
"symfony/css-selector": "~3.4|~4.0",
"symfony/http-client": "^4.3",
"symfony/mime": "^4.3",
"symfony/process": "~3.4|~4.0"
},
"suggest": {
"symfony/process": ""
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "4.3-dev"
}
},
"autoload": {
"psr-4": {
"Symfony\\Component\\BrowserKit\\": ""
},
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony BrowserKit Component",
"homepage": "https://symfony.com",
"time": "2020-01-04T12:24:57+00:00"
},
{
"name": "symfony/dom-crawler",
"version": "v4.3.11",
"source": {
"type": "git",
"url": "https://github.com/symfony/dom-crawler.git",
"reference": "ccf895f6f3ed9430f53ae1ce34566e9bb6c58446"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/dom-crawler/zipball/ccf895f6f3ed9430f53ae1ce34566e9bb6c58446",
"reference": "ccf895f6f3ed9430f53ae1ce34566e9bb6c58446",
"shasum": ""
},
"require": {
"php": "^7.1.3",
"symfony/polyfill-ctype": "~1.8",
"symfony/polyfill-mbstring": "~1.0"
},
"conflict": {
"masterminds/html5": "<2.6"
},
"require-dev": {
"masterminds/html5": "^2.6",
"symfony/css-selector": "~3.4|~4.0"
},
"suggest": {
"symfony/css-selector": ""
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "4.3-dev"
}
},
"autoload": {
"psr-4": {
"Symfony\\Component\\DomCrawler\\": ""
},
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony DomCrawler Component",
"homepage": "https://symfony.com",
"time": "2020-01-04T12:24:57+00:00"
},
{
"name": "symfony/phpunit-bridge",
"version": "v5.0.8",
"source": {
"type": "git",
"url": "https://github.com/symfony/phpunit-bridge.git",
"reference": "00b8da18a52fa842b7a39613fb0a63720a354e74"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/phpunit-bridge/zipball/00b8da18a52fa842b7a39613fb0a63720a354e74",
"reference": "00b8da18a52fa842b7a39613fb0a63720a354e74",
"shasum": ""
},
"require": {
"php": ">=5.5.9"
},
"conflict": {
"phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0|<6.4,>=6.0|9.1.2"
},
"suggest": {
"symfony/error-handler": "For tracking deprecated interfaces usages at runtime with DebugClassLoader"
},
"bin": [
"bin/simple-phpunit"
],
"type": "symfony-bridge",
"extra": {
"branch-alias": {
"dev-master": "5.0-dev"
},
"thanks": {
"name": "phpunit/phpunit",
"url": "https://github.com/sebastianbergmann/phpunit"
}
},
"autoload": {
"files": [
"bootstrap.php"
],
"psr-4": {
"Symfony\\Bridge\\PhpUnit\\": ""
},
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony PHPUnit Bridge",
"homepage": "https://symfony.com",
"time": "2020-04-28T17:58:55+00:00"
},
{
"name": "symfony/process",
"version": "v4.3.10",
@ -6617,7 +6873,11 @@
"php": "^7.1.3",
"ext-ctype": "*",
"ext-iconv": "*",
"ext-json": "*"
"ext-json": "*",
"ext-pdo_mysql": "*"
},
"platform-dev": []
"platform-dev": {
"ext-mbstring": "*",
"ext-pdo_sqlite": "*"
}
}

View File

@ -14,4 +14,5 @@ return [
Nelmio\CorsBundle\NelmioCorsBundle::class => ['all' => true],
Symfony\Bundle\TwigBundle\TwigBundle::class => ['all' => true],
Symfony\Bundle\SwiftmailerBundle\SwiftmailerBundle::class => ['all' => true],
Liip\TestFixturesBundle\LiipTestFixturesBundle::class => ['test' => true],
];

View File

@ -0,0 +1,5 @@
doctrine:
dbal:
driver: pdo_sqlite
path: "%kernel.cache_dir%/test.db"
url: null

View File

@ -2,3 +2,6 @@ framework:
test: true
session:
storage_id: session.storage.mock_file
liip_test_fixtures:
cache_db:
sqlite: liip_test_fixtures.services_database_backup.sqlite

View File

@ -4,6 +4,7 @@
# Put parameters here that don't need to change on each machine where the app is deployed
# https://symfony.com/doc/current/best_practices/configuration.html#application-related-configuration
parameters:
admin_token: '%env(resolve:ADMIN_TOKEN)%'
services:
# default configuration for services in *this* file

33
phpunit.xml.dist Normal file
View File

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- https://phpunit.readthedocs.io/en/latest/configuration.html -->
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="bin/.phpunit/phpunit.xsd"
backupGlobals="false"
colors="true"
bootstrap="tests/bootstrap.php"
>
<php>
<ini name="error_reporting" value="-1" />
<server name="APP_ENV" value="test" force="true" />
<server name="SHELL_VERBOSITY" value="-1" />
<server name="SYMFONY_PHPUNIT_REMOVE" value="" />
<server name="SYMFONY_PHPUNIT_VERSION" value="7.5" />
</php>
<testsuites>
<testsuite name="Project Test Suite">
<directory>tests</directory>
</testsuite>
</testsuites>
<filter>
<whitelist processUncoveredFilesFromWhitelist="true">
<directory suffix=".php">src</directory>
</whitelist>
</filter>
<listeners>
<listener class="Symfony\Bridge\PhpUnit\SymfonyTestsListener" />
</listeners>
</phpunit>

View File

@ -34,7 +34,7 @@ class AdminController extends FramadateController {
function cleanExpiredPolls(
string $token
) {
if ( $this->getParameter( 'ADMIN_TOKEN' ) !== $token ) {
if ( $this->getParameter( 'admin_token' ) !== $token ) {
return $this->json( [
'message' => 'clean routine can NOT be done, your admin token is bad, and you should feel bad.',
],

View File

@ -27,7 +27,7 @@ class CommentController extends FramadateController {
* @Get(
* path = "/poll/{id}/comments",
* name = "get_poll_comment",
* requirements = {"poll_id"="\d+"}
* requirements = {"id"="\d+"}
* )
*/
public
@ -52,7 +52,7 @@ class CommentController extends FramadateController {
* @Post(
* path = "/poll/{id}/comment",
* name = "new_comment",
* requirements = {"content"="\w+", "poll_id"="\d+"}
* requirements = {"content"="\w+", "id"="\d+"}
* )
*/
public
@ -71,13 +71,16 @@ class CommentController extends FramadateController {
$em = $this->getDoctrine()->getRepository( Owner::class );
$data = json_decode( $data, true );
if(!isset($data['email'])) {
return $this->json(["message" => "Incorrect JSON in request"], 400);
}
$foundOwner = $em->findOneByEmail( $data[ 'email' ] );
// manage existing or new Owner
if ( ! $foundOwner ) {
$foundOwner = new Owner();
$foundOwner->setPseudo( $data[ 'owner' ][ 'email' ] )
->setEmail( $data[ 'owner' ][ 'email' ] )
$foundOwner->setPseudo( $data[ 'email' ] )
->setEmail( $data[ 'email' ] )
->setModifierToken( uniqid( '', true ) );
}
// anti flood
@ -142,7 +145,7 @@ class CommentController extends FramadateController {
* @Delete(
* path = "/poll/{id}/comments",
* name = "poll_comments_delete",
* requirements = {"accessToken"="\w+", "poll_id"="\d+"}
* requirements = {"accessToken"="\w+", "id"="\d+"}
* )
*
* @param Poll $poll

View File

@ -10,6 +10,7 @@ use FOS\RestBundle\Controller\Annotations\Get;
use FOS\RestBundle\Controller\Annotations\Post;
use FOS\RestBundle\Controller\Annotations\Put;
use FOS\RestBundle\Controller\Annotations\Route;
use JMS\Serializer\Exception\RuntimeException;
use JMS\Serializer\SerializerBuilder;
use JMS\Serializer\SerializerInterface;
use Swift_Mailer;
@ -142,7 +143,11 @@ class PollController extends FramadateController {
$data = $request->getContent();
$serializer = SerializerBuilder::create()->build();
$newpoll = $serializer->deserialize( $data, 'App\Entity\Poll', 'json' );
try {
$newpoll = $serializer->deserialize( $data, 'App\Entity\Poll', 'json' );
} catch(RuntimeException $e) {
return $this->json(["message" => "Incorrect JSON in request"], 400);
}
$newpoll
->setAdminKey( $newpoll->generateAdminKey() )
->setCreationDate( new DateTime() )

View File

@ -170,6 +170,9 @@
"config/packages/prod/jms_serializer.yaml"
]
},
"liip/test-fixtures-bundle": {
"version": "1.8.0"
},
"nelmio/api-doc-bundle": {
"version": "3.0",
"recipe": {
@ -240,6 +243,9 @@
"swiftmailer/swiftmailer": {
"version": "v6.2.3"
},
"symfony/browser-kit": {
"version": "v4.3.11"
},
"symfony/cache": {
"version": "v4.3.5"
},
@ -271,6 +277,9 @@
"symfony/doctrine-bridge": {
"version": "v4.3.5"
},
"symfony/dom-crawler": {
"version": "v4.3.11"
},
"symfony/dotenv": {
"version": "v4.3.5"
},
@ -365,6 +374,21 @@
"symfony/orm-pack": {
"version": "v1.0.7"
},
"symfony/phpunit-bridge": {
"version": "4.3",
"recipe": {
"repo": "github.com/symfony/recipes",
"branch": "master",
"version": "4.3",
"ref": "6d0e35f749d5f4bfe1f011762875275cd3f9874f"
},
"files": [
".env.test",
"bin/phpunit",
"phpunit.xml.dist",
"tests/bootstrap.php"
]
},
"symfony/polyfill-intl-icu": {
"version": "v1.12.0"
},

View File

@ -0,0 +1,35 @@
<?php
namespace App\Tests\Functional;
use Liip\TestFixturesBundle\Test\FixturesTrait;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
class AdminControllerTest extends WebTestCase {
use FixturesTrait;
// Test getting all polls
public function testGetAllPolls() {
$client = static::createClient();
$this->loadFixtures(array(
'App\DataFixtures\AppPollFixtures'
));
$client->request('GET', '/admin/polls/clean/testAdminToken');
$response = $client->getResponse();
$this->assertEquals(200, $response->getStatusCode());
$body = $response->getContent();
$json = json_decode($body, true);
$this->assertEquals(4, $json['data']['count']);
//This call is supposed to be nilpotent
$client->request('GET', '/admin/polls/clean/testAdminToken');
$response = $client->getResponse();
$json = json_decode($response->getContent(), true);
$this->assertEquals(0, $json['data']['count']);
}
}

View File

@ -0,0 +1,76 @@
<?php
namespace App\Tests\Functional;
use Liip\TestFixturesBundle\Test\FixturesTrait;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
class AdminControllerTest extends WebTestCase {
use FixturesTrait;
// Test getting all comments from one Poll
public function testGetAllComments() {
$client = static::createClient();
$this->loadFixtures(array(
'App\DataFixtures\AppPollFixtures',
'App\DataFixtures\CommentFixtures',
));
$client->request('GET', '/api/v1/poll/1/comments');
$response = $client->getResponse();
$this->assertEquals(200, $response->getStatusCode());
$body = $response->getContent();
$json = json_decode($body, true);
$this->assertEquals(5, count($json['data']));
}
public function testNewComment() {
$client = static::createClient();
$this->loadFixtures(array(
'App\DataFixtures\AppPollFixtures',
'App\DataFixtures\CommentFixtures',
));
$data = [
'text' => "Mon nouveau commentaire de test !",
'email' => "email@host.plop"
];
$client->request('POST', '/api/v1/poll/1/comment', [
'body' => json_encode($data)
],
[],
[
'CONTENT_TYPE' => 'application/json',
'HTTP_ACCEPT' => 'application/json',
],
json_encode($data)
);
$response = $client->getResponse();
$this->assertEquals(201, $response->getStatusCode());
$body = $response->getContent();
$json = json_decode($body, true);
$this->assertEquals("email@host.plop", $json['data']['your_comment']['pseudo']);
}
public function testDeleteComments() {
$client = static::createClient();
$this->loadFixtures(array(
'App\DataFixtures\AppPollFixtures',
'App\DataFixtures\CommentFixtures',
));
$client->request('DELETE', '/api/v1/poll/1/comments');
$response = $client->getResponse();
$this->assertEquals(200, $response->getStatusCode());
}
}

View File

@ -0,0 +1,167 @@
<?php
namespace App\Tests\Functional;
use Liip\TestFixturesBundle\Test\FixturesTrait;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
class PollControllerTest extends WebTestCase {
use FixturesTrait;
// Test getting all polls
public function testGetAllPolls() {
$client = static::createClient();
$this->loadFixtures(array(
'App\DataFixtures\AppPollFixtures'
));
$client->request('GET', '/api/v1/poll/');
$response = $client->getResponse();
$this->assertEquals(200, $response->getStatusCode());
$body = $response->getContent();
$json = json_decode($body, true);
$this->assertEquals(4, count($json['poll']));
}
// Test getting one poll (we should try to check all poll property)
public function testGetOnePoll() {
$client = static::createClient();
$this->loadFixtures(array(
'App\DataFixtures\AppPollFixtures'
));
$client->request('GET', '/api/v1/poll/1');
$response = $client->getResponse();
$this->assertEquals(200, $response->getStatusCode());
$body = $response->getContent();
$json = json_decode($body, true);
$this->assertEquals("citron ou orange", $json['poll']['title']);
}
// Test Put some data on a poll
public function testPutOnePoll() {
$client = static::createClient();
$this->loadFixtures(array(
'App\DataFixtures\AppPollFixtures'
));
$client->request('PUT', '/api/v1/poll/1/notTheToken', [
'body' => "{
\"id\": 1,
\"title\": \"Fromage ou dessert ? \",
\"description\": \"Votre plat préféré\",
\"creation_date\": \"2048-04-25T16:19:48+02:00\",
\"expiracy_date\": \"2048-04-25T16:19:48+02:00\",
\"kind\": \"text\",
\"allowed_answers\": [
\"yes\"
],
\"modification_policy\": \"nobody\",
\"mail_on_vote\": true,
\"choices\": [
{
\"id\": 1,
\"name\": \"fromage\"
},
{
\"id\": 2,
\"name\": \"dessert\"
}
],
\"default_expiracy_days_from_now\": 365
}"
]);
$response = $client->getResponse();
$this->assertEquals(403, $response->getStatusCode());
//Same request but with admin key
$client->request('PUT', '/api/v1/poll/1/5eb5ade73ec4f', [
'body' => "{
\"id\": 1,
\"title\": \"Fromage ou dessert ? \",
\"description\": \"Votre plat préféré\",
\"creation_date\": \"2048-04-25T16:19:48+02:00\",
\"expiracy_date\": \"2048-04-25T16:19:48+02:00\",
\"kind\": \"text\",
\"allowed_answers\": [
\"yes\"
],
\"modification_policy\": \"nobody\",
\"mail_on_vote\": true,
\"choices\": [
{
\"id\": 1,
\"name\": \"fromage\"
},
{
\"id\": 2,
\"name\": \"dessert\"
}
],
\"default_expiracy_days_from_now\": 365
}"
]);
$response = $client->getResponse();
$this->assertEquals(200, $response->getStatusCode());
//Checking the result of modification
$client->request('GET', '/api/v1/poll/1');
$response = $client->getResponse();
$this->assertEquals(200, $response->getStatusCode());
$body = $response->getContent();
$json = json_decode($body, true);
$this->assertEquals("Fromage ou dessert ?", $json['poll']['title']);
}
// Test Post new poll
public function testPostOnePoll() {
$client = static::createClient();
$this->loadFixtures(array(
'App\DataFixtures\AppPollFixtures'
));
$data = [
"title" => "Fromage ou dessert ? ",
"description" => "Votre plat préféré",
"creation_date" => "2048-04-25T16:19:48+02:00",
"expiracy_date" => "2048-04-25T16:19:48+02:00",
"kind" => "text",
"allowed_answers" => [
"yes"
],
"modification_policy" => "nobody",
"mail_on_vote" => true,
"choices" => [
[
"id" => 1,
"name" => "fromage"
],
[
"id" => 2,
"name" => "dessert"
]
],
"default_expiracy_days_from_now" => 365
];
$client->request('POST', '/api/v1/poll/', [
'json' => $data
], [], [], json_encode($data));
$response = $client->getResponse();
$this->assertEquals(201, $response->getStatusCode());
$data = $response->getContent();
$this->assertIsNumeric($data['poll']['id']);
}
}

11
tests/bootstrap.php Normal file
View File

@ -0,0 +1,11 @@
<?php
use Symfony\Component\Dotenv\Dotenv;
require dirname(__DIR__).'/vendor/autoload.php';
if (file_exists(dirname(__DIR__).'/config/bootstrap.php')) {
require dirname(__DIR__).'/config/bootstrap.php';
} elseif (method_exists(Dotenv::class, 'bootEnv')) {
(new Dotenv())->bootEnv(dirname(__DIR__).'/.env');
}