Skip to content

Commit ee70e06

Browse files
authored
Add Livewire v4 support (#474)
* Add Livewire v4 support * Update tests to use dynamic Livewire update endpoint Livewire v4 changed the update endpoint path from /livewire/update to a dynamic path. Use the livewireUpdateEndpoint() helper to support both v3 and v4. * Fix code styling --------- Co-authored-by: joshhanley <882837+joshhanley@users.noreply.github.com>
1 parent 0c67198 commit ee70e06

File tree

6 files changed

+63
-31
lines changed

6 files changed

+63
-31
lines changed

.github/workflows/tests.yml

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,12 @@ jobs:
3535
matrix:
3636
php: [8.1, 8.2, 8.3, 8.4]
3737
laravel: [10, 11, 12]
38+
livewire: [3, 4]
3839
stability: [prefer-lowest, prefer-stable]
3940
include:
4041
- php: 8.5
4142
laravel: 12
43+
livewire: 4
4244
stability: prefer-stable
4345
exclude:
4446
- php: 8.1
@@ -48,7 +50,7 @@ jobs:
4850
- php: 8.4
4951
laravel: 10
5052

51-
name: PHP ${{ matrix.php }} - Laravel ${{ matrix.laravel }} - Stability ${{ matrix.stability }} - MySQL 5.7
53+
name: PHP ${{ matrix.php }} - Laravel ${{ matrix.laravel }} - Livewire ${{ matrix.livewire }} - Stability ${{ matrix.stability }} - MySQL 5.7
5254

5355
steps:
5456
- name: Checkout code
@@ -70,6 +72,10 @@ jobs:
7072
run: |
7173
composer require cachewerk/relay --no-interaction --no-update
7274
75+
- name: Require Livewire ${{ matrix.livewire }}
76+
run: |
77+
composer require livewire/livewire:^${{ matrix.livewire }}.0 --no-interaction --no-update
78+
7379
- name: Install dependencies
7480
run: |
7581
composer update --prefer-dist --no-interaction --no-progress --${{ matrix.stability }}
@@ -108,9 +114,10 @@ jobs:
108114
matrix:
109115
php: [8.3]
110116
laravel: [12]
117+
livewire: [3, 4]
111118
stability: [prefer-stable]
112119

113-
name: PHP ${{ matrix.php }} - Laravel ${{ matrix.laravel }} - Stability ${{ matrix.stability }} - MariaDB 10
120+
name: PHP ${{ matrix.php }} - Laravel ${{ matrix.laravel }} - Livewire ${{ matrix.livewire }} - Stability ${{ matrix.stability }} - MariaDB 10
114121

115122
steps:
116123
- name: Checkout code
@@ -132,6 +139,10 @@ jobs:
132139
run: |
133140
composer require cachewerk/relay --no-interaction --no-update
134141
142+
- name: Require Livewire ${{ matrix.livewire }}
143+
run: |
144+
composer require livewire/livewire:^${{ matrix.livewire }}.0 --no-interaction --no-update
145+
135146
- name: Install dependencies
136147
run: |
137148
composer update --prefer-dist --no-interaction --no-progress --${{ matrix.stability }}
@@ -168,9 +179,10 @@ jobs:
168179
matrix:
169180
php: [8.3]
170181
laravel: [12]
182+
livewire: [3, 4]
171183
stability: [prefer-stable]
172184

173-
name: PHP ${{ matrix.php }} - Laravel ${{ matrix.laravel }} - Stability ${{ matrix.stability }} - PostgreSQL 14
185+
name: PHP ${{ matrix.php }} - Laravel ${{ matrix.laravel }} - Livewire ${{ matrix.livewire }} - Stability ${{ matrix.stability }} - PostgreSQL 14
174186

175187
steps:
176188
- name: Checkout code
@@ -192,6 +204,10 @@ jobs:
192204
run: |
193205
composer require cachewerk/relay --no-interaction --no-update
194206
207+
- name: Require Livewire ${{ matrix.livewire }}
208+
run: |
209+
composer require livewire/livewire:^${{ matrix.livewire }}.0 --no-interaction --no-update
210+
195211
- name: Install dependencies
196212
run: |
197213
composer update --prefer-dist --no-interaction --no-progress --${{ matrix.stability }}
@@ -219,9 +235,10 @@ jobs:
219235
matrix:
220236
php: [8.3]
221237
laravel: [12]
238+
livewire: [3, 4]
222239
stability: [prefer-stable]
223240

224-
name: PHP ${{ matrix.php }} - Laravel ${{ matrix.laravel }} - Stability ${{ matrix.stability }} - SQLite
241+
name: PHP ${{ matrix.php }} - Laravel ${{ matrix.laravel }} - Livewire ${{ matrix.livewire }} - Stability ${{ matrix.stability }} - SQLite
225242

226243
steps:
227244
- name: Checkout code
@@ -243,6 +260,10 @@ jobs:
243260
run: |
244261
composer require cachewerk/relay --no-interaction --no-update
245262
263+
- name: Require Livewire ${{ matrix.livewire }}
264+
run: |
265+
composer require livewire/livewire:^${{ matrix.livewire }}.0 --no-interaction --no-update
266+
246267
- name: Install dependencies
247268
run: |
248269
composer update --prefer-dist --no-interaction --no-progress --${{ matrix.stability }}

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
"illuminate/routing": "^10.48.4|^11.0.8|^12.0",
3434
"illuminate/support": "^10.48.4|^11.0.8|^12.0",
3535
"illuminate/view": "^10.48.4|^11.0.8|^12.0",
36-
"livewire/livewire": "^3.6.4",
36+
"livewire/livewire": "^3.6.4|^4.0",
3737
"symfony/console": "^6.0|^7.0",
3838
"nesbot/carbon": "^2.67|^3.0"
3939
},

