55namespace Tests \Tempest \Integration \Http ;
66
77use JsonSerializable ;
8+ use Stringable ;
9+ use Tempest \DateTime \Duration ;
810use Tempest \Http \GenericRequest ;
911use Tempest \Http \GenericResponse ;
1012use Tempest \Http \Method ;
1416use Tempest \Http \Responses \File ;
1517use Tempest \Http \Responses \Ok ;
1618use Tempest \Http \ServerSentEvent ;
19+ use Tempest \Http \ServerSentMessage ;
1720use Tempest \Http \Status ;
1821use Tempest \Router \GenericResponseSender ;
1922use Tempest \View \ViewRenderer ;
@@ -75,17 +78,10 @@ public function test_sending_head_request(): void
7578 public function test_file_response (): void
7679 {
7780 ob_start ();
78-
7981 $ path = __DIR__ . '/Fixtures/sample.png ' ;
80-
81- $ response = new File (
82- path: $ path ,
83- );
84-
82+ $ response = new File (path: $ path );
8583 $ responseSender = $ this ->container ->get (GenericResponseSender::class);
86-
8784 $ responseSender ->send ($ response );
88-
8985 $ content = ob_get_clean ();
9086
9187 $ this ->assertSame (file_get_contents ($ path ), $ content );
@@ -94,17 +90,10 @@ public function test_file_response(): void
9490 public function test_download_response (): void
9591 {
9692 ob_start ();
97-
9893 $ path = __DIR__ . '/Fixtures/sample.png ' ;
99-
100- $ response = new Download (
101- path: $ path ,
102- );
103-
94+ $ response = new Download (path: $ path );
10495 $ responseSender = $ this ->container ->get (GenericResponseSender::class);
105-
10696 $ responseSender ->send ($ response );
107-
10897 $ content = ob_get_clean ();
10998
11099 $ this ->assertSame (file_get_contents ($ path ), $ content );
@@ -113,16 +102,13 @@ public function test_download_response(): void
113102 public function test_sending_of_array_to_json (): void
114103 {
115104 ob_start ();
116-
117105 $ response = new GenericResponse (
118106 status: Status::CREATED ,
119107 body: ['key ' => 'value ' ],
120108 );
121109
122110 $ responseSender = $ this ->container ->get (GenericResponseSender::class);
123-
124111 $ responseSender ->send ($ response );
125-
126112 $ output = ob_get_clean ();
127113
128114 $ this ->assertSame ('{"key":"value"} ' , $ output );
@@ -131,7 +117,6 @@ public function test_sending_of_array_to_json(): void
131117 public function test_sending_of_json_serializable_to_json (): void
132118 {
133119 ob_start ();
134-
135120 $ response = new GenericResponse (
136121 status: Status::CREATED ,
137122 body: new class implements JsonSerializable {
@@ -143,9 +128,7 @@ public function jsonSerialize(): mixed
143128 );
144129
145130 $ responseSender = $ this ->container ->get (GenericResponseSender::class);
146-
147131 $ responseSender ->send ($ response );
148-
149132 $ output = ob_get_clean ();
150133
151134 $ this ->assertSame ('{"key":"value"} ' , $ output );
@@ -154,17 +137,14 @@ public function jsonSerialize(): mixed
154137 public function test_view_body (): void
155138 {
156139 ob_start ();
157-
158140 $ response = new Ok (
159141 body: view (__DIR__ . '/../../Fixtures/Views/overview.view.php ' )->data (
160142 name: 'Brent ' ,
161143 ),
162144 );
163145
164146 $ responseSender = $ this ->container ->get (GenericResponseSender::class);
165-
166147 $ responseSender ->send ($ response );
167-
168148 $ output = ob_get_clean ();
169149
170150 $ this ->assertStringContainsString ('Hello Brent! ' , $ output );
@@ -176,10 +156,7 @@ public function test_stream(): void
176156 $ response = new EventStream (fn () => yield 'hello ' );
177157 $ responseSender = $ this ->container ->get (GenericResponseSender::class);
178158 $ responseSender ->send ($ response );
179-
180159 $ output = ob_get_clean ();
181-
182- // restore phpunit's output buffer
183160 ob_start ();
184161
185162 $ this ->assertStringContainsString ('event: message ' , $ output );
@@ -190,20 +167,76 @@ public function test_stream_with_custom_event(): void
190167 {
191168 ob_start ();
192169 $ response = new EventStream (function () {
193- yield new ServerSentEvent (data: 'hello ' , event: 'first ' );
194- yield new ServerSentEvent (data: 'goodbye ' , event: 'last ' );
170+ yield new ServerSentMessage (data: 'hello ' , event: 'first ' );
171+ yield new ServerSentMessage (data: 'goodbye ' , event: 'last ' );
195172 });
196173 $ responseSender = $ this ->container ->get (GenericResponseSender::class);
197174 $ responseSender ->send ($ response );
198-
199175 $ output = ob_get_clean ();
200-
201- // restore phpunit's output buffer
202176 ob_start ();
203177
204178 $ this ->assertStringContainsString ('event: first ' , $ output );
205179 $ this ->assertStringContainsString ('data: "hello" ' , $ output );
206180 $ this ->assertStringContainsString ('event: last ' , $ output );
207181 $ this ->assertStringContainsString ('data: "goodbye" ' , $ output );
208182 }
183+
184+ public function test_stream_with_custom_id (): void
185+ {
186+ ob_start ();
187+ $ response = new EventStream (function () {
188+ yield new ServerSentMessage (data: 'hello ' , id: 123 );
189+ yield new ServerSentMessage (data: 'goodbye ' , id: 456 );
190+ });
191+ $ responseSender = $ this ->container ->get (GenericResponseSender::class);
192+ $ responseSender ->send ($ response );
193+ $ output = ob_get_clean ();
194+ ob_start ();
195+
196+ $ this ->assertStringContainsString ('id: 123 ' , $ output );
197+ $ this ->assertStringContainsString ('data: "hello" ' , $ output );
198+ $ this ->assertStringContainsString ('id: 456 ' , $ output );
199+ $ this ->assertStringContainsString ('data: "goodbye" ' , $ output );
200+ }
201+
202+ public function test_stream_with_custom_retry (): void
203+ {
204+ ob_start ();
205+ $ response = new EventStream (function () {
206+ yield new ServerSentMessage (data: 'hello ' , retryAfter: 1000 );
207+ yield new ServerSentMessage (data: 'goodbye ' , retryAfter: Duration::minute ());
208+ });
209+ $ responseSender = $ this ->container ->get (GenericResponseSender::class);
210+ $ responseSender ->send ($ response );
211+ $ output = ob_get_clean ();
212+ ob_start ();
213+
214+ $ this ->assertStringContainsString ('retry: 1000 ' , $ output );
215+ $ this ->assertStringContainsString ('data: "hello" ' , $ output );
216+ $ this ->assertStringContainsString ('retry: 60000 ' , $ output );
217+ $ this ->assertStringContainsString ('data: "goodbye" ' , $ output );
218+ }
219+
220+ public function test_stream_with_custom_implementation (): void
221+ {
222+ ob_start ();
223+ $ response = new EventStream (function () {
224+ yield new class implements ServerSentEvent {
225+ public ?int $ id = 1 ;
226+ public null |Duration |int $ retryAfter = null ;
227+ public ?string $ event = 'custom ' ;
228+ public JsonSerializable |Stringable |string |iterable $ data = ['foo ' , 'bar ' ];
229+ };
230+ });
231+ $ responseSender = $ this ->container ->get (GenericResponseSender::class);
232+ $ responseSender ->send ($ response );
233+ $ output = ob_get_clean ();
234+ ob_start ();
235+
236+ $ this ->assertStringContainsString ('id: 1 ' , $ output );
237+ $ this ->assertStringNotContainsString ('retry: ' , $ output );
238+ $ this ->assertStringContainsString ('event: custom ' , $ output );
239+ $ this ->assertStringContainsString ('data: foo ' , $ output );
240+ $ this ->assertStringContainsString ('data: bar ' , $ output );
241+ }
209242}
0 commit comments