Skip to content

Commit

Permalink
Merge branch 'main' into fix-invalid-view-trace
Browse files Browse the repository at this point in the history
  • Loading branch information
rubenvanassche committed Apr 29, 2024
2 parents 217fe81 + 86da38d commit 9a1b641
Show file tree
Hide file tree
Showing 8 changed files with 235 additions and 28 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/run-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ jobs:
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
extensions: mbstring, fileinfo
extensions: mbstring, fileinfo, pdo_sqlite
coverage: none
tools: composer:v2

Expand Down
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

All notable changes to `laravel-ignition` will be documented in this file

## 2.6.0 - 2024-04-29

### What's Changed

* Livewire 3 by @timvandijck en @riasvdv in https://github.com/spatie/laravel-ignition/pull/193

## 2.5.2 - 2024-04-16

### What's Changed
Expand Down
10 changes: 5 additions & 5 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,19 +23,19 @@
"ext-mbstring": "*",
"illuminate/support": "^10.0|^11.0",
"spatie/flare-client-php": "^1.3.5",
"spatie/ignition": "^1.13.2",
"spatie/ignition": "^1.14",
"symfony/console": "^6.2.3|^7.0",
"symfony/var-dumper": "^6.2.3|^7.0"
},
"require-dev": {
"livewire/livewire": "^2.11|^3.3.5",
"mockery/mockery": "^1.5.1",
"openai-php/client": "^0.8.1",
"orchestra/testbench": "^8.0|^9.0",
"pestphp/pest": "^2.30",
"phpstan/extension-installer": "^1.2",
"orchestra/testbench": "8.22.3|^9.0",
"pestphp/pest": "^2.34",
"phpstan/extension-installer": "^1.3.1",
"phpstan/phpstan-deprecation-rules": "^1.1.1",
"phpstan/phpstan-phpunit": "^1.3.3",
"phpstan/phpstan-phpunit": "^1.3.16",
"vlucas/phpdotenv": "^5.5"
},
"suggest": {
Expand Down
40 changes: 34 additions & 6 deletions src/ContextProviders/LaravelLivewireRequestContextProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,26 @@ public function toArray(): array
/** @return array<string, mixed> */
protected function getLivewireInformation(): array
{
if ($this->request->has('components')) {
$data = [];

foreach ($this->request->get('components') as $component) {
$snapshot = json_decode($component['snapshot'], true);

$class = app(ComponentRegistry::class)->getClass($snapshot['memo']['name']);

$data[] = [
'component_class' => $class ?? null,
'data' => $snapshot['data'],
'memo' => $snapshot['memo'],
'updates' => $this->resolveUpdates($component['updates']),
'calls' => $component['calls'],
];
}

return $data;
}

/** @phpstan-ignore-next-line */
$componentId = $this->request->input('fingerprint.id');

Expand All @@ -56,12 +76,20 @@ protected function getLivewireInformation(): array
$componentClass = null;
}

/** @phpstan-ignore-next-line */
$updates = $this->request->input('updates') ?? [];

/** @phpstan-ignore-next-line */
$updates = $this->request->input('updates') ?? [];

return [
'component_class' => $componentClass,
'component_alias' => $componentAlias,
'component_id' => $componentId,
'data' => $this->resolveData(),
'updates' => $this->resolveUpdates(),
[
'component_class' => $componentClass,
'component_alias' => $componentAlias,
'component_id' => $componentId,
'data' => $this->resolveData(),
'updates' => $this->resolveUpdates($updates),
],
];
}

Expand All @@ -86,7 +114,7 @@ protected function resolveData(): array
}

/** @return array<string, mixed> */
protected function resolveUpdates(): array
protected function resolveUpdates(array $updates): array
{
/** @phpstan-ignore-next-line */
$updates = $this->request->input('updates') ?? [];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
use Spatie\LaravelIgnition\Tests\TestClasses\FakeLivewireManager;

beforeEach(function () {
$this->livewireManager = FakeLivewireManager::setUp();
})->skip(LIVEWIRE_VERSION_3, 'Missing Livewire 3 support.');
$this->livewireManager = resolve(FakeLivewireManager::class);
})->skip(LIVEWIRE_VERSION_2, 'Only test Livewire 3.');

