Skip to content

Minor requirements updates #1

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Jan 30, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,5 @@ composer.lock
state/*-*
build/*
phpunit.xml
.php_cs.cache
.php_cs.result.cache
19 changes: 19 additions & 0 deletions .php_cs.dist
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

$finder = PhpCsFixer\Finder::create()
->in(__DIR__ . '/src')
->in(__DIR__ . '/tests');

return PhpCsFixer\Config::create()
->setRules([
'@Symfony' => true,
'array_syntax' => ['syntax' => 'short'],
'combine_consecutive_unsets' => true,
'concat_space' => ['spacing' => 'one'],
'return_type_declaration' => ['space_before' => 'one'],
'no_unreachable_default_argument_value' => false,
'yoda_style' => false,
'ordered_imports' => ['sortAlgorithm' => 'alpha'],
'pre_increment' => false,
])
->setFinder($finder);
3 changes: 1 addition & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
language: php

php:
- 7.1
- 7.2
- 7.3

Expand All @@ -11,5 +10,5 @@ before_script:
sudo: false

script:
- ./vendor/bin/phpcs --standard=vendor/internations/kodierungsregelwerksammlung/ruleset.xml ./src/
- composer lint:check
- ./vendor/bin/phpunit
39 changes: 32 additions & 7 deletions composer.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "internations/http-mock",
"description": "Mock HTTP requests on the server side in your PHP unit tests",
"description": "Mock HTTP requests on the server side in your PHP unit tests, PSR/7 Fork of internations version",
"license": "MIT",
"authors": [
{
Expand All @@ -10,18 +10,23 @@
{
"name": "Max Beutel",
"email": "max.beutel@internations.org"
},
{
"name": "Joshua Eichorn",
"email": "joshua.eichorn@pagely.com"
}
],
"require": {
"php": "~7.1",
"silex/silex": "~2.0",
"guzzle/guzzle": ">=3.8",
"symfony/process": "~3|~4",
"php": "~7.2",
"symfony/process": "~3|~4|~5",
"jeremeamia/superclosure": "~2",
"lstrojny/hmmmath": ">=0.5.0"
"lstrojny/hmmmath": ">=0.5.0",
"guzzlehttp/guzzle": "^6.3",
"slim/slim": "^3.12",
"friendsofphp/php-cs-fixer": "^2.16",
"sensiolabs/security-checker": "^6.0"
},
"require-dev": {
"internations/kodierungsregelwerksammlung": "~0.23.0",
"internations/testing-component": "1.0.1",
"phpunit/phpunit": "^7"
},
Expand All @@ -30,5 +35,25 @@
},
"autoload-dev": {
"psr-4": {"InterNations\\Component\\HttpMock\\Tests\\": "tests/"}
},
"scripts": {
"auto-scripts": [
"@security-check"
],
"post-install-cmd": [
"@auto-scripts"
],
"post-update-cmd": [
"@auto-scripts"
],
"lint": [
"php-cs-fixer fix --ansi --verbose --show-progress=estimating"
],
"lint:check": [
"@lint --dry-run"
],
"security-check": [
"security-checker security:check"
]
}
}
2 changes: 1 addition & 1 deletion doc/recording.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

Once a SUT (system under test) has fired HTTP requests, we often want to validate that our assumption about the nature
of those requests are valid. For that purpose HTTP mock stores every request for later inspection. The recorded requests
are presented as an instance of `InterNations\Component\HttpMock\Request\UnifiedRequest`.
are presented as an instance of `Slim\Http\Response`.

```php
$this->http->mock
Expand Down
3 changes: 2 additions & 1 deletion doc/server.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ Overview of the internal server functionality
```
POST /_expectation
{
response (required): serialized Symfony response
response (required): stringified http respopnse
responseCallback (optional): serialized closure that is passed in the response, and can return a new Response
matcher (optional): serialized list of closures
limiter (optional): serialized closure that limits the validity of the expectation
}
Expand Down
4 changes: 2 additions & 2 deletions doc/start.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,10 @@ class ExampleTest extends PHPUnit_Framework_TestCase
->end();
$this->http->setUp();

$this->assertSame('mocked body', $this->http->client->post('http://localhost:8082/foo')->send()->getBody(true));
$this->assertSame('mocked body', (string)$this->http->client->post('http://localhost:8082/foo')->getBody());

$this->assertSame('POST', $this->http->requests->latest()->getMethod());
$this->assertSame('/foo', $this->http->requests->latest()->getPath());
$this->assertSame('/foo', $this->http->requests->latest()->getUri()->getPath());
}
}
```
13 changes: 6 additions & 7 deletions doc/stubbing.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ The example above say: when we see a `GET` request asking for `/resource` respon
What we see here is internally syntactic sugar for the following, more verbose, example using plain callbacks.

```php
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Psr\Http\Message\RequestInterface as Request;
use Psr\Http\Message\ResponseInterface as Response;

$this->http->mock
->when()
Expand All @@ -43,21 +43,20 @@ $this->http->mock
->end();
```

What we can see above is that we use standard Symfony HTTP foundation `Request` and `Response` objects. If you want to
learn more about it, look at
[Symfony’s documentation](https://symfony.com/doc/current/components/http_foundation/introduction.html).
What we can see above is that we use standard PSR/7 Request Response, we use the Guzzle implementation on the Client and the Slim implementation on the server side, hurrah standards

Let’s have a look what we can do with matching and response building shortcuts:

```php
use Symfony\Component\HttpFoundation\Response;
use Psr\Http\Message\ResponseInterface as Response;
use Slim\Http\StatusCode;

$this->http->mock
->when()
->methodIs('GET')
->pathIs('/resource')
->then()
->statusCode(Response::HTTP_NOT_FOUND)
->statusCode(StatusCode::HTTP_NOT_FOUND)
->header('X-Custom-Header', 'Header Value')
->body('response')
->end();`
Expand Down
4 changes: 4 additions & 0 deletions public/index.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
<?php
if (empty($_SERVER['REQUEST_URI'])) {
$_SERVER['REQUEST_URI'] = '/_me';
$_SERVER['REQUEST_METHOD'] = 'GET';
}
$filename = __DIR__ . preg_replace('#(\?.*)$#', '', $_SERVER['REQUEST_URI']);
if (php_sapi_name() === 'cli-server' && is_file($filename)) {
return false;
Expand Down
11 changes: 8 additions & 3 deletions src/Expectation.php
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
<?php

namespace InterNations\Component\HttpMock;

use Closure;
use InterNations\Component\HttpMock\Matcher\ExtractorFactory;
use InterNations\Component\HttpMock\Matcher\MatcherFactory;
use InterNations\Component\HttpMock\Matcher\MatcherInterface;
use SuperClosure\SerializableClosure;
use Closure;

class Expectation
{
Expand All @@ -29,8 +30,7 @@ public function __construct(
MatcherFactory $matcherFactory,
ExtractorFactory $extractorFactory,
Closure $limiter
)
{
) {
$this->matcherFactory = $matcherFactory;
$this->responseBuilder = new ResponseBuilder($mockBuilder);
$this->extractorFactory = $extractorFactory;
Expand Down Expand Up @@ -142,6 +142,11 @@ public function getResponse()
return $this->responseBuilder->getResponse();
}

public function getResponseCallback()
{
return $this->responseBuilder->getResponseCallback();
}

public function getLimiter()
{
return new SerializableClosure($this->limiter);
Expand Down
3 changes: 2 additions & 1 deletion src/Matcher/AbstractMatcher.php
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
<?php

namespace InterNations\Component\HttpMock\Matcher;

use Closure;
use Psr\Http\Message\RequestInterface as Request;
use SuperClosure\SerializableClosure;
use Symfony\Component\HttpFoundation\Request;

abstract class AbstractMatcher implements MatcherInterface
{
Expand Down
1 change: 1 addition & 0 deletions src/Matcher/ClosureMatcher.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<?php

namespace InterNations\Component\HttpMock\Matcher;

use Closure;
Expand Down
18 changes: 12 additions & 6 deletions src/Matcher/ExtractorFactory.php
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
<?php

namespace InterNations\Component\HttpMock\Matcher;

use Symfony\Component\HttpFoundation\Request;
use Psr\Http\Message\RequestInterface as Request;

class ExtractorFactory
{
Expand All @@ -17,7 +18,7 @@ public function createPathExtractor()
$basePath = $this->basePath;

return static function (Request $request) use ($basePath) {
return substr_replace($request->getPathInfo(), '', 0, strlen($basePath));
return substr_replace($request->getUri()->getPath(), '', 0, strlen($basePath));
};
}

Expand All @@ -31,28 +32,33 @@ public function createMethodExtractor()
public function createParamExtractor($param)
{
return static function (Request $request) use ($param) {
return $request->query->get($param);
return $request->getParam($param);
};
}

public function createParamExistsExtractor($param)
{
return static function (Request $request) use ($param) {
return $request->query->has($param);
return $request->getParam($param, false) !== false;
};
}

public function createHeaderExtractor($header)
{
return static function (Request $request) use ($header) {
return $request->headers->get($header);
$r = $request->getHeaderLine($header);
if (empty($r)) {
return null;
}

return $r;
};
}

public function createHeaderExistsExtractor($header)
{
return static function (Request $request) use ($header) {
return $request->headers->has($header);
return $request->hasHeader($header);
};
}
}
1 change: 1 addition & 0 deletions src/Matcher/MatcherFactory.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<?php

namespace InterNations\Component\HttpMock\Matcher;

use Closure;
Expand Down
3 changes: 2 additions & 1 deletion src/Matcher/MatcherInterface.php
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
<?php

namespace InterNations\Component\HttpMock\Matcher;

use SuperClosure\SerializableClosure;
use Closure;
use SuperClosure\SerializableClosure;

interface MatcherInterface
{
Expand Down
1 change: 1 addition & 0 deletions src/Matcher/RegexMatcher.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<?php

namespace InterNations\Component\HttpMock\Matcher;

class RegexMatcher extends AbstractMatcher
Expand Down
1 change: 1 addition & 0 deletions src/Matcher/StringMatcher.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<?php

namespace InterNations\Component\HttpMock\Matcher;

class StringMatcher extends AbstractMatcher
Expand Down
1 change: 1 addition & 0 deletions src/MockBuilder.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<?php

namespace InterNations\Component\HttpMock;

use Closure;
Expand Down
15 changes: 8 additions & 7 deletions src/PHPUnit/HttpMockFacade.php
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
<?php

namespace InterNations\Component\HttpMock\PHPUnit;

use Guzzle\Http\Client;
use GuzzleHttp\Client;
use InterNations\Component\HttpMock\Matcher\ExtractorFactory;
use InterNations\Component\HttpMock\Matcher\MatcherFactory;
use InterNations\Component\HttpMock\MockBuilder;
Expand All @@ -10,15 +11,15 @@
use RuntimeException;

/**
* @property-read Server $server The HTTP mock server that is currently running
* @property-read MatcherFactory $matches An instance of the matcher factory
* @property-read MockBuilder $mock An instance of the mock builder
* @property-read RequestCollectionFacade $requests Convenient access to recorded requests
* @property-read Client $client A pre configured HTTP for client for the currently running server
* @property Server $server The HTTP mock server that is currently running
* @property MatcherFactory $matches An instance of the matcher factory
* @property MockBuilder $mock An instance of the mock builder
* @property RequestCollectionFacade $requests Convenient access to recorded requests
* @property Client $client A pre configured HTTP for client for the currently running server
*/
class HttpMockFacade
{
/** @var array */
/** @var array */
private $services = [];

private $basePath;
Expand Down
Loading