Completed
Push — master ( 25953d...e2e6d9 )
by Joschi
02:32
created

UrlTest::testUseAutoconnect()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 4
rs 10
cc 1
eloc 2
nc 1
nop 0
1
<?php
2
3
/**
4
 * apparat-object
5
 *
6
 * @category    Apparat
7
 * @package     Apparat\Object
8
 * @subpackage  Apparat\Object\Infrastructure
9
 * @author      Joschi Kuphal <[email protected]> / @jkphl
10
 * @copyright   Copyright © 2016 Joschi Kuphal <[email protected]> / @jkphl
11
 * @license     http://opensource.org/licenses/MIT	The MIT License (MIT)
0 ignored issues
show
Coding Style introduced by
Spaces must be used for alignment; tabs are not allowed
Loading history...
12
 */
13
14
/***********************************************************************************
15
 *  The MIT License (MIT)
16
 *
17
 *  Copyright © 2016 Joschi Kuphal <[email protected]> / @jkphl
18
 *
19
 *  Permission is hereby granted, free of charge, to any person obtaining a copy of
20
 *  this software and associated documentation files (the "Software"), to deal in
21
 *  the Software without restriction, including without limitation the rights to
22
 *  use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
23
 *  the Software, and to permit persons to whom the Software is furnished to do so,
24
 *  subject to the following conditions:
25
 *
26
 *  The above copyright notice and this permission notice shall be included in all
27
 *  copies or substantial portions of the Software.
28
 *
29
 *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
30
 *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
31
 *  FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
32
 *  COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
33
 *  IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
34
 *  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
35
 ***********************************************************************************/
36
37
namespace Apparat\Object\Tests;
38
39
use Apparat\Kernel\Ports\Kernel;
40
use Apparat\Kernel\Tests\AbstractTest;
41
use Apparat\Object\Domain\Model\Object\Id;
42
use Apparat\Object\Domain\Model\Object\Revision;
43
use Apparat\Object\Domain\Model\Object\Type;
44
use Apparat\Object\Domain\Model\Path\ApparatUrl;
45
use Apparat\Object\Domain\Model\Path\LocalPath;
46
use Apparat\Object\Domain\Model\Path\ObjectUrl;
47
use Apparat\Object\Domain\Model\Path\Url;
48
use Apparat\Object\Domain\Repository\Service;
49
use Apparat\Object\Infrastructure\Repository\FileAdapterStrategy;
50
use Apparat\Object\Ports\Repository;
51
52
/**
53
 * Object URL tests
54
 *
55
 * @package Apparat\Object
56
 * @subpackage ApparatTest
57
 */