it('returns the referer url and method', function () {
$context = createRequestContext([
Expand All @@ -17,15 +17,15 @@

$request = $context->getRequest();

expect($request['url'])->toBe('http://localhost/referred');
expect($request['method'])->toBe('GET');
expect($request['url'])->toBe('http://localhost/POST');
expect($request['method'])->toBe('POST');
});

it('returns livewire component information', function () {
$alias = 'fake-component';
$class = 'fake-class';

$this->livewireManager->fakeAliases[$alias] = $class;
$this->livewireManager->addAlias($alias, $class);

$context = createRequestContext([
'path' => 'http://localhost/referred',
Expand All @@ -36,9 +36,8 @@

$livewire = $context->toArray()['livewire'];

expect($livewire['component_id'])->toBe($id);
expect($livewire['component_alias'])->toBe($alias);
expect($livewire['component_class'])->toBe($class);
expect($livewire[0]['component_id'])->toBe($id);
expect($livewire[0]['component_alias'])->toBe($alias);
});

it('returns livewire component information when it does not exist', function () {
Expand All @@ -51,9 +50,9 @@

$livewire = $context->toArray()['livewire'];

expect($livewire['component_id'])->toBe($id);
expect($livewire['component_alias'])->toBe($name);
expect($livewire['component_class'])->toBeNull();
expect($livewire[0]['component_id'])->toBe($id);
expect($livewire[0]['component_alias'])->toBe($name);
expect($livewire[0]['component_class'])->toBeNull();
});

it('removes ids from update payloads', function () {
Expand All @@ -75,9 +74,9 @@

$livewire = $context->toArray()['livewire'];

expect($livewire['component_id'])->toBe($id);
expect($livewire['component_alias'])->toBe($name);
expect($livewire['component_class'])->toBeNull();
expect($livewire[0]['component_id'])->toBe($id);
expect($livewire[0]['component_alias'])->toBe($name);
expect($livewire[0]['component_class'])->toBeNull();
});

it('combines data into one payload', function () {
Expand Down Expand Up @@ -150,7 +149,7 @@
"collection" => ['a', 'b'],
"stringable" => "Test",
"wireable" => ['a', 'b'],
], $livewire['data']);
], $livewire[0]['data']);
});

// Helpers
Expand Down
172 changes: 172 additions & 0 deletions tests/ContextProviders/LegacyLivewireRequestContextProviderTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
<?php

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
use Spatie\LaravelIgnition\ContextProviders\LaravelLivewireRequestContextProvider;
use Spatie\LaravelIgnition\Tests\TestClasses\FakeLivewireManager;

beforeEach(function () {
$this->livewireManager = FakeLivewireManager::setUp();
})->skip(LIVEWIRE_VERSION_3, 'Only test Livewire 2.');

it('returns the referer url and method', function () {
$context = createLegacyRequestContext([
'path' => 'referred',
'method' => 'GET',
]);

$request = $context->getRequest();

expect($request['url'])->toBe('http://localhost/referred');
expect($request['method'])->toBe('GET');
});

it('returns livewire component information', function () {
$alias = 'fake-component';
$class = 'fake-class';

$this->livewireManager->fakeAliases[$alias] = $class;

$context = createLegacyRequestContext([
'path' => 'http://localhost/referred',
'method' => 'GET',
'id' => $id = uniqid(),
'name' => $alias,
]);

$livewire = $context->toArray()['livewire'];

expect($livewire[0]['component_id'])->toBe($id);
expect($livewire[0]['component_alias'])->toBe($alias);
expect($livewire[0]['component_class'])->toBe($class);
});

it('returns livewire component information when it does not exist', function () {
$context = createLegacyRequestContext([
'path' => 'http://localhost/referred',
'method' => 'GET',
'id' => $id = uniqid(),
'name' => $name = 'fake-component',
]);

$livewire = $context->toArray()['livewire'];

expect($livewire[0]['component_id'])->toBe($id);
expect($livewire[0]['component_alias'])->toBe($name);
expect($livewire[0]['component_class'])->toBeNull();
});

