Passed
Push — master ( 1e501a...58b99e )
by Adrien
08:31
created

ImageActionTest::createRepositoryMock()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 3
c 1
b 0
f 0
nc 1
nop 1
dl 0
loc 6
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace EcodevTests\Felix\Action;
6
7
use Doctrine\Persistence\ObjectRepository;
8
use Ecodev\Felix\Action\ImageAction;
9
use Ecodev\Felix\Model\Image;
10
use Ecodev\Felix\Service\ImageResizer;
11
use Laminas\Diactoros\ServerRequest;
12
use org\bovigo\vfs\vfsStream;
13
use PHPUnit\Framework\TestCase;
14
use Psr\Http\Message\ResponseInterface;
15
use Psr\Http\Message\ServerRequestInterface;
16
use Psr\Http\Server\RequestHandlerInterface;
17
18
class ImageActionTest extends TestCase
19
{
20
    protected function setUp(): void
21
    {
22
        // Minimal binary headers to cheat mime detection
23
        $virtualFileSystem = [
24
            'image.png' => '',
25
            'image-100.jpg' => "\xff\xd8\xff\xe0\x00\x10\x4a\x46\x49\x46\x00\x01\x01\x01\x00\x60",
26
            'image-100.webp' => 'RIFF4<..WEBPVP8',
27
        ];
28
29
        vfsStream::setup('felix', null, $virtualFileSystem);
30
    }
31
32
    public function testWillServeJpgByDefault(): void
33
    {
34
        $image = $this->createImageMock();
35
        $repository = $this->createRepositoryMock($image);
36
37
        $maxHeight = 100;
38
        $imageResizer = $this->createMock(ImageResizer::class);
39
        $imageResizer->expects(self::once())
40
            ->method('resize')
41
            ->with($image, $maxHeight, false)
42
            ->willReturn('vfs://felix/image-100.jpg');
43
44
        // A request without accept header
45
        $request = new ServerRequest();
46
        $request = $request->withAttribute('maxHeight', $maxHeight);
47
48
        $response = $this->process($repository, $imageResizer, $request);
49
50
        self::assertSame('image/jpeg', $response->getHeaderLine('content-type'));
51
        self::assertSame('16', $response->getHeaderLine('content-length'));
52
    }
53
54
    public function testWillServeWebpIfAccepted(): void
55
    {
56
        $image = $this->createImageMock();
57
        $repository = $this->createRepositoryMock($image);
58
59
        $maxHeight = 100;
60
        $imageResizer = $this->createMock(ImageResizer::class);
61
        $imageResizer->expects(self::once())
62
            ->method('resize')
63
            ->with($image, $maxHeight, true)
64
            ->willReturn('vfs://felix/image-100.webp');
65
66
        // A request specifically accepting webp images
67
        $request = new ServerRequest();
68
        $request = $request->withAttribute('maxHeight', $maxHeight)
69
            ->withHeader('accept', 'text/html, image/webp, */*;q=0.8');
70
71
        $response = $this->process($repository, $imageResizer, $request);
72
73
        self::assertSame('image/webp', $response->getHeaderLine('content-type'));
74
        self::assertSame('15', $response->getHeaderLine('content-length'));
75
    }
76
77
    private function process(ObjectRepository $repository, ImageResizer $imageResizer, ServerRequestInterface $request): ResponseInterface
78
    {
79
        $action = new ImageAction($repository, $imageResizer);
80
        $handler = $this->createMock(RequestHandlerInterface::class);
81
82
        return $action->process($request, $handler);
83
    }
84
85
    private function createImageMock(): Image
86
    {
87
        $image = $this->createMock(Image::class);
88
        $image->expects(self::once())->method('getPath')->willReturn('vfs://felix/image.png');
89
90
        return $image;
91
    }
92
93
    private function createRepositoryMock(Image $image): ObjectRepository
94
    {
95
        $repository = $this->createMock(ObjectRepository::class);
96
        $repository->expects(self::once())->method('find')->willReturn($image);
97
98
        return $repository;
99
    }
100
}
101