Completed
Push — master ( e2e6d9...5aa43e )
by Joschi
02:56
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\Object\Domain\Model\Object\Id;
40
use Apparat\Object\Domain\Model\Object\Revision;
41
use Apparat\Object\Domain\Model\Object\Type;
42
use Apparat\Object\Domain\Model\Path\ApparatUrl;
43
use Apparat\Object\Domain\Model\Path\LocalPath;
44
use Apparat\Object\Domain\Model\Path\ObjectUrl;
45
use Apparat\Object\Domain\Model\Path\Url;
46
use Apparat\Object\Domain\Repository\Service;
47
use Apparat\Object\Infrastructure\Repository\FileAdapterStrategy;
48
use Apparat\Object\Ports\Repository;
49
50
/**
51
 * Object URL tests
52
 *
53
 * @package Apparat\Object
54
 * @subpackage ApparatTest
55
 */
56
class UrlTest extends AbstractTest
57
{
58
    /**
59
     * Example query fragment
60
     *
61
     * @var string
62
     */
63
    const QUERY_FRAGMENT = '?param=value#fragment';
64
    /**
65
     * Repository URL
66
     *
67
     * @var string
68
     */
69
    const REPOSITORY_URL = '/repo';
70
    /**
71
     * Example path
72
     *
73
     * @var string
74
     */
75
    const PATH = '/2015/10/01/36704.event/36704-1';
76
    /**
77
     * Example URL
78
     *
79
     * @var string
80
     */
81
    const URL = self::REPOSITORY_URL . self::PATH . self::QUERY_FRAGMENT;
82
    /**
83
     * Example remote repository URL
84
     *
85
     * @var string
86
     */
87
    const REMOTE_REPOSITORY_URL = 'http://apparat:[email protected]:80';
88
    /**
89
     * Example remote URL
90
     *
91
     * @var string
92
     */
93
    const REMOTE_URL = self::REMOTE_REPOSITORY_URL . self::PATH . self::QUERY_FRAGMENT;
94
    /**
95
     * Example apparat URL
96
     *
97
     * @var string
98
     */
99
    const APPARAT_URL = 'aprts://apparat:[email protected]:80' . self::PATH . self::QUERY_FRAGMENT;
100
101
    /**
102
     * Test an URL
103
     *
104
     * @expectedException \Apparat\Object\Domain\Model\Path\InvalidArgumentException
105
     * @expectedExceptionCode 1451515385
106
     */
107
    public function testInvalidRemoteUrl()
108
    {
109
        new ObjectUrl(self::REMOTE_URL);
110
    }
111
112
    /**
113
     * Test an URL
114
     */
115
    public function testRemoteUrl()
116
    {
117
        $url = new ObjectUrl(self::REMOTE_URL, true);
118
        $this->assertInstanceOf(ObjectUrl::class, $url);
119
        $this->assertEquals(self::REMOTE_URL, strval($url));
120
        $this->assertEquals('http', $url->getScheme());
121
        $this->assertEquals('apparat', $url->getUser());
122
        $this->assertEquals('tools', $url->getPassword());
123
        $this->assertEquals('apparat.tools', $url->getHost());
124
        $this->assertEquals(80, $url->getPort());
125
        $this->assertEquals('', $url->getPath());
126
        $this->assertEquals(['param' => 'value'], $url->getQuery());
127
        $this->assertEquals('fragment', $url->getFragment());
128
        $this->assertInstanceOf(\DateTimeImmutable::class, $url->getCreationDate());
129
        $this->assertEquals('2015-10-01', $url->getCreationDate()->format('Y-m-d'));
130
        $this->assertInstanceOf(Id::class, $url->getId());
131
        $this->assertEquals(new Id(36704), $url->getId());
132
        $this->assertInstanceOf(Type::class, $url->getType());
133
        $this->assertEquals(new Type('event'), $url->getType());
134
        $this->assertInstanceOf(Revision::class, $url->getRevision());
135
        $this->assertEquals(new Revision(1), $url->getRevision());
136
        $this->assertEquals(self::REMOTE_REPOSITORY_URL, Service::normalizeRepositoryUrl($url));
137
    }
138
139
    /**
140
     * Test a local URL with path prefix
141
     */
142
    public function testLeadedLocalUrl()
143
    {
144
        $pathPrefix = '/prefix/path';
145
        $url = new ObjectUrl($pathPrefix . self::PATH);
146
        $this->assertEquals($pathPrefix, $url->getPath());
147
        $this->assertEquals(self::PATH, $url->getLocalPath());
148
    }
149
150
    /**
151
     * Test an invalid URL
152
     *
153
     * @expectedException \Apparat\Object\Domain\Model\Path\InvalidArgumentException
154
     * @expectedExceptionCode 1449873819
155
     */
156
    public function testInvalidUrl()
157
    {
158
        new ObjectUrl('invalid://');
159
    }
160
161
    /**
162
     * Test an invalid URL path
163
     *
164
     * @expectedException \Apparat\Object\Domain\Model\Path\InvalidArgumentException
165
     * @expectedExceptionCode 1449874494
166
     */
167
    public function testInvalidUrlPath()
168
    {
169
        new ObjectUrl('http://invalid~url*path', true);
170
    }
171
172
    /**
173
     * Test the scheme setter
174
     *
175
     * @expectedException \Apparat\Object\Domain\Model\Path\InvalidArgumentException
176
     * @expectedExceptionCode 1449924914
177
     */
178
    public function testUrlSchemeSetter()
179
    {
180
        $url = new ObjectUrl(self::URL);
181
        $this->assertEquals(ObjectUrl::SCHEME_HTTPS, $url->setScheme(ObjectUrl::SCHEME_HTTPS)->getScheme());
182
        $url->setScheme('invalid');
183
    }
184
185
    /**
186
     * Test the host setter
187
     *
188
     * @expectedException \Apparat\Object\Domain\Model\Path\InvalidArgumentException
189
     * @expectedExceptionCode 1449925567
190
     */
191
    public function testUrlHostSetter()
192
    {
193
        $url = new ObjectUrl(self::URL);
194
        $this->assertEquals('apparat.com', $url->setHost('apparat.com')->getHost());
195
        $url->setHost('_');
196
    }
197
198
    /**
199
     * Test the port setter
200
     *
201
     * @expectedException \Apparat\Object\Domain\Model\Path\InvalidArgumentException
202
     * @expectedExceptionCode 1449925885
203
     */
204
    public function testUrlPortSetter()
205
    {
206
        $url = new ObjectUrl(self::URL);
207
        $this->assertEquals(443, $url->setPort(443)->getPort());
208
        $url->setPort(123456789);
209
    }
210
211
    /**
212
     * Test the remaining setter methods
213
     */
214
    public function testUrlSetters()
215
    {
216
        $url = new ObjectUrl(self::URL);
217
        $this->assertEquals('test', $url->setUser('test')->getUser());
218
        $this->assertEquals(null, $url->setUser(null)->getUser());
219
        $this->assertEquals('password', $url->setPassword('password')->getPassword());
220
        $this->assertEquals(null, $url->setPassword(null)->getPassword());
221
        $this->assertEquals('/path/prefix', $url->setPath('/path/prefix')->getPath());
222
        $this->assertEquals(['param2' => 'value2'], $url->setQuery(['param2' => 'value2'])->getQuery());
223
        $this->assertEquals('fragment2', $url->setFragment('fragment2')->getFragment());
224
225
        $this->assertEquals(
226
            '2016-01-01',
227
            $url->setCreationDate(new \DateTimeImmutable('@1451606400'))->getCreationDate()->format('Y-m-d')
228
        );
229
        $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...
230
        $this->assertEquals('article', $url->setType(new Type('article'))->getType()->getType());
231
        $this->assertEquals(
232
            Revision::CURRENT,
233
            $url->setRevision(new Revision(Revision::CURRENT))->getRevision()->getRevision()
234
        );
235
    }
236
237
    /**
238
     * Test the override functionality when getting the URL path
239
     */
240
    public function testUrlPathOverride()
241
    {
242
        $url = new TestObjectUrl(self::URL);
243
        $this->assertEquals(
244
            'https://user:[email protected]:443/path/prefix/2015/10/01/36704.event/36704-2?param2=value2#fragment2',
245
            $url->getUrlOverride()
246
        );
247
    }
248
249
    /**
250
     * Test absolute URL
251
     */
252
    public function testUrlAbsolute()
253
    {
254
        $url = new ObjectUrl(self::REMOTE_URL, true);
255
        $this->assertEquals(true, $url->isAbsolute());
256
        $this->assertEquals(self::REMOTE_REPOSITORY_URL, $url->getRepositoryUrl());
257
    }
258
259
    /**
260
     * Test absolute URL
261
     */
262
    public function testUrlAbsoluteLocal()
263
    {
264
        $url = new ObjectUrl(rtrim(getenv('APPARAT_BASE_URL'), '/') . self::REPOSITORY_URL . self::PATH, true);
265
        $this->assertTrue($url->isAbsoluteLocal());
266
    }
267
268
    /**
269
     * Test relative URL
270
     */
271
    public function testUrlRelative()
272
    {
273
        $url = new ObjectUrl(self::PATH . self::QUERY_FRAGMENT);
274
        $this->assertEquals(false, $url->isAbsolute());
275
    }
276
277
    /**
278
     * Test URL comparison
279
     */
280
    public function testUrlComparison()
281
    {
282
        $this->assertFalse((new Url('http://example.com'))->matches(new Url('https://example.com')));
283
        $this->assertFalse((new Url('http://[email protected]'))->matches(new Url('http://[email protected]')));
284
        $this->assertFalse(
285
            (new Url('http://user:[email protected]'))->matches(new Url('http://user:[email protected]'))
286
        );
287
        $this->assertFalse((new Url('http://example1.com'))->matches(new Url('http://example2.com')));
288
        $this->assertFalse((new Url('http://example.com:80'))->matches(new Url('http://example.com:443')));
289
        $this->assertFalse((new Url('http://example.com/a'))->matches(new Url('http://example.com/b')));
290
        $this->assertFalse((new Url('http://example.com/?a=1'))->matches(new Url('http://example.com/?a=2')));
291
        $this->assertFalse((new Url('http://example.com/#a'))->matches(new Url('http://example.com/#b')));
292
        $this->assertTrue((new Url(self::REMOTE_URL))->matches(new Url(self::REMOTE_URL)));
293
    }
294
295
    /**
296
     * Test object URL comparison
297
     */
298
    public function testObjectUrlComparison()
299
    {
300
        $this->assertFalse(
301
            (
302
            new ObjectUrl(
303
                'http://example.com/2015/10/01/36704.event/36704-1',
304
                true
305
            )
306
            )->matches(new ObjectUrl('https://example.com/2015/10/01/36704.event/36704-1', true))
307
        );
308
        $this->assertFalse(
309
            (
310
            new ObjectUrl(
311
                'http://example.com/2015/10/01/36704.event/36704-1',
312
                true
313
            )
314
            )->matches(new ObjectUrl('http://example.com/2016/10/01/36704.event/36704-1', true))
315
        );
316
        $this->assertFalse(
317
            (
318
            new ObjectUrl(
319
                'http://example.com/2015/10/01/36704.event/36704-1',
320
                true
321
            )
322
            )->matches(new ObjectUrl('http://example.com/2015/10/01/36705.event/36705-1', true))
323
        );
324
        $this->assertFalse(
325
            (
326
            new ObjectUrl(
327
                'http://example.com/2015/10/01/36704.event/36704-1',
328
                true
329
            )
330
            )->matches(new ObjectUrl('http://example.com/2015/10/01/36704.article/36704-1', true))
331
        );
332
        $this->assertFalse(
333
            (
334
            new ObjectUrl(
335
                'http://example.com/2015/10/01/36704.event/36704-1',
336
                true
337
            )
338
            )->matches(new ObjectUrl('http://example.com/2015/10/01/36704.event/36704-2', true))
339
        );
340
        $this->assertTrue((new ObjectUrl(self::REMOTE_URL, true))->matches(new ObjectUrl(self::REMOTE_URL, true)));
341
    }
342
343
    /**
344
     * Test an invalid apparat URL
345
     *
346
     * @expectedException \Apparat\Object\Domain\Model\Path\InvalidArgumentException
347
     * @expectedExceptionCode 1451435429
348
     */
349
    public function testInvalidApparatUrl()
350
    {
351
        new ApparatUrl(self::REMOTE_URL, true);
352
    }
353
354
    /**
355
     * Test an absolute apparat URL
356
     */
357
    public function testAbsoluteApparatUrl()
358
    {
359
        $apparatUrl = new ApparatUrl(self::APPARAT_URL, true);
360
        $this->assertInstanceOf(ApparatUrl::class, $apparatUrl);
361
        $this->assertEquals('https://apparat:[email protected]:80', Service::normalizeRepositoryUrl($apparatUrl));
362
    }
363
364
    /**
365
     * Test an unknown relative apparat URL
366
     *
367
     * @expectedException \Apparat\Object\Domain\Model\Path\ApparatInvalidArgumentException
368
     * @expectedExceptionCode 1452695654
369
     */
370
    public function testUnknownRelativeApparatUrl()
371
    {
372
        new ApparatUrl(self::PATH . self::QUERY_FRAGMENT);
373
    }
374
375
    /**
376
     * Test a relative apparat URL
377
     */
378
    public function testRelativeApparatUrl()
379
    {
380
        Repository::register(
381
            self::REPOSITORY_URL,
382
            [
383
                'type' => FileAdapterStrategy::TYPE,
384
                'root' => __DIR__,
385
            ]
386
        );
387
        $apparatUrl = new ApparatUrl(self::URL);
388
        $this->assertInstanceOf(ApparatUrl::class, $apparatUrl);
389
        $this->assertEquals(self::REPOSITORY_URL, Service::normalizeRepositoryUrl($apparatUrl));
390
    }
391
392
    /**
393
     * Test invalid date precision
394
     *
395
     * @expectedException \Apparat\Object\Domain\Model\Path\InvalidArgumentException
396
     * @expectedExceptionCode 1451514114
397
     */
398
    public function testInvalidDatePrecision()
399
    {
400
        new LocalPath(self::PATH, -1);
401
    }
402
403
    /**
404
     * Test arbitrary date precision
405
     */
406
    public function testArbitraryDatePrecision()
407
    {
408
        $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...
409
        $this->assertInstanceOf(LocalPath::class, $path);
410
    }
411
412
    /**
413
     * Test the normalization of an invalid repository URL
414
     *
415
     * @expectedException \Apparat\Object\Domain\Repository\InvalidArgumentException
416
     * @expectedExceptionCode 1453097878
417
     */
418
    public function testInvalidRepositoryUrlNormalization()
419
    {
420
        Service::normalizeRepositoryUrl(new Url(self::REMOTE_REPOSITORY_URL));
421
    }
422
423
    /**
424
     * Test the normalization of a local string repository URL
425
     */
426
    public function testLocalStringUrlNormalization()
427
    {
428
        $this->assertEquals(self::REPOSITORY_URL . self::PATH, Service::normalizeRepositoryUrl(getenv('APPARAT_BASE_URL') . self::REPOSITORY_URL . self::PATH));
429
    }
430
}
431