Completed
Pull Request — master (#13)
by
unknown
03:54
created

ApiServiceTest::itCanPaginate()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 33
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 23
nc 1
nop 0
dl 0
loc 33
rs 9.552
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace ElevenLabs\Api\Service\Tests\Functional;
6
7
use ElevenLabs\Api\Service\ApiServiceBuilder;
8
use ElevenLabs\Api\Service\Exception\RequestViolations;
9
use ElevenLabs\Api\Service\Exception\ResponseViolations;
10
use ElevenLabs\Api\Service\Pagination\Pagination;
11
use ElevenLabs\Api\Service\Pagination\Provider\PaginationHeader;
12
use ElevenLabs\Api\Service\Resource\Collection;
13
use ElevenLabs\Api\Service\Resource\Item;
14
use GuzzleHttp\Psr7\Response;
15
use Http\Discovery\MessageFactoryDiscovery;
16
use Http\Mock\Client;
17
use Http\Promise\Promise;
18
use PHPUnit\Framework\TestCase;
19
20
/**
21
 * Class ApiServiceTest.
22
 *
23
 * @group functional
24
 */
25
class ApiServiceTest extends TestCase
26
{
27
    /** @var string */
28
    private $schemaFile;
29
30
    /** @var Client */
31
    private $httpMockClient;
32
33
    public function setUp()
34
    {
35
        $this->schemaFile = 'file://'.__DIR__.'/../fixtures/httpbin.yml';
36
        $this->httpMockClient = new MockClient();
37
    }
38
39
    /** @test */
40
    public function itCanMakeASynchronousCall()
41
    {
42
        $apiService = (new ApiServiceBuilder())
43
            ->withHttpClient($this->httpMockClient)
44
            ->withMessageFactory($messageFactory = MessageFactoryDiscovery::find())
45
            ->build($this->schemaFile);
46
47
        $this->httpMockClient->addResponse(
48
            $messageFactory->createResponse(
49
                $statusCode   = 200,
50
                $reasonPhrase = '',
51
                $headers      = ['Content-Type' => 'application/json'],
52
                $body         = json_encode(
53
                    [
54
                        'origin' => '127.0.0.1',
55
                        'url'    => 'https://httpbin.org/get',
56
                    ]
57
                )
58
            )
59
        );
60
61
        $response = $apiService->call('dumpGetRequest');
62
63
        $this->assertInstanceOf(Item::class, $response);
64
    }
65
66
    /** @test */
67
    public function itCanMakeAnAsynchronousCall()
68
    {
69
        $apiService = (new ApiServiceBuilder())
70
            ->withHttpClient($this->httpMockClient)
71
            ->withMessageFactory($messageFactory = MessageFactoryDiscovery::find())
72
            ->build($this->schemaFile);
73
74
        $this->httpMockClient->addResponse(
75
            $messageFactory->createResponse(
76
                $statusCode   = 200,
77
                $reasonPhrase = '',
78
                $headers      = ['Content-Type' => 'application/json'],
79
                $body         = json_encode(
80
                    [
81
                        'origin' => '127.0.0.1',
82
                        'url'    => 'https://httpbin.org/get',
83
                    ]
84
                )
85
            )
86
        );
87
88
        $promise = $apiService->callAsync('dumpGetRequest');
89
90
        $this->assertInstanceOf(Promise::class, $promise);
91
        $this->assertInstanceOf(Item::class, $promise->wait());
92
    }
93
94
    /** @test */
95
    public function itValidateTheRequestByDefault()
96
    {
97
        $this->expectException(RequestViolations::class);
98
99
        $apiService = ApiServiceBuilder::create()
100
            ->build($this->schemaFile);
101
102
        $apiService->call('dumpGetRequest', ['aDate' => 'notADateString']);
103
    }
104
105
    /** @test */
106
    public function itAllowTheRequestValidationToBeDisable()
107
    {
108
        $apiService = ApiServiceBuilder::create()
109
            ->disableRequestValidation()
110
            ->withHttpClient($this->httpMockClient)
111
            ->withBaseUri('https://domain.tld')
112
            ->build($this->schemaFile);
113
114
        $this->httpMockClient->addResponse(new Response(200, ['Content-Type' => 'application/json'], '{}'));
115
116
        $apiService->call('dumpGetRequest', [
117
            'aPath' => 1,
118
            'aDate' => 'notADateString',
119
            'aBody' => ['foo' => 'bar'],
120
        ]);
121
122
        $request = current($this->httpMockClient->getRequests());
123
124
        $this->assertEquals('https://domain.tld/get/1?aSlug=test&aDate=notADateString', $request->getUri()->__toString());
125
    }
126
127
    /** @test */
128
    public function itAllowTheResponseValidationToBeEnabled()
129
    {
130
        $this->expectException(ResponseViolations::class);
131
132
        $apiService = ApiServiceBuilder::create()
133
            ->enableResponseValidation()
134
            ->withHttpClient($this->httpMockClient)
135
            ->withBaseUri('https://domain.tld')
136
            ->build($this->schemaFile);
137
138
        $this->httpMockClient->addResponse(
139
            new Response(
140
                200,
141
                ['Content-Type' => 'application/json'],
142
                '{"notAValidProperty": "oups"}'
143
            )
144
        );
145
146
        $apiService->call('dumpGetRequest');
147
    }
148
149
    /** @test */
150
    public function itCanPaginate()
151
    {
152
        $apiService = ApiServiceBuilder::create()
153
            ->withHttpClient($this->httpMockClient)
154
            ->withBaseUri('https://domain.tld')
155
            ->withPaginationProvider(new PaginationHeader())
156
            ->build($this->schemaFile);
157
158
        $this->httpMockClient->addResponse(
159
            new Response(
160
                200,
161
                [
162
                    'Content-Type' => 'application/json',
163
                    'X-Page' => '1',
164
                    'X-Per-Page' => '10',
165
                    'X-Total-Pages' => '10',
166
                    'X-Total-Items' => '100',
167
                    'Link' => [
168
                        '<http://domain.tld?page=1>; rel="first"',
169
                        '<http://domain.tld?page=10>; rel="last"',
170
                        '<http://domain.tld?page=4>; rel="next"',
171
                        '<http://domain.tld?page=2>; rel="prev"',
172
                    ],
173
                ],
174
                '[{"foo": "value 1"}, {"foo": "value 2"}]'
175
            )
176
        );
177
178
        $resource = $apiService->call('getFakeCollection');
179
180
        $this->assertInstanceOf(Collection::class, $resource);
181
        $this->assertTrue($resource->hasPagination());
0 ignored issues
show
Bug introduced by
The method hasPagination() does not exist on Psr\Http\Message\ResponseInterface. ( Ignorable by Annotation )

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

181
        $this->assertTrue($resource->/** @scrutinizer ignore-call */ hasPagination());

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
182
        $this->assertInstanceOf(Pagination::class, $resource->getPagination());
0 ignored issues
show
Bug introduced by
The method getPagination() does not exist on Psr\Http\Message\ResponseInterface. ( Ignorable by Annotation )

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

182
        $this->assertInstanceOf(Pagination::class, $resource->/** @scrutinizer ignore-call */ getPagination());

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
183
    }
184
185
    /** @test */
186
    public function itDoesNotTryToValidateTheResponseBodyIfNoBodySchemaIsProvided()
187
    {
188
        $apiService = ApiServiceBuilder::create()
189
            ->enableResponseValidation()
190
            ->withHttpClient($this->httpMockClient)
191
            ->withMessageFactory($messageFactory = MessageFactoryDiscovery::find())
192
            ->build($this->schemaFile);
193
194
        $this->httpMockClient->addResponse(
195
            $messageFactory->createResponse(201)
196
        );
197
198
        $result = $apiService->call('postResponseWithoutBody');
199
200
        $this->assertInstanceOf(Item::class, $result);
201
        $this->assertEmpty($result->getData());
0 ignored issues
show
Bug introduced by
The method getData() does not exist on Psr\Http\Message\ResponseInterface. ( Ignorable by Annotation )

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

201
        $this->assertEmpty($result->/** @scrutinizer ignore-call */ getData());

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
202
        $this->assertEmpty($result->getBody());
203
        $this->assertArrayHasKey('Host', $result->getMeta());
0 ignored issues
show
Bug introduced by
The method getMeta() does not exist on Psr\Http\Message\ResponseInterface. ( Ignorable by Annotation )

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

203
        $this->assertArrayHasKey('Host', $result->/** @scrutinizer ignore-call */ getMeta());

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
204
    }
205
}
206