Skip to content
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

Feature | Record Requests In Telescope #24

Closed
wants to merge 17 commits into from
Prev Previous commit
Next Next commit
Finished tests
  • Loading branch information
Sammyjo20 committed Jul 22, 2022
commit da270b20812a0d00b3ddecb2764ac3012c16b685
42 changes: 30 additions & 12 deletions src/Listeners/RecordSaloonToTelescope.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

namespace Sammyjo20\SaloonLaravel\Listeners;

use Illuminate\Support\Str;
use Laravel\Telescope\IncomingEntry;
use Laravel\Telescope\Telescope;
use Sammyjo20\Saloon\Http\SaloonRequest;
use Sammyjo20\SaloonLaravel\Events\SentSaloonRequest;

class RecordSaloonToTelescope
Expand All @@ -25,39 +25,57 @@ public function handle(SentSaloonRequest $event): void

// We'll attempt to guess if the response is JSON.

$responseIsJson = Str::of($response->header('Content-Type'))->lower()->contains('application/json');
$isJsonResponse = (bool)json_decode($response->body(), true);

// Let's now append any query parameters to the end of the URL, since Saloon's getFullRequestUrl
// does not provide it.

$url = $request->getFullRequestUrl();
$glue = str_contains($url, '?') ? '&' : '?';
$query = http_build_query($request->getQuery());

$fullUrl = empty($query) ? $url : ($url . $glue . $query);
$fullUrl = $this->buildFullUrl($request);

// We'll now record the client request!

$telescope = app()->make(Telescope::class);

$connectorClass = get_class($request->getConnector());
$requestClass = get_class($request);

$entry = IncomingEntry::make([
'method' => $request->getMethod(),
'uri' => $fullUrl,
'headers' => $request->getHeaders(),
'payload' => $request->getData(),
'response_status' => $response->status(),
'response_headers' => $response->headers(),
'response' => $responseIsJson ? $response->json() : $response->body(),
'saloon_connector' => get_class($request->getConnector()),
'saloon_request' => get_class($request),
'response' => $isJsonResponse ? $response->json() : $response->body(),
'saloon_connector' => $connectorClass,
'saloon_request' => $requestClass,
]);

// Create tags

$entry->tags([
'Saloon',
'SaloonConnector:' . get_class($request->getConnector()),
'SaloonRequest:' . get_class($request),
'SaloonConnector:' . $connectorClass,
'SaloonRequest:' . $requestClass,
]);

$telescope->recordClientRequest($entry);
}

/**
* Build the full URL with query parameters
*
* @param SaloonRequest $request
* @return string
* @throws \ReflectionException
* @throws \Sammyjo20\Saloon\Exceptions\SaloonInvalidConnectorException
*/
private function buildFullUrl(SaloonRequest $request): string
{
$url = $request->getFullRequestUrl();
$glue = str_contains($url, '?') ? '&' : '?';
$query = http_build_query($request->getQuery());

return empty($query) ? $url : ($url . $glue . $query);
}
}
36 changes: 28 additions & 8 deletions tests/Feature/TelescopeRecorderTest.php
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
<?php

use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Event;
use Laravel\Telescope\EntryType;
use Laravel\Telescope\ExtractTags;
use Sammyjo20\Saloon\Clients\MockClient;
use Sammyjo20\Saloon\Http\MockResponse;
use Sammyjo20\SaloonLaravel\Events\SentSaloonRequest;
use Sammyjo20\SaloonLaravel\Listeners\RecordSaloonToTelescope;
use Sammyjo20\SaloonLaravel\Tests\Fixtures\Connectors\TestConnector;
use Sammyjo20\SaloonLaravel\Tests\Fixtures\Requests\PostRequest;
use Sammyjo20\SaloonLaravel\Tests\Fixtures\Requests\UserRequest;

beforeEach(function () {
Event::listen(SentSaloonRequest::class, RecordSaloonToTelescope::class);
Expand All @@ -29,26 +32,43 @@
$entry = $entries->sole();
$entryContent = $entry->content;

// Make sure all fields are present and it's stored correctly.

dd($entry);
// Make sure all fields are present, and it's stored correctly.

expect($entryContent)->toBeArray();
expect($entryContent)->toHaveKey('method', 'POST');
expect($entryContent)->toHaveKey('uri', 'https://tests.saloon.dev/api/post');
expect($entryContent)->toHaveKey('uri', 'https://tests.saloon.dev/api/post?test_query=hello');
expect($entryContent)->toHaveKey('headers', ['X-Foo' => 'Bar']);
expect($entryContent)->toHaveKey('payload', ['name' => 'Sammy']);
expect($entryContent)->toHaveKey('response_status', 200);
expect($entryContent)->toHaveKey('response_headers', ['Content-Type' => [0 => 'application/json'], 'X-Foo' => [0 => 'Bar']]);
expect($entryContent)->toHaveKey('response', ['name' => 'Sammy']);
expect($entryContent)->toHaveKey('saloon_connector', TestConnector::class);
expect($entryContent)->toHaveKey('saloon_request', PostRequest::class);
});

test('query parameters are shown in the url of the telescope report', function () {
// Now we need to check the tags

$tags = DB::table('telescope_entries_tags')->get();

expect($tags)->toHaveCount(3);

$saloonTag = $tags->where('tag', 'Saloon')->first();
$requestTag = $tags->where('tag', 'SaloonRequest:' . PostRequest::class)->first();
$connectorTag = $tags->where('tag', 'SaloonConnector:' . TestConnector::class)->first();

expect($saloonTag)->not()->toBeNull();
expect($requestTag)->not()->toBeNull();
expect($connectorTag)->not()->toBeNull();
});

test('it will format the response data as json if it can find the correct content type header', function () {
// Test it won't format without.
test('it will format the response data as json if it can determine the response is JSON', function () {
$mockClient = new MockClient([
MockResponse::make('Plain Text Response', 200, ['Content-Type' => 'text/plain'])
]);

UserRequest::make()->send($mockClient);

$entry = $this->loadTelescopeEntries()->where('type', EntryType::CLIENT_REQUEST)->sole();
$entryContent = $entry->content;

expect($entryContent)->toHaveKey('response', 'Plain Text Response');
});
7 changes: 7 additions & 0 deletions tests/Fixtures/Requests/PostRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,11 @@ public function defaultHeaders(): array
'X-Foo' => 'Bar',
];
}

public function defaultQuery(): array
{
return [
'test_query' => 'hello',
];
}
}
2 changes: 2 additions & 0 deletions tests/TestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ public function getPackageProviders($app)
protected function defineDatabaseMigrations()
{
$this->loadMigrationsFrom(__DIR__ . '/../vendor/laravel/telescope/database/migrations');

$this->artisan('migrate');
}

/**
Expand Down