Skip to content

Commit 300a22e

Browse files
committed
Update payload structure
1 parent a67200b commit 300a22e

File tree

3 files changed

+56
-35
lines changed

3 files changed

+56
-35
lines changed

src/Records/Request.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ public function __construct(
2525
public readonly int $requestSize,
2626
public readonly int $responseSize,
2727
public HeaderBag $headers,
28-
public ?InputBag $payload,
28+
public InputBag $payload,
2929
public FileBag $files,
3030
) {
3131
//

src/Sensors/RequestSensor.php

Lines changed: 38 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,17 @@
99
use Laravel\Nightwatch\Concerns\RecordsContext;
1010
use Laravel\Nightwatch\Concerns\RedactsHeaders;
1111
use Laravel\Nightwatch\ExecutionStage;
12+
use Laravel\Nightwatch\Facades\Nightwatch;
1213
use Laravel\Nightwatch\Records\Request as RequestRecord;
1314
use Laravel\Nightwatch\State\RequestState;
1415
use Laravel\Nightwatch\Types\Str;
1516
use Symfony\Component\HttpFoundation\BinaryFileResponse;
16-
use Symfony\Component\HttpFoundation\InputBag;
1717
use Symfony\Component\HttpFoundation\Response;
1818
use Throwable;
1919

2020
use function array_map;
2121
use function array_sum;
22+
use function assert;
2223
use function hash;
2324
use function implode;
2425
use function in_array;
@@ -101,7 +102,7 @@ public function __invoke(Request $request, Response $response): array
101102
$headers->remove('php-auth-pw');
102103
$headers->remove('php-auth-digest');
103104
}),
104-
payload: rescue(static fn () => $request->getPayload(), report: false),
105+
payload: clone $request->request,
105106
files: clone $request->files,
106107
),
107108
function () use ($record) {
@@ -152,16 +153,18 @@ function () use ($record) {
152153
'context' => $this->serializedContext(),
153154
'headers' => Str::text(json_encode((object) $this->redactHeaders($record->headers, $this->redactHeaders)->all(), JSON_THROW_ON_ERROR | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_PRESERVE_ZERO_FRACTION)),
154155
'body' => $this->captureBody && $record->statusCode === 500
155-
? Str::text(json_encode([
156-
'payload' => $record->payload instanceof InputBag ? $this->redactRecursively($record->payload->all()) : null,
157-
'files' => array_map(static fn (UploadedFile $file) => [
158-
'client_name' => $file->getClientOriginalName(),
159-
'client_mime_type' => $file->getClientMimeType(),
160-
'mime_type' => $file->getMimeType(),
161-
'size' => $file->getSize(),
162-
'path' => $file->getPathname(),
163-
], $record->files->all()),
164-
], JSON_THROW_ON_ERROR | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT))
156+
? Str::text(rescue(
157+
fn () => json_encode([
158+
...$this->redactRecursively($record->payload->all()),
159+
'_nightwatch_files' => $this->mapUploadedFilesRecursively($record->files->all()),
160+
], JSON_THROW_ON_ERROR | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_PRESERVE_ZERO_FRACTION),
161+
'{"_nightwatch_error":"Failed to serialize body"}',
162+
static function ($e) {
163+
Nightwatch::unrecoverableExceptionOccurred($e);
164+
165+
return false;
166+
}
167+
))
165168
: '',
166169
];
167170
},
@@ -208,4 +211,27 @@ private function redactRecursively(array $array): array
208211
return ! in_array($key, $this->redactKeys, true) || ! is_string($value) ? $value : '['.strlen($value).' bytes redacted]';
209212
});
210213
}
214+
215+
/**
216+
* @param array<mixed> $files
217+
* @return array<mixed>
218+
*/
219+
private function mapUploadedFilesRecursively(array $files): array
220+
{
221+
return array_map(function ($file) {
222+
if (is_array($file)) {
223+
return $this->mapUploadedFilesRecursively($file);
224+
}
225+
226+
assert($file instanceof UploadedFile);
227+
228+
return [
229+
'client_name' => $file->getClientOriginalName(),
230+
'client_mime_type' => $file->getClientMimeType(),
231+
'mime_type' => $file->getMimeType(),
232+
'size' => $file->getSize(),
233+
'path' => $file->getPathname(),
234+
];
235+
}, $files);
236+
}
211237
}

