Skip to content

Commit

Permalink
[5.x] Ability to override how objects are serialized (#1562)
Browse files Browse the repository at this point in the history
* Implement `formatForTelescope` for events

* Implement `formatForTelescope` for gates

* StyleCI
  • Loading branch information
duncanmcclean authored Jan 24, 2025
1 parent 9073cf8 commit bc3df85
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 6 deletions.
4 changes: 3 additions & 1 deletion src/ExtractProperties.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,9 @@ public static function from($target)
return [
$property->getName() => [
'class' => get_class($value),
'properties' => json_decode(json_encode($value), true),
'properties' => method_exists($value, 'formatForTelescope')
? $value->formatForTelescope()
: json_decode(json_encode($value), true),
],
];
} else {
Expand Down
10 changes: 9 additions & 1 deletion src/Watchers/GateWatcher.php
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,15 @@ private function gateResult($result)
private function formatArguments($arguments)
{
return collect($arguments)->map(function ($argument) {
return $argument instanceof Model ? FormatModel::given($argument) : $argument;
if (is_object($argument) && method_exists($argument, 'formatForTelescope')) {
return $argument->formatForTelescope();
}

if ($argument instanceof Model) {
return FormatModel::given($argument);
}

return $argument;
})->toArray();
}
}
41 changes: 41 additions & 0 deletions tests/Watchers/EventWatcherTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
use Dummies\DummyEvent;
use Dummies\DummyEventListener;
use Dummies\DummyEventSubscriber;
use Dummies\DummyEventWithObject;
use Dummies\DummyInvokableEventListener;
use Dummies\DummyObject;
use Dummies\IgnoredEvent;
use Illuminate\Support\Facades\Event;
use Laravel\Telescope\EntryType;
Expand Down Expand Up @@ -60,6 +62,25 @@ public function test_event_watcher_stores_payloads()
$this->assertContains('PHP', $entry->content['payload']['data']);
}

public function test_event_watcher_with_object_property_calls_format_for_telescope_method_if_it_exists()
{
Event::listen(DummyEventWithObject::class, function ($payload) {
//
});

event(new DummyEventWithObject());

$entry = $this->loadTelescopeEntries()->first();

$this->assertSame(EntryType::EVENT, $entry->type);
$this->assertSame(DummyEventWithObject::class, $entry->content['name']);
$this->assertArrayHasKey('thing', $entry->content['payload']);
$this->assertSame(DummyObject::class, $entry->content['payload']['thing']['class']);
$this->assertContains('Telescope', $entry->content['payload']['thing']['properties']);
$this->assertContains('Laravel', $entry->content['payload']['thing']['properties']);
$this->assertContains('PHP', $entry->content['payload']['thing']['properties']);
}

public function test_event_watcher_registers_events_and_stores_payloads_with_subscriber_methods()
{
Event::listen(DummyEvent::class, DummyEventSubscriber::class.'@handleDummyEvent');
Expand Down Expand Up @@ -174,6 +195,26 @@ public function handle()
}
}

class DummyEventWithObject
{
public $thing;

public function __construct()
{
$this->thing = new DummyObject;
}
}

class DummyObject
{
public function formatForTelescope(): array
{
return [
'Telescope', 'Laravel', 'PHP',
];
}
}

class DummyEventSubscriber
{
public function handleDummyEvent($event)
Expand Down
40 changes: 36 additions & 4 deletions tests/Watchers/GateWatcherTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ public function test_gate_watcher_registers_allowed_policy_entries()

$this->assertSame(EntryType::GATE, $entry->type);
$this->assertSame(__FILE__, $entry->content['file']);
$this->assertSame(271, $entry->content['line']);
$this->assertSame(303, $entry->content['line']);
$this->assertSame('create', $entry->content['ability']);
$this->assertSame('allowed', $entry->content['result']);
$this->assertSame([[]], $entry->content['arguments']);
Expand Down Expand Up @@ -156,12 +156,34 @@ public function test_gate_watcher_registers_denied_policy_entries()

$this->assertSame(EntryType::GATE, $entry->type);
$this->assertSame(__FILE__, $entry->content['file']);
$this->assertSame(276, $entry->content['line']);
$this->assertSame(308, $entry->content['line']);
$this->assertSame('update', $entry->content['ability']);
$this->assertSame('denied', $entry->content['result']);
$this->assertSame([[]], $entry->content['arguments']);
}

public function test_gate_watcher_calls_format_for_telescope_method_if_it_exists()
{
$this->app->setBasePath(dirname(__FILE__, 3));

Gate::policy(TestResourceWithFormatForTelescope::class, TestPolicy::class);

try {
(new TestController())->update(new TestResourceWithFormatForTelescope());
} catch (\Exception $ex) {
// ignore
}

$entry = $this->loadTelescopeEntries()->first();

$this->assertSame(EntryType::GATE, $entry->type);
$this->assertSame(__FILE__, $entry->content['file']);
$this->assertSame(308, $entry->content['line']);
$this->assertSame('update', $entry->content['ability']);
$this->assertSame('denied', $entry->content['result']);
$this->assertSame([['Telescope', 'Laravel', 'PHP']], $entry->content['arguments']);
}

public function test_gate_watcher_registers_allowed_response_policy_entries()
{
$this->app->setBasePath(dirname(__FILE__, 3));
Expand All @@ -178,7 +200,7 @@ public function test_gate_watcher_registers_allowed_response_policy_entries()

$this->assertSame(EntryType::GATE, $entry->type);
$this->assertSame(__FILE__, $entry->content['file']);
$this->assertSame(266, $entry->content['line']);
$this->assertSame(298, $entry->content['line']);
$this->assertSame('view', $entry->content['ability']);
$this->assertSame('allowed', $entry->content['result']);
$this->assertSame([[]], $entry->content['arguments']);
Expand All @@ -200,7 +222,7 @@ public function test_gate_watcher_registers_denied_response_policy_entries()

$this->assertSame(EntryType::GATE, $entry->type);
$this->assertSame(__FILE__, $entry->content['file']);
$this->assertSame(281, $entry->content['line']);
$this->assertSame(313, $entry->content['line']);
$this->assertSame('delete', $entry->content['ability']);
$this->assertSame('denied', $entry->content['result']);
$this->assertSame([[]], $entry->content['arguments']);
Expand Down Expand Up @@ -257,6 +279,16 @@ class TestResource
//
}

class TestResourceWithFormatForTelescope
{
public function formatForTelescope(): array
{
return [
'Telescope', 'Laravel', 'PHP',
];
}
}

class TestController
{
use AuthorizesRequests;
Expand Down

0 comments on commit bc3df85

Please sign in to comment.