Completed
Push — master ( 954878...4f4902 )
by Joschi
03:36
created

RelationTest::testRelationProxying()   B

Complexity

Conditions 5
Paths 3

Size

Total Lines 20
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 5
eloc 11
c 1
b 0
f 1
nc 3
nop 0
dl 0
loc 20
rs 8.8571
1
<?php
2
3
/**
4
 * apparat-object
5
 *
6
 * @category    Apparat
7
 * @package     Apparat\Object
8
 * @subpackage  Apparat\Object\Test
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)
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\Object\Application\Model\Object\Article;
41
use Apparat\Object\Domain\Factory\RelationFactory;
42
use Apparat\Object\Domain\Model\Object\ObjectInterface;
43
use Apparat\Object\Domain\Model\Properties\Relations;
44
use Apparat\Object\Domain\Model\Relation\ContributedByRelation;
45
use Apparat\Object\Domain\Model\Uri\Url;
46
use Apparat\Object\Infrastructure\Model\Object\Object;
47
use Apparat\Object\Ports\Types\Relation;
48
49
/**
50
 * Object relation test
51
 *
52
 * @package Apparat\Object
53
 * @subpackage Apparat\Object\Tests
54
 */
55
class RelationTest extends AbstractRepositoryEnabledTest
56
{
57
    /**
58
     * Example object locator
59
     *
60
     * @var string
61
     */
62
    const OBJECT_LOCATOR = '/2015/12/21/1-article/1';
63
64
    /**
65
     * Test the addition of an object relation
66
     *
67
     * @expectedException \Apparat\Object\Domain\Model\Relation\OutOfBoundsException
68
     * @expectedExceptionCode 1462401333
69
     */
70
    public function testObjectAddRelation()
71
    {
72
        $article = Object::load(getenv('REPOSITORY_URL').self::OBJECT_LOCATOR);
73
        $this->assertInstanceOf(Article::class, $article);
74
        $article->addRelation('http://example.com <[email protected]> John Doe', Relation::EMBEDDED_BY);
75
        $this->assertEquals(3, count($article->findRelations([Relation::URL => 'example.com'])));
76
        foreach ($article->findRelations([Relation::EMAIL => 'tollwerk.de']) as $relation) {
77
            $article->deleteRelation($relation);
78
        }
79
        $this->assertEquals(6, count($article->getRelations()));
80
        $article->addRelation('http://example.com <[email protected]> John Doe', 'invalid');
81
    }
82
83
    /**
84
     * Test a relation deserialization with repeated email
85
     *
86
     * @expectedException \Apparat\Object\Domain\Model\Relation\InvalidArgumentException
87
     * @expectedExceptionCode 1462395977
88
     */
89
    public function testInvalidRelationEmail()
90
    {
91
        RelationFactory::createFromString(Relation::CONTRIBUTED_BY, '<invalid', self::$repository);
92
    }
93
94
    /**
95
     * Test a relation deserialization with repeated email
96
     *
97
     * @expectedException \Apparat\Object\Domain\Model\Relation\InvalidArgumentException
98
     * @expectedExceptionCode 1462394737
99
     */
100
    public function testRepeatedRelationEmail()
101
    {
102
        RelationFactory::createFromString(
103
            Relation::CONTRIBUTED_BY,
104
            '<[email protected]> <[email protected]>',
105
            self::$repository
106
        );
107
    }
108
109
    /**
110
     * Test a relation deserialization with repeated URL
111
     *
112
     * @expectedException \Apparat\Object\Domain\Model\Relation\InvalidArgumentException
113
     * @expectedExceptionCode 1462394737
114
     */
115
    public function testRepeatedRelationUrl()
116
    {
117
        RelationFactory::createFromString(
118
            Relation::CONTRIBUTED_BY,
119
            'http://example.com http://example.com',
120
            self::$repository
121
        );
122
    }
123
124
    /**
125
     * Test a relation construction
126
     *
127
     * @expectedException \Apparat\Object\Domain\Model\Properties\InvalidArgumentException
128
     * @expectedExceptionCode 1462703468
129
     */
130
    public function testRelationConstruction()
131
    {
132
        $article = Object::load(getenv('REPOSITORY_URL').self::OBJECT_LOCATOR);
133
134
        /** @var Relations $relations */
135
        $relations = Kernel::create(Relations::class, [[Relation::CONTRIBUTED_BY => []], $article]);
136
137
        // Multiple relation addition
138
        $relations = $relations->addRelation('http://example.org John Doe', Relation::CONTRIBUTED_BY);
139
        $relations = $relations->addRelation('http://example.org John Doe', Relation::CONTRIBUTED_BY);
140
141
        // Retrieve contributed-by relations
142
        $contributedByRels = $relations->getRelations(Relation::CONTRIBUTED_BY);
143
        $this->assertEquals(1, count($contributedByRels));
144
145
        // Multiple relation deletion
146
        $relations = $relations->deleteRelation($contributedByRels[0]);
147
        $relations = $relations->deleteRelation($contributedByRels[0]);
148
149
        // Add invalid relation
150
        $relations->addRelation(null);
151
    }
152
153
    /**
154
     * Test the filtering of relations
155
     */
156
    public function testRelationFiltering()
157
    {
158
        $article = Object::load(getenv('REPOSITORY_URL').self::OBJECT_LOCATOR);
159
160
        /** @var Relations $relations */
161
        $relations = Kernel::create(Relations::class, [[Relation::CONTRIBUTED_BY => []], $article]);
162
        $relations = $relations->addRelation(
163
            '!/repo/2016/01/08/2-contact/2 <[email protected]> John Doe',
164
            Relation::CONTRIBUTED_BY
165
        );
166
167
        // Filter by type
168
        $this->assertEquals(1, count($relations->findRelations([Relation::TYPE => Relation::CONTRIBUTED_BY])));
169
        $this->assertEquals(0, count($relations->findRelations([Relation::TYPE => Relation::CONTRIBUTES])));
170
171
        // Filter by URL
172
        $this->assertEquals(1, count($relations->findRelations([Relation::URL => 'repo'])));
173
        $this->assertEquals(0, count($relations->findRelations([Relation::URL => 'example.com'])));
174
175
        // Filter by email
176
        $this->assertEquals(1, count($relations->findRelations([Relation::EMAIL => '@example.com'])));
177
        $this->assertEquals(0, count($relations->findRelations([Relation::EMAIL => '@test.com'])));
178
179
        // Filter by label
180
        $this->assertEquals(1, count($relations->findRelations([Relation::LABEL => 'John'])));
181
        $this->assertEquals(0, count($relations->findRelations([Relation::LABEL => 'Jane'])));
182
183
        // Filter by coupling
184
        $this->assertEquals(1, count($relations->findRelations([Relation::COUPLING => true])));
185
        $this->assertEquals(0, count($relations->findRelations([Relation::COUPLING => false])));
186
187
        // Filter by invalid criteria
188
        $this->assertEquals(0, count($relations->findRelations(['invalid' => 'invalid'])));
189
    }
190
191
    /**
192
     * Test invalid relation coupling
193
     *
194
     * @expectedException \Apparat\Object\Domain\Model\Relation\OutOfBoundsException
195
     * @expectedExceptionCode 1462311299
196
     */
197
    public function testInvalidRelationCoupling()
198
    {
199
        Kernel::create(ContributedByRelation::class, ['Label', '[email protected]', 'invalid-coupling']);
200
    }
201
202
    /**
203
     * Test relation getters & setters
204
     *
205
     * @expectedException \Apparat\Object\Domain\Model\Relation\OutOfBoundsException
206
     * @expectedExceptionCode 1462311299
207
     */
208
    public function testRelationGetterSetters()
209
    {
210
        $url = Kernel::create(Url::class, [self::OBJECT_LOCATOR]);
211
        $this->assertInstanceOf(Url::class, $url);
212
213
        /** @var ContributedByRelation $relation */
214
        $relation = Kernel::create(
215
            ContributedByRelation::class,
216
            [$url, 'label', '[email protected]', Relation::LOOSE_COUPLING]
217
        );
218
        $this->assertInstanceOf(ContributedByRelation::class, $relation);
219
220
        // Set the URL
221
        $url2 = Kernel::create(Url::class, ['http://example.com/test']);
222
        $this->assertInstanceOf(Url::class, $url2);
223
        $relation = $relation->setUrl($url2)
224
            ->setLabel('Modified label')
225
            ->setEmail('[email protected]')
226
            ->setCoupling(Relation::TIGHT_COUPLING);
227
        $relation->setCoupling('invalid-coupling');
228
    }
229
230
    /**
231
     * Test relation proxying
232
     */
233
    public function testRelationProxying()
234
    {
235
        $article = Object::load(getenv('REPOSITORY_URL').self::OBJECT_LOCATOR);
236
        $this->assertInstanceOf(Article::class, $article);
237
238
        $relationFilter = [
239
            Relation::URL => 'contact',
240
            Relation::TYPE => ContributedByRelation::TYPE,
241
        ];
242
        foreach ($article->findRelations($relationFilter) as $relation) {
243
            $this->assertInstanceOf(ContributedByRelation::class, $relation);
244
245
            // Test for object proxies
246
            if (($relation instanceof ObjectInterface)
247
                && (!$relation->getUrl()->isAbsolute() || $relation->getUrl()->isAbsoluteLocal())
248
            ) {
249
                $this->assertEquals('John Doe', $relation->getTitle());
250
            }
251
        }
252
    }
253
}
254