it('removes ids from update payloads', function () {
$context = createLegacyRequestContext([
'path' => 'http://localhost/referred',
'method' => 'GET',
'id' => $id = uniqid(),
'name' => $name = 'fake-component',
], [
[
'type' => 'callMethod',
'payload' => [
'id' => 'remove-me',
'method' => 'chang',
'params' => ['a'],
],
],
]);

$livewire = $context->toArray()['livewire'];

expect($livewire[0]['component_id'])->toBe($id);
expect($livewire[0]['component_alias'])->toBe($name);
expect($livewire[0]['component_class'])->toBeNull();
});

it('combines data into one payload', function () {
$context = createLegacyRequestContext([
'path' => 'http://localhost/referred',
'method' => 'GET',
'id' => uniqid(),
'name' => 'fake-component',
], [], [
'data' => [
'string' => 'Ruben',
'array' => ['a', 'b'],
'modelCollection' => [],
'model' => [],
'date' => '2021-11-10T14:20:36+0000',
'collection' => ['a', 'b'],
'stringable' => 'Test',
'wireable' => ['a', 'b'],
],
'dataMeta' => [
'modelCollections' => [
'modelCollection' => [
'class' => 'App\\\\Models\\\\User',
'id' => [1, 2, 3, 4],
'relations' => [],
'connection' => 'mysql',
],
],
'models' => [
'model' => [
'class' => 'App\\\\Models\\\\User',
'id' => 1,
'relations' => [],
'connection' => 'mysql',
],
],
'dates' => [
'date' => 'carbonImmutable',
],
'collections' => [
'collection',
],
'stringables' => [
'stringable',
],
'wireables' => [
'wireable',
],
],
]);

$livewire = $context->toArray()['livewire'];

$this->assertEquals([
"string" => "Ruben",
"array" => ['a', 'b'],
"modelCollection" => [
"class" => "App\\\\Models\\\\User",
"id" => [1, 2, 3, 4],
"relations" => [],
"connection" => "mysql",
],
"model" => [
"class" => "App\\\\Models\\\\User",
"id" => 1,
"relations" => [],
"connection" => "mysql",
],
"date" => "2021-11-10T14:20:36+0000",
"collection" => ['a', 'b'],
"stringable" => "Test",
"wireable" => ['a', 'b'],
], $livewire[0]['data']);
});

// Helpers
function createLegacyRequestContext(array $fingerprint, array $updates = [], array $serverMemo = []): LaravelLivewireRequestContextProvider
{
$providedRequest = null;

Route::post('livewire', function (Request $request) use (&$providedRequest) {
$providedRequest = $request;
})->name('livewire.message');

test()->postJson('livewire', [
'fingerprint' => $fingerprint,
'serverMemo' => $serverMemo,
'updates' => $updates,
], ['X-Livewire' => 1]);

return new LaravelLivewireRequestContextProvider($providedRequest, test()->livewireManager);
}
1 change: 1 addition & 0 deletions tests/Pest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
use Livewire\Mechanisms\ComponentRegistry;
use Spatie\LaravelIgnition\Tests\TestCase;

define('LIVEWIRE_VERSION_2', ! class_exists(ComponentRegistry::class));
define('LIVEWIRE_VERSION_3', class_exists(ComponentRegistry::class));

uses(TestCase::class)->in(__DIR__);
Expand Down
3 changes: 2 additions & 1 deletion tests/TestClasses/FakeLivewireManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Spatie\LaravelIgnition\Tests\TestClasses;

use Livewire\LivewireManager;
use Livewire\Mechanisms\ComponentRegistry;

class FakeLivewireManager extends LivewireManager
{
Expand All @@ -24,7 +25,7 @@ public function isDefinitelyLivewireRequest()

public function getClass($alias)
{
return $this->fakeAliases[$alias] ?? parent::getClass($alias);
return $this->fakeAliases[$alias] ?? app(ComponentRegistry::class)->getClass($alias);
}

public function addAlias(string $alias, string $class): void
Expand Down

0 comments on commit 9a1b641

Please sign in to comment.