Passed
Push — master ( e71c55...7f377b )
by Aimeos
12:09 queued 06:04
created

StandardTest::testRate()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
rs 10
c 1
b 0
f 0
1
<?php
2
3
/**
4
 * @license LGPLv3, https://opensource.org/licenses/LGPL-3.0
5
 * @copyright Metaways Infosystems GmbH, 2011
6
 * @copyright Aimeos (aimeos.org), 2015-2021
7
 */
8
9
10
namespace Aimeos\MShop\Index\Manager;
11
12
13
class StandardTest extends \PHPUnit\Framework\TestCase
14
{
15
	private static $products;
16
	private $context;
17
	private $object;
18
	private $editor = '';
19
20
21
	public static function setUpBeforeClass() : void
22
	{
23
		$context = \TestHelperMShop::getContext();
24
25
		$manager = new \Aimeos\MShop\Index\Manager\Standard( $context );
26
		$productManager = \Aimeos\MShop\Product\Manager\Factory::create( $context );
27
28
		$search = $productManager->filter();
29
		$conditions = array(
30
			$search->compare( '==', 'product.code', array( 'CNC', 'CNE' ) ),
31
			$search->compare( '==', 'product.editor', $context->getEditor() ),
32
		);
33
		$search->setConditions( $search->and( $conditions ) );
34
		$result = $productManager->search( $search, array( 'attribute', 'price', 'text', 'product' ) );
35
36
		if( count( $result ) !== 2 ) {
37
			throw new \RuntimeException( 'Products not available' );
38
		}
39
40
		foreach( $result as $item )
41
		{
42
			self::$products[$item->getCode()] = $item;
43
			$manager->save( $item );
44
		}
45
	}
46
47
48
	protected function setUp() : void
49
	{
50
		$this->context = \TestHelperMShop::getContext();
51
		$this->editor = $this->context->getEditor();
52
		$this->object = new \Aimeos\MShop\Index\Manager\Standard( $this->context );
53
	}
54
55
56
	protected function tearDown() : void
57
	{
58
		unset( $this->object );
59
	}
60
61
62
	public function testCreateItem()
63
	{
64
		$this->assertInstanceOf( \Aimeos\MShop\Product\Item\Iface::class, $this->object->create() );
65
	}
66
67
68
	public function testCreateSearch()
69
	{
70
		$this->assertInstanceOf( \Aimeos\MW\Criteria\Iface::class, $this->object->filter() );
71
	}
72
73
74
	public function testAggregate()
75
	{
76
		$id = \Aimeos\MShop::create( \TestHelperMShop::getContext(), 'attribute' )
77
			->find( 'white', [], 'product', 'color' )->getId();
78
79
		$search = $this->object->filter( true )->add( ['index.catalog.id' => null], '!=' );
80
		$result = $this->object->aggregate( $search, 'index.attribute.id' )->toArray();
81
82
		$this->assertEquals( 14, count( $result ) );
83
		$this->assertArrayHasKey( $id, $result );
84
		$this->assertEquals( 3, $result[$id] );
85
	}
86
87
88
	public function testAggregateMultiple()
89
	{
90
		$id = \Aimeos\MShop::create( \TestHelperMShop::getContext(), 'attribute' )
91
			->find( 'white', [], 'product', 'color' )->getId();
92
93
		$search = $this->object->filter( true )->add( ['index.catalog.id' => null], '!=' );
94
		$result = $this->object->aggregate( $search, ['product.status', 'index.attribute.id'] )->toArray();
95
96
		$this->assertEquals( 14, count( $result[1] ) );
97
		$this->assertArrayHasKey( $id, $result[1] );
98
		$this->assertEquals( 3, $result[1][$id] );
99
	}
100
101
102
	public function testAggregateMax()
103
	{
104
		$search = $this->object->filter( true );
105
		$search->add( $search->is( $search->make( 'index.price:value', ['EUR'] ), '!=', null ) );
106
107
		$result = $this->object->aggregate( $search, 'product.status', 'agg:index.price:value("EUR")', 'max' )->max();
108
109
		$this->assertEquals( 600, $result );
110
	}
111
112
113
	public function testAggregateMin()
114
	{
115
		$search = $this->object->filter( true );
116
		$search->add( $search->is( $search->make( 'index.price:value', ['EUR'] ), '!=', null ) );
117
118
		$result = $this->object->aggregate( $search, 'product.status', 'agg:index.price:value("EUR")', 'min' )->min();
119
120
		$this->assertEquals( 12, $result );
121
	}
122
123
124
	public function testDeleteItems()
125
	{
126
		$this->assertEquals( $this->object, $this->object->delete( [-1] ) );
127
	}
128
129
130
	public function testFindItem()
131
	{
132
		$productManager = \Aimeos\MShop\Product\Manager\Factory::create( $this->context );
133
		$product = $productManager->find( 'CNE' );
134
135
		$this->assertEquals( $product, $this->object->find( 'CNE' ) );
136
	}
137
138
139
	public function testGetItem()
140
	{
141
		$productManager = \Aimeos\MShop\Product\Manager\Factory::create( $this->context );
142
		$product = $productManager->find( 'CNE' );
143
144
		$item = $this->object->get( $product->getId() );
145
		$this->assertEquals( $product, $item );
146
	}
147
148
149
	public function testGetResourceType()
150
	{
151
		$result = $this->object->getResourceType();
152
153
		$this->assertContains( 'index', $result );
154
		$this->assertContains( 'index/attribute', $result );
155
		$this->assertContains( 'index/supplier', $result );
156
		$this->assertContains( 'index/catalog', $result );
157
		$this->assertContains( 'index/price', $result );
158
		$this->assertContains( 'index/text', $result );
159
	}
160
161
162
	public function testGetSearchAttributes()
163
	{
164
		$attributes = $this->object->getSearchAttributes();
165
166
		foreach( $attributes as $attribute ) {
167
			$this->assertInstanceOf( \Aimeos\MW\Criteria\Attribute\Iface::class, $attribute );
168
		}
169
170
		$this->assertArrayHasKey( 'index.attribute.id', $attributes );
171
		$this->assertArrayHasKey( 'index.catalog.id', $attributes );
172
		$this->assertArrayHasKey( 'index.supplier.id', $attributes );
173
	}
174
175
176
	public function testSave()
177
	{
178
		$item = self::$products['CNE'];
179
180
		$context = $this->context;
181
		$dbm = $context->getDatabaseManager();
182
		$siteId = $context->getLocale()->getSiteId();
183
184
		$sqlAttribute = 'SELECT COUNT(*) as count FROM "mshop_index_attribute" WHERE "siteid" = ? AND "prodid" = ?';
185
		$sqlCatalog = 'SELECT COUNT(*) as count FROM "mshop_index_catalog" WHERE "siteid" = ? AND "prodid" = ?';
186
		$sqlPrice = 'SELECT COUNT(*) as count FROM "mshop_index_price" WHERE "siteid" = ? AND "prodid" = ?';
187
		$sqlText = 'SELECT COUNT(*) as count FROM "mshop_index_text" WHERE "siteid" = ? AND "prodid" = ?';
188
189
		$this->object->save( $item );
190
191
		$cntAttribute = $this->getValue( $dbm, $sqlAttribute, 'count', $siteId, $item->getId() );
192
		$cntCatalog = $this->getValue( $dbm, $sqlCatalog, 'count', $siteId, $item->getId() );
193
		$cntPrice = $this->getValue( $dbm, $sqlPrice, 'count', $siteId, $item->getId() );
194
		$cntText = $this->getValue( $dbm, $sqlText, 'count', $siteId, $item->getId() );
195
196
		$this->assertEquals( 6, $cntAttribute );
197
		$this->assertEquals( 5, $cntCatalog );
198
		$this->assertEquals( 1, $cntPrice );
199
		$this->assertEquals( 2, $cntText );
200
	}
201
202
203
	public function testSaveMultiple()
204
	{
205
		$result = $this->object->save( self::$products );
206
		$expected = [
207
			'CNC' => self::$products['CNC'],
208
			'CNE' => self::$products['CNE']
209
		];
210
		$this->assertEquals( $expected, $result );
211
	}
212
213
214
	public function testSearchItems()
215
	{
216
		$total = 0;
217
		$search = $this->object->filter();
218
		$search->slice( 0, 1 );
219
220
		$expr = array(
221
			$search->compare( '!=', 'index.catalog.id', null ),
222
			$search->compare( '=~', 'product.label', 'Cafe Noire' ),
223
			$search->compare( '==', 'product.editor', $this->editor ),
224
		);
225
		$search->setConditions( $search->and( $expr ) );
226
227
		$result = $this->object->search( $search, [], $total )->toArray();
228
229
		$this->assertEquals( 1, count( $result ) );
230
		$this->assertEquals( 2, $total );
231
	}
232
233
234
	public function testSearchItemsBase()
235
	{
236
		$search = $this->object->filter( true );
237
		$conditions = array(
238
			$search->compare( '!=', 'index.catalog.id', null ),
239
			$search->compare( '==', 'product.editor', $this->editor ),
240
			$search->getConditions()
241
		);
242
		$search->setConditions( $search->and( $conditions ) );
243
		$products = $this->object->search( $search )->toArray();
244
		$this->assertEquals( 8, count( $products ) );
245
246
		foreach( $products as $itemId => $item ) {
247
			$this->assertEquals( $itemId, $item->getId() );
248
		}
249
	}
250
251
252
	public function testSearchItemsSub()
253
	{
254
		$total = 0;
255
		$search = $this->object->filter();
256
		$search->slice( 0, 1 );
257
258
		$expr = array(
259
			$search->compare( '!=', 'index.attribute.id', null ),
260
			$search->compare( '!=', 'index.catalog.id', null ),
261
			$search->compare( '!=', 'index.supplier.id', null ),
262
			$search->compare( '>=', $search->make( 'index.price:value', ['EUR'] ), 0 ),
263
			$search->compare( '>=', $search->make( 'index.text:name', ['de'] ), '' ),
264
			$search->compare( '==', 'product.editor', $this->editor )
265
		);
266
267
		$search->setConditions( $search->and( $expr ) );
268
		$result = $this->object->search( $search, [], $total )->toArray();
269
270
		$this->assertEquals( 1, count( $result ) );
271
		$this->assertEquals( 2, $total );
272
	}
273
274
275
	public function testOptimize()
276
	{
277
		$this->assertInstanceOf( \Aimeos\MShop\Index\Manager\Iface::class, $this->object->optimize() );
278
	}
279
280
281
	public function testCleanup()
282
	{
283
		$this->assertInstanceOf( \Aimeos\MShop\Index\Manager\Iface::class, $this->object->cleanup( '1970-01-01 00:00:00' ) );
284
	}
285
286
287
	public function testRate()
288
	{
289
		$this->assertEquals( $this->object, $this->object->rate( -1, 0, 0 ) );
290
	}
291
292
293
	public function testRebuildWithList()
294
	{
295
		$manager = \Aimeos\MShop\Product\Manager\Factory::create( $this->context );
296
		$search = $manager->filter();
0 ignored issues
show
Unused Code introduced by
The assignment to $search is dead and can be removed.
Loading history...
297
298
		$search = $manager->filter();
299
		$search->setConditions( $search->compare( '==', 'product.code', array( 'CNE', 'CNC' ) ) );
300
		$items = $manager->search( $search )->toArray();
301
302
		$this->object->cleanup( date( 'Y-m-d H:i:s', time() + 1 ) )->rebuild( $items );
303
304
		$afterInsertAttr = $this->getCatalogSubDomainItems( 'index.attribute.id', 'attribute' );
305
		$afterInsertCat = $this->getCatalogSubDomainItems( 'index.catalog.id', 'catalog' );
306
307
		$this->assertEquals( 2, count( $afterInsertAttr ) );
308
		$this->assertEquals( 2, count( $afterInsertCat ) );
309
	}
310
311
312
	public function testRebuild()
313
	{
314
		$this->object->cleanup( date( 'Y-m-d H:i:s', time() + 1 ) )->rebuild();
315
316
		$afterInsertAttr = $this->getCatalogSubDomainItems( 'index.attribute.id', 'attribute' );
317
		$afterInsertCat = $this->getCatalogSubDomainItems( 'index.catalog.id', 'catalog' );
318
319
		$this->assertEquals( 13, count( $afterInsertAttr ) );
320
		$this->assertEquals( 9, count( $afterInsertCat ) );
321
	}
322
323
324
	public function testRemove()
325
	{
326
		$this->assertEquals( $this->object, $this->object->remove( [-1] ) );
327
	}
328
329
330
	public function testStock()
331
	{
332
		$this->assertEquals( $this->object, $this->object->stock( -1, 0 ) );
333
	}
334
335
336
	/**
337
	 * Returns value of a catalog_index column.
338
	 *
339
	 * @param \Aimeos\MW\DB\Manager\Iface $dbm Database Manager for connection
340
	 * @param string $sql Specified db query to find only one value
341
	 * @param string $column Column where to search
342
	 * @param string $siteId Siteid of the db entry
343
	 * @param string $productId Product id
344
	 * @return string $value Value returned for specified sql statement
345
	 * @throws \Exception If column not available or error during a connection to db
346
	 */
347
	protected function getValue( \Aimeos\MW\DB\Manager\Iface $dbm, $sql, $column, $siteId, $productId )
348
	{
349
		$config = $this->context->getConfig();
350
351
		if( $config->get( 'resource/db-product' ) === null ) {
352
			$dbname = $config->get( 'resource/default', 'db' );
353
		} else {
354
			$dbname = 'db-product';
355
		}
356
357
		$conn = $dbm->acquire( $dbname );
358
359
		try
360
		{
361
			$stmt = $conn->create( $sql );
362
			$stmt->bind( 1, $siteId, \Aimeos\MW\DB\Statement\Base::PARAM_INT );
363
			$stmt->bind( 2, $productId, \Aimeos\MW\DB\Statement\Base::PARAM_INT );
364
			$result = $stmt->execute();
365
366
			if( ( $row = $result->fetch() ) === null ) {
367
				throw new \RuntimeException( 'No rows available' );
368
			}
369
370
			if( !isset( $row[$column] ) ) {
371
				throw new \RuntimeException( sprintf( 'Column "%1$s" not available for "%2$s"', $column, $sql ) );
372
			}
373
374
			$value = $row[$column];
375
376
			$dbm->release( $conn, $dbname );
377
		}
378
		catch( \Exception $e )
379
		{
380
			$dbm->release( $conn, $dbname );
381
			throw $e;
382
		}
383
384
		return $value;
385
	}
386
387
388
	/**
389
	 * Gets product items of index subdomains specified by the key.
390
	 *
391
	 * @param string $key Key for searchItems
392
	 * @param string $domain Subdomain of index manager
393
	 */
394
	protected function getCatalogSubDomainItems( $key, $domain )
395
	{
396
		$subIndex = $this->object->getSubManager( $domain );
397
		$search = $subIndex->filter();
398
399
		$expr = array(
400
			$search->compare( '!=', $key, null ),
401
			$search->compare( '==', 'product.editor', $this->editor )
402
		);
403
404
		$search->setConditions( $search->and( $expr ) );
405
406
		return $subIndex->search( $search )->toArray();
407
	}
408
409
}
410