Skip to content
This repository has been archived by the owner on Dec 11, 2023. It is now read-only.

Commit

Permalink
Add behat
Browse files Browse the repository at this point in the history
  • Loading branch information
rgomezcasas committed Jul 25, 2019
1 parent d9a5a46 commit efebedc
Show file tree
Hide file tree
Showing 20 changed files with 1,764 additions and 217 deletions.
3 changes: 2 additions & 1 deletion apps/mooc/backend/config/bundles.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<?php

return [
Symfony\Bundle\FrameworkBundle\FrameworkBundle::class => ['all' => true],
Symfony\Bundle\FrameworkBundle\FrameworkBundle::class => ['all' => true],
FriendsOfBehat\SymfonyExtension\Bundle\FriendsOfBehatSymfonyExtensionBundle::class => ['test' => true],
];
12 changes: 12 additions & 0 deletions apps/mooc/backend/config/services_test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
framework:
test: true

services:
_defaults:
autoconfigure: true
autowire: true

CodelyTv\Tests\:
resource: '../../../../tests/src'

CodelyTv\Shared\Domain\RandomNumberGenerator: '@CodelyTv\Tests\Shared\Infrastructure\ConstantRandomNumberGenerator'
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

namespace CodelyTv\Apps\Mooc\Backend\Controller\HealthCheck;

use CodelyTv\Shared\Infrastructure\RandomNumberGenerator;
use CodelyTv\Shared\Domain\RandomNumberGenerator;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
Expand Down
5 changes: 4 additions & 1 deletion apps/mooc/backend/src/MoocBackendKernel.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,10 @@ protected function configureContainer(ContainerBuilder $container, LoaderInterfa
$container->setParameter('container.dumper.inline_class_loader', true);
$confDir = $this->getProjectDir().'/config';

$loader->load($confDir.'/*'.self::CONFIG_EXTS, 'glob');
$loader->load($confDir.'/services'.self::CONFIG_EXTS, 'glob');
$loader->load($confDir.'/services_'.$this->environment.self::CONFIG_EXTS, 'glob');
$loader->load($confDir.'/services/*'.self::CONFIG_EXTS, 'glob');

}

protected function configureRoutes(RouteCollectionBuilder $routes): void
Expand Down
2 changes: 2 additions & 0 deletions behat.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
imports:
- tests/apps/mooc/backend/mooc_backend.yml
11 changes: 9 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,19 @@

"symfony/framework-bundle": "^4.3",
"symfony/dotenv": "^4.3",
"symfony/yaml": "^4.3"
"symfony/yaml": "^4.3",

