@@ -237,6 +237,131 @@ public function testIfNoneMatch(string $body, string $contentLength, ?string $co
237237 self ::assertSame ($ response , $ middleware ->process ($ request , $ handler ));
238238 }
239239
240+ #[DataProvider('provideFiles ' )]
241+ public function testIfNoneMatchWithDifferentEtag (
242+ string $ body ,
243+ string $ contentLength ,
244+ ?string $ contentType ,
245+ string $ extension
246+ ): void {
247+ $ publicDirectory = sys_get_temp_dir ();
248+ $ requestTarget = '/ ' .uniqid ().uniqid ().'. ' .$ extension ;
249+ $ filename = $ publicDirectory .$ requestTarget ;
250+ $ hashAlgorithm = 'adler32 ' ;
251+
252+ file_put_contents ($ filename , $ body );
253+
254+ $ hash = hash_file ($ hashAlgorithm , $ filename );
255+
256+ $ builder = new MockObjectBuilder ();
257+
258+ /** @var ServerRequestInterface $request */
259+ $ request = $ builder ->create (ServerRequestInterface::class, [
260+ new WithReturn ('getRequestTarget ' , [], $ requestTarget ),
261+ new WithReturn ('getHeaderLine ' , ['If-None-Match ' ], $ hash .'-different ' ),
262+ ]);
263+
264+ /** @var StreamInterface $responseBody */
265+ $ responseBody = $ builder ->create (StreamInterface::class, []);
266+
267+ if (null !== $ contentType ) {
268+ /** @var ResponseInterface $response */
269+ $ response = $ builder ->create (ResponseInterface::class, [
270+ new WithReturnSelf ('withHeader ' , ['Content-Length ' , $ contentLength ]),
271+ new WithReturnSelf ('withHeader ' , ['Content-Type ' , $ contentType ]),
272+ new WithReturnSelf ('withHeader ' , ['ETag ' , $ hash ]),
273+ new WithReturnSelf ('withBody ' , [$ responseBody ]),
274+ ]);
275+ } else {
276+ /** @var ResponseInterface $response */
277+ $ response = $ builder ->create (ResponseInterface::class, [
278+ new WithReturnSelf ('withHeader ' , ['Content-Length ' , $ contentLength ]),
279+ new WithReturnSelf ('withHeader ' , ['ETag ' , $ hash ]),
280+ new WithReturnSelf ('withBody ' , [$ responseBody ]),
281+ ]);
282+ }
283+
284+ /** @var RequestHandlerInterface $handler */
285+ $ handler = $ builder ->create (RequestHandlerInterface::class, []);
286+
287+ /** @var ResponseFactoryInterface $responseFactory */
288+ $ responseFactory = $ builder ->create (ResponseFactoryInterface::class, [
289+ new WithReturn ('createResponse ' , [200 , '' ], $ response ),
290+ ]);
291+
292+ /** @var StreamFactoryInterface $streamFactory */
293+ $ streamFactory = $ builder ->create (StreamFactoryInterface::class, [
294+ new WithReturn ('createStreamFromFile ' , [$ filename , 'r ' ], $ responseBody ),
295+ ]);
296+
297+ $ middleware = new StaticFileMiddleware ($ responseFactory , $ streamFactory , $ publicDirectory , $ hashAlgorithm );
298+
299+ self ::assertSame ($ response , $ middleware ->process ($ request , $ handler ));
300+ }
301+
302+ #[DataProvider('provideFiles ' )]
303+ public function testUsesCustomMimetypes (
304+ string $ body ,
305+ string $ contentLength ,
306+ ?string $ contentType ,
307+ string $ extension
308+ ): void {
309+ $ publicDirectory = sys_get_temp_dir ();
310+ $ requestTarget = '/ ' .uniqid ().uniqid ().'. ' .$ extension ;
311+ $ filename = $ publicDirectory .$ requestTarget ;
312+ $ hashAlgorithm = 'adler32 ' ;
313+ $ customContentType = 'application/custom- ' .$ extension ;
314+ $ mimetypes = null !== $ contentType ? [$ extension => $ customContentType ] : [];
315+
316+ file_put_contents ($ filename , $ body );
317+
318+ $ hash = hash_file ($ hashAlgorithm , $ filename );
319+
320+ $ builder = new MockObjectBuilder ();
321+
322+ /** @var ServerRequestInterface $request */
323+ $ request = $ builder ->create (ServerRequestInterface::class, [
324+ new WithReturn ('getRequestTarget ' , [], $ requestTarget ),
325+ new WithReturn ('getHeaderLine ' , ['If-None-Match ' ], $ hash ),
326+ ]);
327+
328+ if (null !== $ contentType ) {
329+ /** @var ResponseInterface $response */
330+ $ response = $ builder ->create (ResponseInterface::class, [
331+ new WithReturnSelf ('withHeader ' , ['Content-Length ' , $ contentLength ]),
332+ new WithReturnSelf ('withHeader ' , ['Content-Type ' , $ customContentType ]),
333+ new WithReturnSelf ('withHeader ' , ['ETag ' , $ hash ]),
334+ ]);
335+ } else {
336+ /** @var ResponseInterface $response */
337+ $ response = $ builder ->create (ResponseInterface::class, [
338+ new WithReturnSelf ('withHeader ' , ['Content-Length ' , $ contentLength ]),
339+ new WithReturnSelf ('withHeader ' , ['ETag ' , $ hash ]),
340+ ]);
341+ }
342+
343+ /** @var RequestHandlerInterface $handler */
344+ $ handler = $ builder ->create (RequestHandlerInterface::class, []);
345+
346+ /** @var ResponseFactoryInterface $responseFactory */
347+ $ responseFactory = $ builder ->create (ResponseFactoryInterface::class, [
348+ new WithReturn ('createResponse ' , [304 , '' ], $ response ),
349+ ]);
350+
351+ /** @var StreamFactoryInterface $streamFactory */
352+ $ streamFactory = $ builder ->create (StreamFactoryInterface::class, []);
353+
354+ $ middleware = new StaticFileMiddleware (
355+ $ responseFactory ,
356+ $ streamFactory ,
357+ $ publicDirectory ,
358+ $ hashAlgorithm ,
359+ $ mimetypes
360+ );
361+
362+ self ::assertSame ($ response , $ middleware ->process ($ request , $ handler ));
363+ }
364+
240365 public static function provideFiles (): iterable
241366 {
242367 return [
0 commit comments