Completed
Branch master (6c7c3c)
by Joschi
02:33
created

ItemTest::testItemUnprofiledProperty()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 20
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
dl 0
loc 20
c 1
b 0
f 0
rs 9.4285
cc 1
eloc 12
nc 1
nop 0
1
<?php
2
3
/**
4
 * micrometa
5
 *
6
 * @category Jkphl
7
 * @package Jkphl\Micrometa
8
 * @subpackage Infrastructure
9
 * @author Joschi Kuphal <[email protected]> / @jkphl
10
 * @copyright Copyright © 2017 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 © 2017 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 Jkphl\Micrometa\Tests\Ports;
38
39
use Jkphl\Micrometa\Application\Item\PropertyList;
40
use Jkphl\Micrometa\Application\Value\StringValue;
41
use Jkphl\Micrometa\Infrastructure\Factory\MicroformatsFactory;
42
use Jkphl\Micrometa\Ports\Item\Item;
43
use Jkphl\Micrometa\Ports\Item\ItemInterface;
44
use Jkphl\Micrometa\Ports\Item\ItemList;
45
use Jkphl\Micrometa\Tests\AbstractTestBase;
46
use Jkphl\Micrometa\Tests\MicroformatsFeedTrait;
47
48
/**
49
 * Parser factory tests
50
 *
51
 * @package Jkphl\Micrometa
52
 * @subpackage Jkphl\Micrometa\Tests
53
 */