"lambdish/phunctional": "^1.0"
},
"require-dev": {
"ext-xdebug": "*",

"roave/security-advisories": "dev-master"
"roave/security-advisories": "dev-master",

"behat/behat": "^3.5",
"behat/mink-extension": "^2.3",
"behat/mink-browserkit-driver": "^1.3",
"friends-of-behat/symfony-extension": "^2.0"
},
"autoload": {
"psr-4": {
Expand Down
1,616 changes: 1,418 additions & 198 deletions composer.lock

Large diffs are not rendered by default.

Empty file removed src/Shared/Domain/.gitkeep
Empty file.
10 changes: 10 additions & 0 deletions src/Shared/Domain/RandomNumberGenerator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

declare(strict_types = 1);

namespace CodelyTv\Shared\Domain;

interface RandomNumberGenerator
{
public function generate(): int;
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@

namespace CodelyTv\Shared\Infrastructure;

final class RandomNumberGenerator
use CodelyTv\Shared\Domain\RandomNumberGenerator;

final class PhpRandomNumberGenerator implements RandomNumberGenerator
{
public function generate(): int
{
Expand Down
Empty file removed tests/apps/mooc/backend/.gitkeep
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
Feature: Api status
In order to know the server is up and running
As a health check
I want to check the api status

Scenario: Check the api status
Given I send a GET request to "/health-check"
Then the response content should be:
"""
{
"mooc-backend": "ok",
"rand": 1
}
"""
18 changes: 18 additions & 0 deletions tests/apps/mooc/backend/mooc_backend.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
mooc_backend:
extensions:
FriendsOfBehat\SymfonyExtension:
kernel:
class: CodelyTv\Apps\Mooc\Backend\MoocBackendKernel
bootstrap: apps/mooc/bootstrap.php
Behat\MinkExtension:
sessions:
symfony:
symfony: ~
base_url: ''

suites:
health_check:
paths: [ tests/apps/mooc/backend/features/health_check ]
contexts:
- CodelyTv\Tests\Shared\Infrastructure\Behat\ApiRequestContext
- CodelyTv\Tests\Shared\Infrastructure\Behat\ApiResponseContext
37 changes: 37 additions & 0 deletions tests/src/Shared/Infrastructure/Behat/ApiRequestContext.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php

declare(strict_types = 1);

namespace CodelyTv\Tests\Shared\Infrastructure\Behat;

use Behat\Gherkin\Node\PyStringNode;
use Behat\Mink\Session;
use Behat\MinkExtension\Context\RawMinkContext;
use CodelyTv\Tests\Shared\Infrastructure\Mink\MinkHelper;
use CodelyTv\Tests\Shared\Infrastructure\Mink\MinkSessionRequestHelper;

final class ApiRequestContext extends RawMinkContext
{
private $request;

public function __construct(Session $session)
{
$this->request = new MinkSessionRequestHelper(new MinkHelper($session));
}

/**
* @Given I send a :method request to :url
*/
public function iSendARequestTo($method, $url): void
{
$this->request->sendRequest($method, $this->locatePath($url));
}

/**
* @Given I send a :method request to :url with body:
*/
public function iSendARequestToWithBody($method, $url, PyStringNode $body): void
{
$this->request->sendRequestWithPyStringNode($method, $this->locatePath($url), $body);
}
}
89 changes: 89 additions & 0 deletions tests/src/Shared/Infrastructure/Behat/ApiResponseContext.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
<?php

declare(strict_types = 1);

namespace CodelyTv\Tests\Shared\Infrastructure\Behat;

use Behat\Gherkin\Node\PyStringNode;
use Behat\Mink\Session;
use Behat\MinkExtension\Context\RawMinkContext;
use CodelyTv\Tests\Shared\Infrastructure\Mink\MinkHelper;
use RuntimeException;

final class ApiResponseContext extends RawMinkContext
{
private $sessionHelper;
private $minkSession;

public function __construct(Session $minkSession)
{
$this->minkSession = $minkSession;
$this->sessionHelper = new MinkHelper($this->minkSession);
}

/**
* @Then the response content should be:
*/
public function theResponseContentShouldBe(PyStringNode $expectedResponse): void
{
$expected = $this->sanitizeOutput($expectedResponse->getRaw());
$actual = $this->sanitizeOutput($this->sessionHelper->getResponse());

if ($expected !== $actual) {
throw new RuntimeException(
sprintf("The outputs does not match!\n\n-- Expected:\n%s\n\n-- Actual:\n%s", $expected, $actual)
);
}
}

/**
* @Then the response should be empty
*/
public function theResponseShouldBeEmpty(): void
{
$actual = trim($this->sessionHelper->getResponse());

if (!empty($actual)) {
throw new RuntimeException(
sprintf("The outputs is not empty, Actual:\n%s", $actual)
);
}
}

/**
* @Then print last api response
*/
public function printApiResponse(): void
{
print_r($this->sessionHelper->getResponse());
}

/**
* @Then print response headers
*/
public function printResponseHeaders(): void
{
print_r($this->sessionHelper->getResponseHeaders());
}

/**
* @Then the response status code should be :expectedResponseCode
*/
public function theResponseStatusCodeShouldBe($expectedResponseCode): void
{
if ($this->minkSession->getStatusCode() !== (int) $expectedResponseCode) {
throw new RuntimeException(
sprintf(
'The status code <%s> does not match the expected <%s>',
$this->minkSession->getStatusCode(),
$expectedResponseCode
)
);
}
}

private function sanitizeOutput(string $output)
{
return json_encode(json_decode(trim($output), true));
}
}
15 changes: 15 additions & 0 deletions tests/src/Shared/Infrastructure/ConstantRandomNumberGenerator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

declare(strict_types = 1);

namespace CodelyTv\Tests\Shared\Infrastructure;

use CodelyTv\Shared\Domain\RandomNumberGenerator;

final class ConstantRandomNumberGenerator implements RandomNumberGenerator
{
public function generate(): int
{
return 1;
}
}
96 changes: 96 additions & 0 deletions tests/src/Shared/Infrastructure/Mink/MinkHelper.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
<?php

declare(strict_types = 1);

namespace CodelyTv\Tests\Shared\Infrastructure\Mink;

use Behat\Mink\Driver\DriverInterface;
use Behat\Mink\Session;
use Symfony\Component\BrowserKit\AbstractBrowser;
use Symfony\Component\DomCrawler\Crawler;
use Symfony\Component\HttpFoundation\Request;

final class MinkHelper
{
private $session;

public function __construct(Session $session)
{
$this->session = $session;
}

public function sendRequest($method, $url, array $optionalParams = []): Crawler
{
$defaultOptionalParams = [
'parameters' => [],
'files' => [],
'server' => ['HTTP_ACCEPT' => 'application/json', 'CONTENT_TYPE' => 'application/json'],
'content' => null,
'changeHistory' => true,
];

$optionalParams = array_merge($defaultOptionalParams, $optionalParams);

$crawler = $this->getClient()->request(
$method,
$url,
$optionalParams['parameters'],
$optionalParams['files'],
$optionalParams['server'],
$optionalParams['content'],
$optionalParams['changeHistory']
);

$this->resetRequestStuff();

return $crawler;
}

public function getResponse(): string
{
return $this->getSession()->getPage()->getContent();
}

public function getResponseHeaders(): array
{
return $this->normalizeHeaders(
array_change_key_case($this->getSession()->getResponseHeaders(), CASE_LOWER)
);
}

public function resetServerParameters(): void
{
$this->getClient()->setServerParameters([]);
}

public function getRequest(): Request
{
return $this->getClient()->getRequest();
}

private function getSession(): Session
{
return $this->session;
}

private function getDriver(): DriverInterface
{
return $this->getSession()->getDriver();
}

private function getClient(): AbstractBrowser
{
return $this->getDriver()->getClient();
}

private function normalizeHeaders(array $headers): array
{
return array_map('implode', array_filter($headers));
}

private function resetRequestStuff(): void
{
$this->getSession()->reset();
$this->resetServerParameters();
}
}
34 changes: 34 additions & 0 deletions tests/src/Shared/Infrastructure/Mink/MinkSessionRequestHelper.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php

declare(strict_types = 1);

namespace CodelyTv\Tests\Shared\Infrastructure\Mink;

use Behat\Gherkin\Node\PyStringNode;
use Symfony\Component\DomCrawler\Crawler;

final class MinkSessionRequestHelper
{
/** @var MinkHelper */
private $sessionHelper;

public function __construct($sessionHelper)
{
$this->sessionHelper = $sessionHelper;
}

public function sendRequest($method, $url, array $optionalParams = []): void
{
$this->request($method, $url, $optionalParams);
}

public function sendRequestWithPyStringNode($method, $url, PyStringNode $body): void
{
$this->request($method, $url, ['content' => $body->getRaw()]);
}

public function request($method, $url, array $optionalParams = []): Crawler
{
return $this->sessionHelper->sendRequest($method, $url, $optionalParams);
}
}
Loading

0 comments on commit efebedc

Please sign in to comment.