Coder Social home page Coder Social logo

php-http-fixture-client's Introduction

Fixture client for PHP-HTTP

PHP from Packagist Latest Version on Packagist Software License Buy us a tree Build Status Scrutinizer Coverage Scrutinizer Code Quality Made by SWIS

This is a fixture client for PHP-HTTP and is meant for testing purposes. It maps requests to static fixtures.

Install

$ composer require --dev swisnl/php-http-fixture-client

Usage

// Create client
$responseBuilder = new \Swis\Http\Fixture\ResponseBuilder('/path/to/fixtures');
$client = new \Swis\Http\Fixture\Client($responseBuilder);

// Send request
$response = $client->sendRequest(new Request(...));

Fixture mapping

All requests send using this client are mapped to static fixtures located in the provided path. URLs are transformed to file paths by using the domain and path fragments and (optionally) the method and/or the query params (sorted alphabetically). A list of possible fixture paths is made and handled in order of specificity:

  1. {path}.{query}.{method}.mock
  2. {path}.{query}.mock
  3. {path}.{method}.mock
  4. {path}.mock

Please see the following table for some examples.

URL Method Possible fixtures (in order of specificity)
http://example.com/api/articles/1 GET /path/to/fixtures/example.com/api/articles/1.get.mock
/path/to/fixtures/example.com/api/articles/1.mock
http://example.com/api/articles POST /path/to/fixtures/example.com/api/articles.post.mock
/path/to/fixtures/example.com/api/articles.mock
http://example.com/api/comments?query=json GET /path/to/fixtures/example.com/api/comments.query=json.get.mock
/path/to/fixtures/example.com/api/comments.query=json.mock
/path/to/fixtures/example.com/api/comments.get.mock
/path/to/fixtures/example.com/api/comments.mock
http://example.com/api/comments?query=json&order=id GET /path/to/fixtures/example.com/api/comments.order=id&query=json.get.mock
/path/to/fixtures/example.com/api/comments.order=id&query=json.mock
/path/to/fixtures/example.com/api/comments.get.mock
/path/to/fixtures/example.com/api/comments.mock

Domain aliases

The ReponseBuilder can be instructed to use aliases for domains using setDomainAliases([...]). When configured, the provided aliases will be normalized when transforming requests to file paths. You should provide aliases in the form of ['alias' => 'abstract'].

Ignored query parameters

The ReponseBuilder can be instructed to ignore certain query parameters using setIgnoredQueryParameters([...]). When configured, the provided parameters will be ignored when transforming requests to file paths. You should only provide the parameter name, not the value. This allows you to ignore 'dynamic' parameters that change in each test execution. Parameters are matched strictly, after url decoding, so 'foo' will match 'foo=bar', but not 'foo[]=bar'.

Strict mode

The ReponseBuilder can be set to strict mode using setStrictMode(true). When in strict mode, only the first possible fixture path will be used. This means that both the method and query params must be present in the fixture file name and it does not fall back to other fixture files.

Helper

Please see https://swisnl.github.io/php-http-fixture-client/#helper for the URL helper.

Body

The body of a request is loaded directly from a fixture with the file extension .mock. The contents of this file can be anything that is a valid HTTP response, e.g. HTML, JSON or even images. If a fixture can not be found, a MockNotFoundException will be thrown. This exception has a convenience method getPossiblePaths() which lists all file paths that were checked, in order of specificity.

Headers (optional)

The headers of a request are loaded from a fixture with the file extension .headers. This is a simple JSON object with headers, e.g.

{
  "X-Made-With": "PHPUnit"
}

Status (optional)

The status code of a request is loaded from a fixture with the file extension .status. This is a plain file containing only the HTTP status code. If no .status file is found, 200 OK will be used.

Mocks (advanced)

This client extends php-http/mock-client, which allows you to add custom responses and exceptions that ignore fixture files. Please see the mock-client documentation for more information.

N.B. A default response can not be set because this client uses that under the hood.

Change log

Please see CHANGELOG for more information on what has changed recently.

Testing

$ composer test

Contributing

Please see CONTRIBUTING and CODE_OF_CONDUCT for details.

Security

If you discover any security related issues, please email [email protected] instead of using the issue tracker.

License

The MIT License (MIT). Please see License File for more information.

This package is Treeware. If you use it in production, then we ask that you buy the world a tree to thank us for our work. By contributing to the Treeware forest you’ll be creating employment for local families and restoring wildlife habitats.

SWIS ❤️ Open Source

SWIS is a web agency from Leiden, the Netherlands. We love working with open source software.

php-http-fixture-client's People

Contributors

dependabot[bot] avatar github-actions[bot] avatar jazo avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

Forkers

pbxapi taggers-io

php-http-fixture-client's Issues

possibility to have different fixtures for same endpoint

Detailed description

I have path api-example.com/orders.json
I need 2 tests for 2 cases

  1. successful order creation
  2. order was not created for some reason (response contains reason)

while reading docs I didn't find any example how to achieve it

Context

Same http endpoint can respond with big variety of responses that means different logic for client

Response path always out of bounds on Windows

ResponseBuilder:174 will always throw an exception on Windows even if the path is valid.

if (realpath(\dirname($file)) !== \dirname($file)) {
    throw new \RuntimeException(sprintf('Path to file "%s" is out of bounds.', $file));
}

This is because realpath in Windows will have backslashes as a directory separator between all directories, whereas dirname will only have backslashes for the part that's not already in the $file path.

realpath(\dirname($file)); // C:\dev\my-project\tests\stubs\responses\some-website.com\endpoint\123.get.mock
\dirname($file);           // C:\dev\my-project\tests\stubs\responses/some-website.com/endpoint/123.get.mock

Is there a reason for this specific condition instead of just file_exists()?

if (! file_exists($file)) {
    throw new \RuntimeException(sprintf('Path to file "%s" is out of bounds.', $file));
}

Getting possible mock file paths can result in a collision

Endpoint 1:
api/endpoint?foo_bar_fizz=buzz

Endpoint 2:
api/endpoint?foo=bar&fizz=buzz

Getting possible mock file paths for both the endpoints will result in the same mock file:
api/endpoint.foo-bar-fizz-buzz.mock

I think changes need to be made in the getQueryFromRequst method in the ResponseBuilder.

Client breaking change

php-http/mock-client introduced a breaking change in a minor release. This breaks Swis\Http\Fixture\Client::doSendRequest because the parent method no longer exists.

https://github.com/php-http/mock-client/blame/a797c2a9122cccafcce14773b8a24d2808a9ab44/src/Client.php#L87

Adding this new method would fix it:

/**
 * {@inheritdoc}
 */
public function sendRequest(RequestInterface $request): ResponseInterface
{
    $this->setDefaultResponse($this->fixtureResponseBuilder->build($request));

    return parent::sendRequest($request);
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.