tests/Feature/AuthTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@
4949
->first(fn ($component) => $component->memo->name === 'pulse.servers');
5050

5151
$this
52-
->post('/livewire/update', [
52+
->post(livewireUpdateEndpoint(), [
5353
'_token' => csrf_token(),
5454
'components' => [
5555
[
@@ -68,7 +68,7 @@
6868
Gate::define('viewPulse', fn ($user = null) => false);
6969

7070
$this
71-
->post('/livewire/update', [
71+
->post(livewireUpdateEndpoint(), [
7272
'_token' => csrf_token(),
7373
'components' => [],
7474
])

tests/Feature/Recorders/SlowRequestsTest.php

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -268,14 +268,14 @@
268268
it('ignores livewire update requests from an ignored path', function () {
269269
Config::set('pulse.recorders.'.SlowRequests::class.'.threshold', 0);
270270
Date::setTestNow('2000-01-02 03:04:05');
271-
Route::post('livewire/update', function () {
271+
Route::post(livewireUpdateEndpoint(), function () {
272272
Date::setTestNow('2000-01-02 03:04:09');
273273
})->name('livewire.update');
274274
Config::set('pulse.recorders.'.SlowRequests::class.'.ignore', [
275275
'#^/test-route#',
276276
]);
277277

278-
post('/livewire/update', [
278+
post(livewireUpdateEndpoint(), [
279279
'components' => [
280280
[
281281
'snapshot' => json_encode([
@@ -295,11 +295,11 @@
295295
it('captures the requests "via" route when using livewire', function () {
296296
Config::set('pulse.recorders.'.SlowRequests::class.'.threshold', 0);
297297
Date::setTestNow('2000-01-02 03:04:05');
298-
Route::post('livewire/update', function () {
298+
Route::post(livewireUpdateEndpoint(), function () {
299299
Date::setTestNow('2000-01-02 03:04:09');
300300
})->name('livewire.update');
301301

302-
post('/livewire/update', [
302+
post(livewireUpdateEndpoint(), [
303303
'components' => [
304304
[
305305
'snapshot' => json_encode([
@@ -315,8 +315,8 @@
315315
expect($entries)->toHaveCount(1);
316316
expect($entries[0]->timestamp)->toBe(946782245);
317317
expect($entries[0]->type)->toBe('slow_request');
318-
expect($entries[0]->key)->toBe(json_encode(['POST', '/test-route', 'via /livewire/update']));
319-
expect($entries[0]->key_hash)->toBe(keyHash(json_encode(['POST', '/test-route', 'via /livewire/update'])));
318+
expect($entries[0]->key)->toBe(json_encode(['POST', '/test-route', 'via '.livewireUpdateEndpoint()]));
319+
expect($entries[0]->key_hash)->toBe(keyHash(json_encode(['POST', '/test-route', 'via '.livewireUpdateEndpoint()])));
320320
expect($entries[0]->value)->toBe(4000);
321321

322322
$aggregates = Pulse::ignore(fn () => DB::table('pulse_aggregates')->orderBy('type')->orderBy('period')->orderBy('aggregate')->get());
@@ -326,64 +326,64 @@
326326
expect($aggregates[0]->period)->toBe(60);
327327
expect($aggregates[0]->type)->toBe('slow_request');
328328
expect($aggregates[0]->aggregate)->toBe('count');
329-
expect($aggregates[0]->key)->toBe(json_encode(['POST', '/test-route', 'via /livewire/update']));
330-
expect($aggregates[0]->key_hash)->toBe(keyHash(json_encode(['POST', '/test-route', 'via /livewire/update'])));
329+
expect($aggregates[0]->key)->toBe(json_encode(['POST', '/test-route', 'via '.livewireUpdateEndpoint()]));
330+
expect($aggregates[0]->key_hash)->toBe(keyHash(json_encode(['POST', '/test-route', 'via '.livewireUpdateEndpoint()])));
331331
expect($aggregates[0]->value)->toEqual(1);
332332

333333
expect($aggregates[1]->bucket)->toBe(946782240);
334334
expect($aggregates[1]->period)->toBe(60);
335335
expect($aggregates[1]->type)->toBe('slow_request');
336336
expect($aggregates[1]->aggregate)->toBe('max');
337-
expect($aggregates[1]->key)->toBe(json_encode(['POST', '/test-route', 'via /livewire/update']));
338-
expect($aggregates[1]->key_hash)->toBe(keyHash(json_encode(['POST', '/test-route', 'via /livewire/update'])));
337+
expect($aggregates[1]->key)->toBe(json_encode(['POST', '/test-route', 'via '.livewireUpdateEndpoint()]));
338+
expect($aggregates[1]->key_hash)->toBe(keyHash(json_encode(['POST', '/test-route', 'via '.livewireUpdateEndpoint()])));
339339
expect($aggregates[1]->value)->toEqual(4000);
340340

341341
expect($aggregates[2]->bucket)->toBe(946782000);
342342
expect($aggregates[2]->period)->toBe(360);
343343
expect($aggregates[2]->type)->toBe('slow_request');
344344
expect($aggregates[2]->aggregate)->toBe('count');
345-
expect($aggregates[2]->key)->toBe(json_encode(['POST', '/test-route', 'via /livewire/update']));
346-
expect($aggregates[2]->key_hash)->toBe(keyHash(json_encode(['POST', '/test-route', 'via /livewire/update'])));
345+
expect($aggregates[2]->key)->toBe(json_encode(['POST', '/test-route', 'via '.livewireUpdateEndpoint()]));
346+
expect($aggregates[2]->key_hash)->toBe(keyHash(json_encode(['POST', '/test-route', 'via '.livewireUpdateEndpoint()])));
347347
expect($aggregates[2]->value)->toEqual(1);
348348

349349
expect($aggregates[3]->bucket)->toBe(946782000);
350350
expect($aggregates[3]->period)->toBe(360);
351351
expect($aggregates[3]->type)->toBe('slow_request');
352352
expect($aggregates[3]->aggregate)->toBe('max');
353-
expect($aggregates[3]->key)->toBe(json_encode(['POST', '/test-route', 'via /livewire/update']));
354-
expect($aggregates[3]->key_hash)->toBe(keyHash(json_encode(['POST', '/test-route', 'via /livewire/update'])));
353+
expect($aggregates[3]->key)->toBe(json_encode(['POST', '/test-route', 'via '.livewireUpdateEndpoint()]));
354+
expect($aggregates[3]->key_hash)->toBe(keyHash(json_encode(['POST', '/test-route', 'via '.livewireUpdateEndpoint()])));
355355
expect($aggregates[3]->value)->toEqual(4000);
356356

357357
expect($aggregates[4]->bucket)->toBe(946781280);
358358
expect($aggregates[4]->period)->toBe(1440);
359359
expect($aggregates[4]->type)->toBe('slow_request');
360360
expect($aggregates[4]->aggregate)->toBe('count');
361-
expect($aggregates[4]->key)->toBe(json_encode(['POST', '/test-route', 'via /livewire/update']));
362-
expect($aggregates[4]->key_hash)->toBe(keyHash(json_encode(['POST', '/test-route', 'via /livewire/update'])));
361+
expect($aggregates[4]->key)->toBe(json_encode(['POST', '/test-route', 'via '.livewireUpdateEndpoint()]));
362+
expect($aggregates[4]->key_hash)->toBe(keyHash(json_encode(['POST', '/test-route', 'via '.livewireUpdateEndpoint()])));
363363
expect($aggregates[4]->value)->toEqual(1);
364364

365365
expect($aggregates[5]->bucket)->toBe(946781280);
366366
expect($aggregates[5]->period)->toBe(1440);
367367
expect($aggregates[5]->type)->toBe('slow_request');
368368
expect($aggregates[5]->aggregate)->toBe('max');
369-
expect($aggregates[5]->key)->toBe(json_encode(['POST', '/test-route', 'via /livewire/update']));
370-
expect($aggregates[5]->key_hash)->toBe(keyHash(json_encode(['POST', '/test-route', 'via /livewire/update'])));
369+
expect($aggregates[5]->key)->toBe(json_encode(['POST', '/test-route', 'via '.livewireUpdateEndpoint()]));
370+
expect($aggregates[5]->key_hash)->toBe(keyHash(json_encode(['POST', '/test-route', 'via '.livewireUpdateEndpoint()])));
371371
expect($aggregates[5]->value)->toEqual(4000);
372372

373373
expect($aggregates[6]->bucket)->toBe(946774080);
374374
expect($aggregates[6]->period)->toBe(10080);
375375
expect($aggregates[6]->type)->toBe('slow_request');
376376
expect($aggregates[6]->aggregate)->toBe('count');
377-
expect($aggregates[6]->key)->toBe(json_encode(['POST', '/test-route', 'via /livewire/update']));
378-
expect($aggregates[6]->key_hash)->toBe(keyHash(json_encode(['POST', '/test-route', 'via /livewire/update'])));
377+
expect($aggregates[6]->key)->toBe(json_encode(['POST', '/test-route', 'via '.livewireUpdateEndpoint()]));
378+
expect($aggregates[6]->key_hash)->toBe(keyHash(json_encode(['POST', '/test-route', 'via '.livewireUpdateEndpoint()])));
379379
expect($aggregates[6]->value)->toEqual(1);
380380

381381
expect($aggregates[7]->bucket)->toBe(946774080);
382382
expect($aggregates[7]->period)->toBe(10080);
383383
expect($aggregates[7]->type)->toBe('slow_request');
384384
expect($aggregates[7]->aggregate)->toBe('max');
385-
expect($aggregates[7]->key)->toBe(json_encode(['POST', '/test-route', 'via /livewire/update']));
386-
expect($aggregates[7]->key_hash)->toBe(keyHash(json_encode(['POST', '/test-route', 'via /livewire/update'])));
385+
expect($aggregates[7]->key)->toBe(json_encode(['POST', '/test-route', 'via '.livewireUpdateEndpoint()]));
386+
expect($aggregates[7]->key_hash)->toBe(keyHash(json_encode(['POST', '/test-route', 'via '.livewireUpdateEndpoint()])));
387387
expect($aggregates[7]->value)->toEqual(4000);
388388

389389
Pulse::ignore(fn () => expect(DB::table('pulse_values')->count())->toBe(0));

tests/Feature/Recorders/UserRequestsTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,10 +114,10 @@ public function user()
114114
'#^/users#',
115115
]);
116116
Route::get('users', fn () => []);
117-
Route::post('livewire/update', fn () => [])->name('livewire.update');
117+
Route::post(livewireUpdateEndpoint(), fn () => [])->name('livewire.update');
118118

119119
actingAs(User::make(['id' => '567']))
120-
->post('/livewire/update', [
120+
->post(livewireUpdateEndpoint(), [
121121
'components' => [
122122
[
123123
'snapshot' => json_encode([

tests/Pest.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,3 +170,14 @@ function avatar(string $email)
170170
{
171171
return sprintf('https://gravatar.com/avatar/%s?d=mp', hash('sha256', trim(strtolower($email))));
172172
}
173+
174+
function livewireUpdateEndpoint()
175+
{
176+
// Livewire v4
177+
if (class_exists(\Livewire\Mechanisms\HandleRequests\EndpointResolver::class)) {
178+
return \Livewire\Mechanisms\HandleRequests\EndpointResolver::updatePath();
179+
}
180+
181+
// Livewire v3
182+
return '/livewire/update';
183+
}

0 commit comments

Comments
 (0)