Composing Macros

  • Macros can call other macros for layered behaviour
  • Most test assertion methods accept closures, making them composable
  • This removes repeated setup code and keeps tests focused on intent
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Http;
use Illuminate\Http\Client\Request;

Request::macro('hasGraphQLCall', function ($mutation, array $data) {
    $data = Arr::undot($data);
    $arguments = $this->data;

    if (!array_key_exists('variables', $arguments)) {
        return false;
    }

    if (array_intersect($data, $arguments['variables']) != $data) {
        return false;
    }

    return $this->hasHeader('Authorization', 'Bearer ' . config('services.api.token'))
        && $this->url() == config('services.api.url')
        && $this['operationName'] === $mutation;
});

Http::macro('assertGraphQLCall', function ($mutation, $data) {
    Http::assertSent(function (Request $request) use ($mutation, $data) {
        return $request->hasGraphQLCall($mutation, $data);
    });
});

Http::macro('sendsGraphQL', function () {
    Http::fake([
        config('services.api.url') => Http::response(['data' => (object) [
            'some' => 'data',
        ]]),
    ]);
});

← / → navigate · N notes · Esc exit