Passed
Pull Request — 1.x (#62)
by Kevin
02:14
created

Response::assertHtml()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 3
nc 2
nop 0
dl 0
loc 7
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Zenstruck\Browser;
4
5
use Symfony\Component\BrowserKit\AbstractBrowser as Client;
6
use Symfony\Component\HttpFoundation\HeaderBag;
7
use Symfony\Component\VarDumper\VarDumper;
8
use Zenstruck\Assert;
9
use Zenstruck\Browser\Response\DomResponse;
10
use Zenstruck\Browser\Response\HtmlResponse;
11
use Zenstruck\Browser\Response\JsonResponse;
12
use Zenstruck\Browser\Response\XmlResponse;
13
14
/**
15
 * @author Kevin Bond <[email protected]>
16
 */
17
class Response
18
{
19
    private Client $client;
20
21
    /**
22
     * @internal
23
     */
24
    final public function __construct(Client $client)
25
    {
26
        $this->client = $client;
27
    }
28
29
    public function statusCode(): int
30
    {
31
        return $this->client->getInternalResponse()->getStatusCode();
32
    }
33
34
    public function headers(): HeaderBag
35
    {
36
        return new HeaderBag($this->client->getInternalResponse()->getHeaders());
37
    }
38
39
    public function currentUrl(): string
40
    {
41
        return $this->client->getInternalRequest()->getUri();
42
    }
43
44
    /**
45
     * @internal
46
     */
47
    final public static function createFor(Client $client): self
48
    {
49
        $contentType = $client->getInternalResponse()->getHeader('content-type');
50
51
        if (str_contains($contentType, 'json')) {
0 ignored issues
show
Bug introduced by
It seems like $contentType can also be of type array and null; however, parameter $haystack of str_contains() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

51
        if (str_contains(/** @scrutinizer ignore-type */ $contentType, 'json')) {
Loading history...
52
            return new JsonResponse($client);
53
        }
54
55
        if (str_contains($contentType, 'html')) {
56
            return new HtmlResponse($client);
57
        }
58
59
        if (str_contains($contentType, 'xml')) {
60
            return new XmlResponse($client);
61
        }
62
63
        return new self($client);
64
    }
65
66
    final public function body(): string
67
    {
68
        return $this->client->getInternalResponse()->getContent();
69
    }
70
71
    final public function ensureJson(): JsonResponse
72
    {
73
        if (!$this instanceof JsonResponse) {
74
            Assert::fail('Not a json response.');
75
        }
76
77
        return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type Zenstruck\Browser\Response which includes types incompatible with the type-hinted return Zenstruck\Browser\Response\JsonResponse.
Loading history...
78
    }
79
80
    final public function ensureXml(): XmlResponse
81
    {
82
        if (!$this instanceof XmlResponse) {
83
            Assert::fail('Not an xml response.');
84
        }
85
86
        return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type Zenstruck\Browser\Response which includes types incompatible with the type-hinted return Zenstruck\Browser\Response\XmlResponse.
Loading history...
87
    }
88
89
    final public function ensureHtml(): HtmlResponse
90
    {
91
        if (!$this instanceof HtmlResponse) {
92
            Assert::fail('Not an html response.');
93
        }
94
95
        return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type Zenstruck\Browser\Response which includes types incompatible with the type-hinted return Zenstruck\Browser\Response\HtmlResponse.
Loading history...
96
    }
97
98
    final public function ensureDom(): DomResponse
99
    {
100
        if (!$this instanceof DomResponse) {
101
            Assert::fail('Not an DOM response.');
102
        }
103
104
        return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type Zenstruck\Browser\Response which includes types incompatible with the type-hinted return Zenstruck\Browser\Response\DomResponse.
Loading history...
105
    }
106
107
    final public function raw(): string
108
    {
109
        return "{$this->rawMetadata()}\n{$this->rawBody()}";
110
    }
111
112
    final public function isSuccessful(): bool
113
    {
114
        return $this->statusCode() >= 200 && $this->statusCode() < 300;
115
    }
116
117
    final public function isRedirect(): bool
118
    {
119
        return $this->statusCode() >= 300 && $this->statusCode() < 400;
120
    }
121
122
    public function dump(?string $selector = null): void
123
    {
124
        if (null !== $selector) {
125
            throw new \LogicException('$selector cannot be used with this response type.');
126
        }
127
128
        VarDumper::dump($this->raw());
129
    }
130
131
    /**
132
     * @internal
133
     */
134
    protected function rawMetadata(): string
135
    {
136
        return "URL: {$this->currentUrl()} ({$this->statusCode()})\n\n{$this->headers()}";
137
    }
138
139
    /**
140
     * @internal
141
     */
142
    protected function rawBody(): string
143
    {
144
        return $this->body();
145
    }
146
}
147