54
class ItemTest extends AbstractTestBase
55
{
56
    /**
57
     * Use the Microformats feed method
58
     */
59
    use MicroformatsFeedTrait;
60
61
    /**
62
     * Test an item
63
     */
64
    public function testItemTypes()
65
    {
66
        $feedItem = $this->getFeedItem();
67
        $this->assertInstanceOf(Item::class, $feedItem);
68
69
        // Test the item type
70
        $this->assertTrue($feedItem->isOfType('h-feed'));
71
        $this->assertTrue($feedItem->isOfType('h-feed', MicroformatsFactory::MF2_PROFILE_URI));
72
        $this->assertFalse($feedItem->isOfType('invalid', MicroformatsFactory::MF2_PROFILE_URI));
73
74
        // Test other item properties
75
        $this->assertEquals('feed-id', $feedItem->getId());
76
        $this->assertEquals('feed-language', $feedItem->getLanguage());
77
        $this->assertEquals('feed-value', $feedItem->getValue());
78
    }
79
80
    /**
81
     * Test the item properties
82
     *
83
     * @expectedException \Jkphl\Micrometa\Ports\Exceptions\OutOfBoundsException
84
     * @expectedExceptionCode 1491672553
85
     */
86
    public function testItemProperties()
87
    {
88
        $feedItem = $this->getFeedItem();
89
        $this->assertInstanceOf(Item::class, $feedItem);
90
91
        $properties = $feedItem->getProperties();
92
        $this->assertInstanceOf(PropertyList::class, $properties);
93
        $this->assertEquals(3, count($properties));
94
95
        // Get an unknown property
96
        $feedItem->getProperty('name', null, 2);
97
    }
98
99
    /**
100
     * Test the item export
101
     */
102
    public function testItemExport()
103
    {
104
        $feedItem = $this->getFeedItem();
105
        $this->assertInstanceOf(Item::class, $feedItem);
106
107
        $export = $feedItem->toObject();
108
        $this->assertInstanceOf(\stdClass::class, $export);
109
        foreach (['format', 'types', 'properties', 'items'] as $property) {
110
            $this->assertTrue(isset($export->$property));
111
        }
112
    }
113
114
    /**
115
     * Test an unprofiled property
116
     *
117
     * @expectedException \Jkphl\Micrometa\Ports\Exceptions\OutOfBoundsException
118
     * @expectedExceptionCode 1488315604
119
     */
120
    public function testItemUnprofiledProperty()
121
    {
122
        $feedItem = $this->getFeedItem();
123
        $this->assertInstanceOf(Item::class, $feedItem);
124
125
        // Test the item name as an unprofiled property value list
126
        $feedNameList = $feedItem->getProperty('name');
127
        $this->assertTrue(is_array($feedNameList));
128
        $this->assertEquals(1, count($feedNameList));
129
        $this->assertInstanceOf(StringValue::class, $feedNameList[0]);
130
        $this->assertEquals('John Doe\'s Blog', strval($feedNameList[0]));
131
132
        // Test the item name as an unprofiled single property value
133
        $feedName = $feedItem->getProperty('name', null, 0);
134
        $this->assertInstanceOf(StringValue::class, $feedName);
135
        $this->assertEquals('John Doe\'s Blog', strval($feedName));
136
137
        // Test an invalid unprofiled property
138
        $feedItem->getProperty('invalid');
139
    }
140
141
    /**
142
     * Test a profiled property
143
     *
144
     * @expectedException \Jkphl\Micrometa\Ports\Exceptions\OutOfBoundsException
145
     * @expectedExceptionCode 1488315604
146
     */
147
    public function testItemProfiledProperty()
148
    {
149
        $feedItem = $this->getFeedItem();
150
        $this->assertInstanceOf(Item::class, $feedItem);
151
152
        // Test the item name as an unprofiled property value list
153
        $feedNameList = $feedItem->getProperty('name', MicroformatsFactory::MF2_PROFILE_URI);
154
        $this->assertTrue(is_array($feedNameList));
155
        $this->assertEquals(1, count($feedNameList));
156
        $this->assertInstanceOf(StringValue::class, $feedNameList[0]);
157
        $this->assertEquals('John Doe\'s Blog', strval($feedNameList[0]));
158
159
        // Test the item name as an unprofiled single property value
160
        $feedName = $feedItem->getProperty('name', MicroformatsFactory::MF2_PROFILE_URI, 0);
161
        $this->assertInstanceOf(StringValue::class, $feedName);
162
        $this->assertEquals('John Doe\'s Blog', strval($feedName));
163
164
        // Test an invalid unprofiled property
165
        $feedItem->getProperty('invalid', MicroformatsFactory::MF2_PROFILE_URI);
166
    }
167
168
    /**
169
     * Test an unprofiled property
170
     *
171
     * @expectedException \Jkphl\Micrometa\Ports\Exceptions\OutOfBoundsException
172
     * @expectedExceptionCode 1488315604
173
     */
174
    public function testItemAliasedProperty()
175
    {
176
        $feedItem = $this->getFeedItem();
177
        $this->assertInstanceOf(Item::class, $feedItem);
178
179
        // Run the custom item property tests
180
        $this->runCustomItemPropertyTests($feedItem);
181
182
        // Test an invalid property
183
        $feedItem->invalidProperty;
184
    }
185
186
    /**
187
     * Run the custom item property tests
188
     *
189
     * @param Item $feedItem Feed item
190
     */
191
    protected function runCustomItemPropertyTests(Item $feedItem)
192
    {
193
        // Test the custom item property as an unprofiled property value list
194
        $feedCustomPropList = $feedItem->getProperty('custom-property');
195
        $this->assertTrue(is_array($feedCustomPropList));
196
        $this->assertEquals(1, count($feedCustomPropList));
197
        $this->assertInstanceOf(StringValue::class, $feedCustomPropList[0]);
198
        $this->assertEquals('Property for alias testing', strval($feedCustomPropList[0]));
199
200
        // Test the custom item property as an unprofiled single property value
201
        $feedCustomProp = $feedItem->getProperty('custom-property', null, 0);
202
        $this->assertInstanceOf(StringValue::class, $feedCustomProp);
203
        $this->assertEquals('Property for alias testing', strval($feedCustomProp));
204
205
        // Test the custom item property via the convenience getter
206
        $feedCustomProp = $feedItem->customProperty;
207
        $this->assertInstanceOf(StringValue::class, $feedCustomProp);
208
        $this->assertEquals('Property for alias testing', strval($feedCustomProp));
209
    }
210
211
    /**
212
     * Test a property stack
213
     *
214
     * @expectedException \Jkphl\Micrometa\Ports\Exceptions\OutOfBoundsException
215
     * @expectedExceptionCode 1488315604
216
     */
217
    public function testItemPropertyStack()
218
    {
219
        $feedItem = $this->getFeedItem();
220
        $this->assertInstanceOf(Item::class, $feedItem);
221
222
        // Request a valid property stack
223
        $propertyValues = $feedItem->getFirstProperty('photo', MicroformatsFactory::MF2_PROFILE_URI, 'name');
224
        $this->assertEquals(['John Doe\'s Blog'], $propertyValues);
225
226
        // Request unknown properties only
227
        $feedItem->getFirstProperty('photo', MicroformatsFactory::MF2_PROFILE_URI, 'invalid');
228
    }
229
230
    /**
231
     * Test a property item
232
     */
233
    public function testItemPropertyItem()
234
    {
235
        $feedItem = $this->getFeedItem();
236
        $this->assertInstanceOf(Item::class, $feedItem);
237
238
        // Request a valid property stack
239
        /** @var ItemInterface[] $authors */
240
        $authors = $feedItem->getFirstProperty('author');
241
        $this->assertTrue(is_array($authors));
242
        $this->assertInstanceOf(ItemInterface::class, $authors[0]);
243
244
        // Test the author name as an unprofiled single property value
245
        $authorName = $authors[0]->getProperty('name', MicroformatsFactory::MF2_PROFILE_URI, 0);
246
        $this->assertInstanceOf(StringValue::class, $authorName);
247
        $this->assertEquals('John Doe', strval($authorName));
248
    }
249
250
    /**
251
     * Test nested items
252
     *
253
     * @expectedException \Jkphl\Micrometa\Ports\Exceptions\InvalidArgumentException
254
     * @expectedExceptionCode 1492418709
255
     */
256
    public function testItemNestedItems()
257
    {
258
        $feedItem = $this->getFeedItem();
259
        $this->assertInstanceOf(Item::class, $feedItem);
260
261
        // Test the number of nested items
262
        $this->assertEquals(2, count($feedItem));
263
        $this->assertEquals(2, count($feedItem->getItems()));
264
        foreach ($feedItem as $itemIndex => $entryItem) {
265
            $this->assertInstanceOf(ItemInterface::class, $entryItem);
266
            $this->assertTrue(is_int($itemIndex));
267
        }
268
        $this->assertInstanceOf(ItemInterface::class, $feedItem->getFirstItem('h-entry'));
269
        $this->assertInstanceOf(
270
            ItemInterface::class, $feedItem->getFirstItem('h-entry', MicroformatsFactory::MF2_PROFILE_URI)
271
        );
272
273
        // Test the second entry item
274
        $this->runFeedNestedEntryItemTest($feedItem);
275
    }
276
277
    /**
278
     * Test a nested entry item
279
     *
280
     * @param ItemInterface $feedItem Feed item
281
     */
282
    protected function runFeedNestedEntryItemTest(ItemInterface $feedItem)
283
    {
284
        $entryItem = $feedItem->getItems('h-entry')[1];
285
        $this->assertInstanceOf(ItemInterface::class, $entryItem);
286
287
        // Test the magic item getter / item type aliases
288
        /** @noinspection PhpUndefinedMethodInspection */
289
        $entryItem = $feedItem->hEntry(0);
290
        $this->assertInstanceOf(ItemInterface::class, $entryItem);
291
        /** @noinspection PhpUndefinedMethodInspection */
292
        $feedItem->hEntry(-1);
293
    }
294
295
    /**
296
     * Test non-existent nested item
297
     *
298
     * @expectedException \Jkphl\Micrometa\Ports\Exceptions\OutOfBoundsException
299
     * @expectedExceptionCode 1492418999
300
     */
301
    public function testItemNonExistentNestedItems()
302
    {
303
        $feedItem = $this->getFeedItem();
304
        /** @noinspection PhpUndefinedMethodInspection */
305
        $this->assertEquals('John Doe', $feedItem->hEntry()->author->name);
306
        /** @noinspection PhpUndefinedMethodInspection */
307
        $feedItem->hEntry(2);
308
    }
309
310
    /**
311
     * Test the item list export
312
     *
313
     * @expectedException \Jkphl\Micrometa\Ports\Exceptions\OutOfBoundsException
314
     * @expectedExceptionCode 1492030227
315
     */
316
    public function testItemListExport()
317
    {
318
        $feedItem = $this->getFeedItem();
319
        $itemList = new ItemList([$feedItem]);
320
        $this->assertInstanceOf(ItemList::class, $itemList);
321
322
        $export = $itemList->toObject();
323
        $this->assertInstanceOf(\stdClass::class, $export);
324
        $this->assertTrue(isset($export->items));
325
        $this->assertTrue(is_array($export->items));
326
        $this->assertEquals($feedItem->toObject(), current($export->items));
327
328
        $itemList->getFirstItem('invalid');
329
    }
330
331
    /**
332
     * Test the item list immutability
333
     *
334
     * @expectedException \Jkphl\Micrometa\Ports\Exceptions\RuntimeException
335
     * @expectedExceptionCode 1495988721
336
     */
337
    public function testItemListImmutabilitySet()
338
    {
339
        $feedItem = $this->getFeedItem();
340
        $itemList = new ItemList([$feedItem]);
341
        $this->assertInstanceOf(ItemList::class, $itemList);
342
        $this->assertEquals($feedItem, $itemList[0]);
343
        $itemList[1] = $feedItem;
344
    }
345
346
    /**
347
     * Test the item list immutability
348
     *
349
     * @expectedException \Jkphl\Micrometa\Ports\Exceptions\RuntimeException
350
     * @expectedExceptionCode 1495988721
351
     */
352
    public function testItemListImmutabilityUnset()
353
    {
354
        $feedItem = $this->getFeedItem();
355
        $itemList = new ItemList([$feedItem]);
356
        $this->assertInstanceOf(ItemList::class, $itemList);
357
        $this->assertEquals($feedItem, $itemList[0]);
358
        unset($itemList[0]);
359
    }
360
}
361