28
28
*/
29
29
final class TestLiveComponent
30
30
{
31
+ private bool $ performedInitialRequest = false ;
32
+
31
33
/**
32
34
* @internal
33
35
*/
34
36
public function __construct (
35
37
private ComponentMetadata $ metadata ,
36
- array $ data ,
38
+ private array $ data ,
37
39
private ComponentFactory $ factory ,
38
40
private KernelBrowser $ client ,
39
41
private LiveComponentHydrator $ hydrator ,
40
42
private LiveComponentMetadataFactory $ metadataFactory ,
41
43
private UrlGeneratorInterface $ router ,
42
44
) {
43
45
$ this ->client ->catchExceptions (false );
44
-
45
- $ data ['attributes ' ]['id ' ] ??= 'in-a-real-scenario-it-would-already-have-one---provide-one-yourself-if-needed ' ;
46
-
47
- $ mounted = $ this ->factory ->create ($ this ->metadata ->getName (), $ data );
48
- $ props = $ this ->hydrator ->dehydrate (
49
- $ mounted ->getComponent (),
50
- $ mounted ->getAttributes (),
51
- $ this ->metadataFactory ->getMetadata ($ mounted ->getName ())
52
- );
53
-
54
- if ('POST ' === strtoupper ($ this ->metadata ->get ('method ' ))) {
55
- $ this ->client ->request (
56
- 'POST ' ,
57
- $ this ->router ->generate ($ this ->metadata ->get ('route ' ), [
58
- '_live_component ' => $ this ->metadata ->getName (),
59
- ]),
60
- [
61
- 'data ' => json_encode (['props ' => $ props ->getProps ()], flags: \JSON_THROW_ON_ERROR ),
62
- ],
63
- );
64
- } else {
65
- $ this ->client ->request ('GET ' , $ this ->router ->generate (
66
- $ this ->metadata ->get ('route ' ),
67
- [
68
- '_live_component ' => $ this ->metadata ->getName (),
69
- 'props ' => json_encode ($ props ->getProps (), flags: \JSON_THROW_ON_ERROR ),
70
- ]
71
- ));
72
- }
46
+ $ this ->data ['attributes ' ]['data-live-id ' ] ??= 'in-a-real-scenario-it-would-already-have-one---provide-one-yourself-if-needed ' ;
73
47
}
74
48
75
49
public function render (): RenderedComponent
@@ -95,6 +69,7 @@ public function component(): object
95
69
*/
96
70
public function actingAs (object $ user , string $ firewallContext = 'main ' ): self
97
71
{
72
+ // we call loginUser() on the raw client in case the entire component requires authentication
98
73
$ this ->client ->loginUser ($ user , $ firewallContext );
99
74
100
75
return $ this ;
@@ -145,14 +120,14 @@ public function refresh(): self
145
120
146
121
public function response (): Response
147
122
{
148
- return $ this ->client ->getResponse ();
123
+ return $ this ->client () ->getResponse ();
149
124
}
150
125
151
126
private function request (array $ content = [], ?string $ action = null ): self
152
127
{
153
128
$ csrfToken = $ this ->csrfToken ();
154
129
155
- $ this ->client ->request (
130
+ $ this ->client () ->request (
156
131
'POST ' ,
157
132
$ this ->router ->generate (
158
133
$ this ->metadata ->get ('route ' ),
@@ -170,7 +145,7 @@ private function request(array $content = [], ?string $action = null): self
170
145
171
146
private function props (): array
172
147
{
173
- $ crawler = $ this ->client ->getCrawler ();
148
+ $ crawler = $ this ->client () ->getCrawler ();
174
149
175
150
if (!\count ($ node = $ crawler ->filter ('[data-live-props-value] ' ))) {
176
151
throw new \LogicException ('A live component action has redirected and you can no longer access the component. ' );
@@ -181,12 +156,50 @@ private function props(): array
181
156
182
157
private function csrfToken (): ?string
183
158
{
184
- $ crawler = $ this ->client ->getCrawler ();
159
+ $ crawler = $ this ->client () ->getCrawler ();
185
160
186
161
if (!\count ($ node = $ crawler ->filter ('[data-live-csrf-value] ' ))) {
187
162
return null ;
188
163
}
189
164
190
165
return $ node ->attr ('data-live-csrf-value ' );
191
166
}
167
+
168
+ private function client (): KernelBrowser
169
+ {
170
+ if ($ this ->performedInitialRequest ) {
171
+ return $ this ->client ;
172
+ }
173
+
174
+ $ mounted = $ this ->factory ->create ($ this ->metadata ->getName (), $ this ->data );
175
+ $ props = $ this ->hydrator ->dehydrate (
176
+ $ mounted ->getComponent (),
177
+ $ mounted ->getAttributes (),
178
+ $ this ->metadataFactory ->getMetadata ($ mounted ->getName ())
179
+ );
180
+
181
+ if ('POST ' === strtoupper ($ this ->metadata ->get ('method ' ))) {
182
+ $ this ->client ->request (
183
+ 'POST ' ,
184
+ $ this ->router ->generate ($ this ->metadata ->get ('route ' ), [
185
+ '_live_component ' => $ this ->metadata ->getName (),
186
+ ]),
187
+ [
188
+ 'data ' => json_encode (['props ' => $ props ->getProps ()], flags: \JSON_THROW_ON_ERROR ),
189
+ ],
190
+ );
191
+ } else {
192
+ $ this ->client ->request ('GET ' , $ this ->router ->generate (
193
+ $ this ->metadata ->get ('route ' ),
194
+ [
195
+ '_live_component ' => $ this ->metadata ->getName (),
196
+ 'props ' => json_encode ($ props ->getProps (), flags: \JSON_THROW_ON_ERROR ),
197
+ ]
198
+ ));
199
+ }
200
+
201
+ $ this ->performedInitialRequest = true ;
202
+
203
+ return $ this ->client ;
204
+ }
192
205
}
0 commit comments