tests/Feature/Sensors/RequestSensorTest.php

Lines changed: 17 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
use Orchestra\Testbench\Attributes\WithEnv;
2828
use Tests\TestCase;
2929

30-
use function array_keys;
3130
use function fseek;
3231
use function fwrite;
3332
use function hash;
@@ -948,34 +947,31 @@ public function test_it_captures_a_form_request_body_on_unhandled_exceptions():
948947
'user' => [
949948
'username' => 'taylor',
950949
'password' => '$f4c4d3',
950+
'avatar' => UploadedFile::fake()->create('avatar.jpg', 1, 'image/jpeg'),
951951
],
952-
'avatar' => UploadedFile::fake()->create('avatar.jpg', 1, 'image/jpeg'),
953952
]);
954953

955954
$response->assertInternalServerError();
956955
$ingest->assertWrittenTimes(1);
957956
$ingest->assertLatestWrite('request:0.body', function ($body) {
958957
$body = json_decode($body, true);
959-
$this->assertNotNull($body);
960958
$this->assertSame([
961959
'user' => [
962960
'username' => 'taylor',
963961
'password' => '[7 bytes redacted]',
964962
],
965-
], $body['payload']);
966-
$this->assertCount(1, $body['files']);
967-
$this->assertEqualsCanonicalizing([
968-
'client_name',
969-
'client_mime_type',
970-
'mime_type',
971-
'size',
972-
'path',
973-
], array_keys($body['files']['avatar']));
974-
$this->assertSame('avatar.jpg', $body['files']['avatar']['client_name']);
975-
$this->assertSame('image/jpeg', $body['files']['avatar']['client_mime_type']);
976-
$this->assertSame('image/jpeg', $body['files']['avatar']['mime_type']);
977-
$this->assertSame(1024, $body['files']['avatar']['size']);
978-
$this->assertFileExists($body['files']['avatar']['path']);
963+
'_nightwatch_files' => [
964+
'user' => [
965+
'avatar' => [
966+
'client_name' => 'avatar.jpg',
967+
'client_mime_type' => 'image/jpeg',
968+
'mime_type' => 'image/jpeg',
969+
'size' => 1024,
970+
'path' => $body['_nightwatch_files']['user']['avatar']['path'],
971+
],
972+
],
973+
],
974+
], $body);
979975

980976
return true;
981977
});
@@ -1001,14 +997,13 @@ public function test_it_captures_a_json_body_on_unhandled_exceptions(): void
1001997
$ingest->assertWrittenTimes(1);
1002998
$ingest->assertLatestWrite('request:0.body', function ($body) {
1003999
$body = json_decode($body, true);
1004-
$this->assertNotNull($body);
10051000
$this->assertSame([
10061001
'user' => [
10071002
'username' => 'taylor',
10081003
'password' => '[7 bytes redacted]',
10091004
],
1010-
], $body['payload']);
1011-
$this->assertCount(0, $body['files']);
1005+
'_nightwatch_files' => [],
1006+
], $body);
10121007

10131008
return true;
10141009
});
@@ -1036,14 +1031,14 @@ public function test_the_redacted_keys_can_be_customized(): void
10361031
$ingest->assertWrittenTimes(1);
10371032
$ingest->assertLatestWrite('request:0.body', function ($body) {
10381033
$body = json_decode($body, true);
1039-
$this->assertNotNull($body);
10401034
$this->assertSame([
10411035
'user' => [
10421036
'username' => 'taylor',
10431037
'password' => '$f4c4d3',
10441038
],
10451039
'foo' => '[3 bytes redacted]',
1046-
], $body['payload']);
1040+
'_nightwatch_files' => [],
1041+
], $body);
10471042

10481043
return true;
10491044
});

0 commit comments

Comments
 (0)