Completed
Push — develop ( 74108a...5db66d )
by Alejandro
17s queued 12s
created

QrCodeActionTest::provideRequestsWithSize()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 6
c 1
b 0
f 0
dl 0
loc 8
rs 10
cc 1
nc 1
nop 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace ShlinkioTest\Shlink\Core\Action;
6
7
use Laminas\Diactoros\Response;
8
use Laminas\Diactoros\ServerRequest;
9
use Laminas\Diactoros\ServerRequestFactory;
10
use Mezzio\Router\RouterInterface;
11
use PHPUnit\Framework\TestCase;
12
use Prophecy\Argument;
13
use Prophecy\PhpUnit\ProphecyTrait;
14
use Prophecy\Prophecy\ObjectProphecy;
15
use Psr\Http\Message\ServerRequestInterface;
16
use Psr\Http\Server\RequestHandlerInterface;
17
use Shlinkio\Shlink\Common\Response\QrCodeResponse;
18
use Shlinkio\Shlink\Core\Action\QrCodeAction;
19
use Shlinkio\Shlink\Core\Entity\ShortUrl;
20
use Shlinkio\Shlink\Core\Exception\ShortUrlNotFoundException;
21
use Shlinkio\Shlink\Core\Model\ShortUrlIdentifier;
22
use Shlinkio\Shlink\Core\Service\ShortUrl\ShortUrlResolverInterface;
23
24
use function getimagesizefromstring;
25
26
class QrCodeActionTest extends TestCase
27
{
28
    use ProphecyTrait;
29
30
    private QrCodeAction $action;
31
    private ObjectProphecy $urlResolver;
32
33
    public function setUp(): void
34
    {
35
        $router = $this->prophesize(RouterInterface::class);
36
        $router->generateUri(Argument::cetera())->willReturn('/foo/bar');
37
38
        $this->urlResolver = $this->prophesize(ShortUrlResolverInterface::class);
39
40
        $this->action = new QrCodeAction($this->urlResolver->reveal(), ['domain' => 'doma.in']);
41
    }
42
43
    /** @test */
44
    public function aNotFoundShortCodeWillDelegateIntoNextMiddleware(): void
45
    {
46
        $shortCode = 'abc123';
47
        $this->urlResolver->resolveEnabledShortUrl(new ShortUrlIdentifier($shortCode, ''))
48
            ->willThrow(ShortUrlNotFoundException::class)
49
            ->shouldBeCalledOnce();
50
        $delegate = $this->prophesize(RequestHandlerInterface::class);
51
        $process = $delegate->handle(Argument::any())->willReturn(new Response());
52
53
        $this->action->process((new ServerRequest())->withAttribute('shortCode', $shortCode), $delegate->reveal());
54
55
        $process->shouldHaveBeenCalledOnce();
56
    }
57
58
    /** @test */
59
    public function aCorrectRequestReturnsTheQrCodeResponse(): void
60
    {
61
        $shortCode = 'abc123';
62
        $this->urlResolver->resolveEnabledShortUrl(new ShortUrlIdentifier($shortCode, ''))
63
            ->willReturn(new ShortUrl(''))
64
            ->shouldBeCalledOnce();
65
        $delegate = $this->prophesize(RequestHandlerInterface::class);
66
67
        $resp = $this->action->process(
68
            (new ServerRequest())->withAttribute('shortCode', $shortCode),
69
            $delegate->reveal(),
70
        );
71
72
        self::assertInstanceOf(QrCodeResponse::class, $resp);
73
        self::assertEquals(200, $resp->getStatusCode());
74
        $delegate->handle(Argument::any())->shouldHaveBeenCalledTimes(0);
75
    }
76
77
    /**
78
     * @test
79
     * @dataProvider provideQueries
80
     */
81
    public function imageIsReturnedWithExpectedContentTypeBasedOnProvidedFormat(
82
        array $query,
83
        string $expectedContentType
84
    ): void {
85
        $code = 'abc123';
86
        $this->urlResolver->resolveEnabledShortUrl(new ShortUrlIdentifier($code, ''))->willReturn(new ShortUrl(''));
87
        $delegate = $this->prophesize(RequestHandlerInterface::class);
88
        $req = (new ServerRequest())->withAttribute('shortCode', $code)->withQueryParams($query);
89
90
        $resp = $this->action->process($req, $delegate->reveal());
91
92
        self::assertEquals($expectedContentType, $resp->getHeaderLine('Content-Type'));
93
    }
94
95
    public function provideQueries(): iterable
96
    {
97
        yield 'no format' => [[], 'image/png'];
98
        yield 'png format' => [['format' => 'png'], 'image/png'];
99
        yield 'svg format' => [['format' => 'svg'], 'image/svg+xml'];
100
        yield 'unsupported format' => [['format' => 'jpg'], 'image/png'];
101
    }
102
103
    /**
104
     * @test
105
     * @dataProvider provideRequestsWithSize
106
     */
107
    public function imageIsReturnedWithExpectedSize(ServerRequestInterface $req, int $expectedSize): void
108
    {
109
        $code = 'abc123';
110
        $this->urlResolver->resolveEnabledShortUrl(new ShortUrlIdentifier($code, ''))->willReturn(new ShortUrl(''));
111
        $delegate = $this->prophesize(RequestHandlerInterface::class);
112
113
        $resp = $this->action->process($req->withAttribute('shortCode', $code), $delegate->reveal());
114
        [$size] = getimagesizefromstring((string) $resp->getBody());
115
116
        self::assertEquals($expectedSize, $size);
117
    }
118
119
    public function provideRequestsWithSize(): iterable
120
    {
121
        yield 'no size' => [ServerRequestFactory::fromGlobals(), 300];
122
        yield 'size in attr' => [ServerRequestFactory::fromGlobals()->withAttribute('size', '400'), 400];
123
        yield 'size in query' => [ServerRequestFactory::fromGlobals()->withQueryParams(['size' => '123']), 123];
124
        yield 'size in query and attr' => [
125
            ServerRequestFactory::fromGlobals()->withAttribute('size', '350')->withQueryParams(['size' => '123']),
126
            350,
127
        ];
128
    }
129
}
130