58
class UrlTest extends AbstractTest
59
{
60
    /**
61
     * Example query fragment
62
     *
63
     * @var string
64
     */
65
    const QUERY_FRAGMENT = '?param=value#fragment';
66
    /**
67
     * Repository URL
68
     *
69
     * @var string
70
     */
71
    const REPOSITORY_URL = '/repo';
72
    /**
73
     * Example path
74
     *
75
     * @var string
76
     */
77
    const PATH = '/2015/10/01/36704.event/36704-1';
78
    /**
79
     * Example URL
80
     *
81
     * @var string
82
     */
83
    const URL = self::REPOSITORY_URL . self::PATH . self::QUERY_FRAGMENT;
84
    /**
85
     * Example remote repository URL
86
     *
87
     * @var string
88
     */
89
    const REMOTE_REPOSITORY_URL = 'http://apparat:[email protected]:80';
90
    /**
91
     * Example remote URL
92
     *
93
     * @var string
94
     */
95
    const REMOTE_URL = self::REMOTE_REPOSITORY_URL . self::PATH . self::QUERY_FRAGMENT;
96
    /**
97
     * Example apparat URL
98
     *
99
     * @var string
100
     */
101
    const APPARAT_URL = 'aprts://apparat:[email protected]:80' . self::PATH . self::QUERY_FRAGMENT;
102
103
    /**
104
     * Test disabling of repository auto-connection
105
     */
106
    public function testUseAutoconnect()
107
    {
108
        $this->assertFalse(Kernel::create(Service::class)->useAutoConnect(false));
109
    }
110
111
    /**
112
     * Test an URL
113
     *
114
     * @expectedException \Apparat\Object\Domain\Model\Path\InvalidArgumentException
115
     * @expectedExceptionCode 1451515385
116
     */
117
    public function testInvalidRemoteUrl()
118
    {
119
        new ObjectUrl(self::REMOTE_URL);
120
    }
121
122
    /**
123
     * Test an URL
124
     */
125
    public function testRemoteUrl()
126
    {
127
        $url = new ObjectUrl(self::REMOTE_URL, true);
128
        $this->assertInstanceOf(ObjectUrl::class, $url);
129
        $this->assertEquals(self::REMOTE_URL, strval($url));
130
        $this->assertEquals('http', $url->getScheme());
131
        $this->assertEquals('apparat', $url->getUser());
132
        $this->assertEquals('tools', $url->getPassword());
133
        $this->assertEquals('apparat.tools', $url->getHost());
134
        $this->assertEquals(80, $url->getPort());
135
        $this->assertEquals('', $url->getPath());
136
        $this->assertEquals(['param' => 'value'], $url->getQuery());
137
        $this->assertEquals('fragment', $url->getFragment());
138
        $this->assertInstanceOf(\DateTimeImmutable::class, $url->getCreationDate());
139
        $this->assertEquals('2015-10-01', $url->getCreationDate()->format('Y-m-d'));
140
        $this->assertInstanceOf(Id::class, $url->getId());
141
        $this->assertEquals(new Id(36704), $url->getId());
142
        $this->assertInstanceOf(Type::class, $url->getType());
143
        $this->assertEquals(new Type('event'), $url->getType());
144
        $this->assertInstanceOf(Revision::class, $url->getRevision());
145
        $this->assertEquals(new Revision(1), $url->getRevision());
146
        $this->assertEquals(self::REMOTE_REPOSITORY_URL, Service::normalizeRepositoryUrl($url));
147
    }
148
149
    /**
150
     * Test a local URL with path prefix
151
     */
152
    public function testLeadedLocalUrl()
153
    {
154
        $pathPrefix = '/prefix/path';
155
        $url = new ObjectUrl($pathPrefix . self::PATH);
156
        $this->assertEquals($pathPrefix, $url->getPath());
157
        $this->assertEquals(self::PATH, $url->getLocalPath());
158
    }
159
160
    /**
161
     * Test an invalid URL
162
     *
163
     * @expectedException \Apparat\Object\Domain\Model\Path\InvalidArgumentException
164
     * @expectedExceptionCode 1449873819
165
     */
166
    public function testInvalidUrl()
167
    {
168
        new ObjectUrl('invalid://');
169
    }
170
171
    /**
172
     * Test an invalid URL path
173
     *
174
     * @expectedException \Apparat\Object\Domain\Model\Path\InvalidArgumentException
175
     * @expectedExceptionCode 1449874494
176
     */
177
    public function testInvalidUrlPath()
178
    {
179
        new ObjectUrl('http://invalid~url*path', true);
180
    }
181
182
    /**
183
     * Test the scheme setter
184
     *
185
     * @expectedException \Apparat\Object\Domain\Model\Path\InvalidArgumentException
186
     * @expectedExceptionCode 1449924914
187
     */
188
    public function testUrlSchemeSetter()
189
    {
190
        $url = new ObjectUrl(self::URL);
191
        $this->assertEquals(ObjectUrl::SCHEME_HTTPS, $url->setScheme(ObjectUrl::SCHEME_HTTPS)->getScheme());
192
        $url->setScheme('invalid');
193
    }
194
195
    /**
196
     * Test the host setter
197
     *
198
     * @expectedException \Apparat\Object\Domain\Model\Path\InvalidArgumentException
199
     * @expectedExceptionCode 1449925567
200
     */
201
    public function testUrlHostSetter()
202
    {
203
        $url = new ObjectUrl(self::URL);
204
        $this->assertEquals('apparat.com', $url->setHost('apparat.com')->getHost());
205
        $url->setHost('_');
206
    }
207
208
    /**
209
     * Test the port setter
210
     *
211
     * @expectedException \Apparat\Object\Domain\Model\Path\InvalidArgumentException
212
     * @expectedExceptionCode 1449925885
213
     */
214
    public function testUrlPortSetter()
215
    {
216
        $url = new ObjectUrl(self::URL);
217
        $this->assertEquals(443, $url->setPort(443)->getPort());
218
        $url->setPort(123456789);
219
    }
220
221
    /**
222
     * Test the remaining setter methods
223
     */
224
    public function testUrlSetters()
225
    {
226
        $url = new ObjectUrl(self::URL);
227
        $this->assertEquals('test', $url->setUser('test')->getUser());
228
        $this->assertEquals(null, $url->setUser(null)->getUser());
229
        $this->assertEquals('password', $url->setPassword('password')->getPassword());
230
        $this->assertEquals(null, $url->setPassword(null)->getPassword());
231
        $this->assertEquals('/path/prefix', $url->setPath('/path/prefix')->getPath());
232
        $this->assertEquals(['param2' => 'value2'], $url->setQuery(['param2' => 'value2'])->getQuery());
233
        $this->assertEquals('fragment2', $url->setFragment('fragment2')->getFragment());
234
235
        $this->assertEquals(
236
            '2016-01-01',
237
            $url->setCreationDate(new \DateTimeImmutable('@1451606400'))->getCreationDate()->format('Y-m-d')
238
        );
239
        $this->assertEquals(123, $url->setId(new Id(123))->getId()->getId());
0 ignored issues
show
Bug introduced by
The method getId cannot be called on $url->setId(new \Apparat...bject\Id(123))->getId() (of type integer).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
240
        $this->assertEquals('article', $url->setType(new Type('article'))->getType()->getType());
241
        $this->assertEquals(
242
            Revision::CURRENT,
243
            $url->setRevision(new Revision(Revision::CURRENT))->getRevision()->getRevision()
244
        );
245
    }
246
247
    /**
248
     * Test the override functionality when getting the URL path
249
     */
250
    public function testUrlPathOverride()
251
    {
252
        $url = new TestObjectUrl(self::URL);
253
        $this->assertEquals(
254
            'https://user:[email protected]:443/path/prefix/2015/10/01/36704.event/36704-2?param2=value2#fragment2',
255
            $url->getUrlOverride()
256
        );
257
    }
258
259
    /**
260
     * Test absolute URL
261
     */
262
    public function testUrlAbsolute()
263
    {
264
        $url = new ObjectUrl(self::REMOTE_URL, true);
265
        $this->assertEquals(true, $url->isAbsolute());
266
        $this->assertEquals(self::REMOTE_REPOSITORY_URL, $url->getRepositoryUrl());
267
    }
268
269
    /**
270
     * Test absolute URL
271
     */
272
    public function testUrlAbsoluteLocal()
273
    {
274
        $url = new ObjectUrl(rtrim(getenv('APPARAT_BASE_URL'), '/') . self::REPOSITORY_URL . self::PATH, true);
275
        $this->assertTrue($url->isAbsoluteLocal());
276
    }
277
278
    /**
279
     * Test relative URL
280
     */
281
    public function testUrlRelative()
282
    {
283
        $url = new ObjectUrl(self::PATH . self::QUERY_FRAGMENT);
284
        $this->assertEquals(false, $url->isAbsolute());
285
    }
286
287
    /**
288
     * Test URL comparison
289
     */
290
    public function testUrlComparison()
291
    {
292
        $this->assertFalse((new Url('http://example.com'))->matches(new Url('https://example.com')));
293
        $this->assertFalse((new Url('http://[email protected]'))->matches(new Url('http://[email protected]')));
294
        $this->assertFalse(
295
            (new Url('http://user:[email protected]'))->matches(new Url('http://user:[email protected]'))
296
        );
297
        $this->assertFalse((new Url('http://example1.com'))->matches(new Url('http://example2.com')));
298
        $this->assertFalse((new Url('http://example.com:80'))->matches(new Url('http://example.com:443')));
299
        $this->assertFalse((new Url('http://example.com/a'))->matches(new Url('http://example.com/b')));
300
        $this->assertFalse((new Url('http://example.com/?a=1'))->matches(new Url('http://example.com/?a=2')));
301
        $this->assertFalse((new Url('http://example.com/#a'))->matches(new Url('http://example.com/#b')));
302
        $this->assertTrue((new Url(self::REMOTE_URL))->matches(new Url(self::REMOTE_URL)));
303
    }
304
305
    /**
306
     * Test object URL comparison
307
     */
308
    public function testObjectUrlComparison()
309
    {
310
        $this->assertFalse(
311
            (
312
            new ObjectUrl(
313
                'http://example.com/2015/10/01/36704.event/36704-1',
314
                true
315
            )
316
            )->matches(new ObjectUrl('https://example.com/2015/10/01/36704.event/36704-1', true))
317
        );
318
        $this->assertFalse(
319
            (
320
            new ObjectUrl(
321
                'http://example.com/2015/10/01/36704.event/36704-1',
322
                true
323
            )
324
            )->matches(new ObjectUrl('http://example.com/2016/10/01/36704.event/36704-1', true))
325
        );
326
        $this->assertFalse(
327
            (
328
            new ObjectUrl(
329
                'http://example.com/2015/10/01/36704.event/36704-1',
330
                true
331
            )
332
            )->matches(new ObjectUrl('http://example.com/2015/10/01/36705.event/36705-1', true))
333
        );
334
        $this->assertFalse(
335
            (
336
            new ObjectUrl(
337
                'http://example.com/2015/10/01/36704.event/36704-1',
338
                true
339
            )
340
            )->matches(new ObjectUrl('http://example.com/2015/10/01/36704.article/36704-1', true))
341
        );
342
        $this->assertFalse(
343
            (
344
            new ObjectUrl(
345
                'http://example.com/2015/10/01/36704.event/36704-1',
346
                true
347
            )
348
            )->matches(new ObjectUrl('http://example.com/2015/10/01/36704.event/36704-2', true))
349
        );
350
        $this->assertTrue((new ObjectUrl(self::REMOTE_URL, true))->matches(new ObjectUrl(self::REMOTE_URL, true)));
351
    }
352
353
    /**
354
     * Test an invalid apparat URL
355
     *
356
     * @expectedException \Apparat\Object\Domain\Model\Path\InvalidArgumentException
357
     * @expectedExceptionCode 1451435429
358
     */
359
    public function testInvalidApparatUrl()
360
    {
361
        new ApparatUrl(self::REMOTE_URL, true);
362
    }
363
364
    /**
365
     * Test an absolute apparat URL
366
     */
367
    public function testAbsoluteApparatUrl()
368
    {
369
        $apparatUrl = new ApparatUrl(self::APPARAT_URL, true);
370
        $this->assertInstanceOf(ApparatUrl::class, $apparatUrl);
371
        $this->assertEquals('https://apparat:[email protected]:80', Service::normalizeRepositoryUrl($apparatUrl));
372
    }
373
374
    /**
375
     * Test an unknown relative apparat URL
376
     *
377
     * @expectedException \Apparat\Object\Domain\Model\Path\ApparatInvalidArgumentException
378
     * @expectedExceptionCode 1452695654
379
     */
380
    public function testUnknownRelativeApparatUrl()
381
    {
382
        new ApparatUrl(self::PATH . self::QUERY_FRAGMENT);
383
    }
384
385
    /**
386
     * Test a relative apparat URL
387
     */
388
    public function testRelativeApparatUrl()
389
    {
390
        Repository::register(
391
            self::REPOSITORY_URL,
392
            [
393
                'type' => FileAdapterStrategy::TYPE,
394
                'root' => __DIR__,
395
            ]
396
        );
397
        $apparatUrl = new ApparatUrl(self::URL);
398
        $this->assertInstanceOf(ApparatUrl::class, $apparatUrl);
399
        $this->assertEquals(self::REPOSITORY_URL, Service::normalizeRepositoryUrl($apparatUrl));
400
    }
401
402
    /**
403
     * Test invalid date precision
404
     *
405
     * @expectedException \Apparat\Object\Domain\Model\Path\InvalidArgumentException
406
     * @expectedExceptionCode 1451514114
407
     */
408
    public function testInvalidDatePrecision()
409
    {
410
        new LocalPath(self::PATH, -1);
411
    }
412
413
    /**
414
     * Test arbitrary date precision
415
     */
416
    public function testArbitraryDatePrecision()
417
    {
418
        $path = new LocalPath(self::PATH, true);
0 ignored issues
show
Documentation introduced by
true is of type boolean, but the function expects a null|object<Apparat\Obje...odel\Path\TRUE>|integer.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
419
        $this->assertInstanceOf(LocalPath::class, $path);
420
    }
421
422
    /**
423
     * Test the normalization of an invalid repository URL
424
     *
425
     * @expectedException \Apparat\Object\Domain\Repository\InvalidArgumentException
426
     * @expectedExceptionCode 1453097878
427
     */
428
    public function testInvalidRepositoryUrlNormalization() {
429
        Service::normalizeRepositoryUrl(new Url(self::REMOTE_REPOSITORY_URL));
430
    }
431
}
432