testGetEntityIdsForQueryWithoutLimits()   B
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 37
Code Lines 30

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 37
rs 8.8571
cc 1
eloc 30
nc 1
nop 0
1
<?php
2
3
namespace Wikibase\EntityStore\MongoDB;
4
5
use ArrayIterator;
6
use Ask\Language\Description\AnyValue;
7
use Ask\Language\Description\Conjunction;
8
use Ask\Language\Description\Description;
9
use Ask\Language\Description\Disjunction;
10
use Ask\Language\Description\SomeProperty;
11
use Ask\Language\Description\ValueDescription;
12
use Ask\Language\Option\QueryOptions;
13
use DataValues\MonolingualTextValue;
14
use DataValues\StringValue;
15
use DataValues\TimeValue;
16
use MongoRegex;
17
use Wikibase\DataModel\Entity\EntityIdValue;
18
use Wikibase\DataModel\Entity\Item;
19
use Wikibase\DataModel\Entity\ItemId;
20
use Wikibase\DataModel\Entity\PropertyId;
21
use Wikibase\EntityStore\FeatureNotSupportedException;
22
23
/**
24
 * @covers Wikibase\EntityStore\MongoDB\MongoDBEntityIdForQueryLookup
25
 *
26
 * @licence GPLv2+
27
 * @author Thomas Pellissier Tanon
28
 */
29
class MongoDBEntityIdForQueryLookupTest extends \PHPUnit_Framework_TestCase {
30
31
	/**
32
	 * @dataProvider getEntityIdsForQueryProvider
33
	 */
34
	public function testGetEntityIdsForQuery(
35
		Description $queryDescription,
36
		QueryOptions $queryOptions,
37
		$type = null,
38
		$mongoQuery,
39
		$skip,
40
		$limit,
41
		$mongoResult
42
	) {
43
		$cursorMock = $this->getMockBuilder( 'Doctrine\MongoDB\Cursor' )
44
			->disableOriginalConstructor()
45
			->getMock();
46
		$cursorMock->expects( $this->once() )
47
			->method( 'skip' )
48
			->with( $this->equalTo( $skip ) )
49
			->willReturn( $cursorMock );
50
		$cursorMock->expects( $this->once() )
51
			->method( 'limit' )
52
			->with( $this->equalTo( $limit ) )
53
				->willReturn( new ArrayIterator( $mongoResult ) );
54
55
		$collectionMock = $this->getMockBuilder( 'Doctrine\MongoDB\Collection' )
56
			->disableOriginalConstructor()
57
			->getMock();
58
		$collectionMock->expects( $this->once() )
59
			->method( 'find' )
60
			->with( $this->equalTo( $mongoQuery ) )
61
			->willReturn( $cursorMock );
62
63
		$databaseMock = $this->getMockBuilder( 'Doctrine\MongoDB\Database' )
64
			->disableOriginalConstructor()
65
			->getMock();
66
		$databaseMock->expects( $this->once() )
67
			->method( 'selectCollection' )
68
			->with( $this->equalTo( $type ) )
69
			->willReturn( $collectionMock );
70
71
		$documentBuilderMock = $this->getMockBuilder( 'Wikibase\EntityStore\MongoDB\MongoDBDocumentBuilder' )
72
			->disableOriginalConstructor()
73
			->getMock();
74
		$documentBuilderMock->expects( $this->once() )
75
			->method( 'buildEntityIdForDocument' )
76
			->with( $this->equalTo( [ '_id' => 'Q1' ] ) )
77
			->willReturn( new ItemId( 'Q1' ) );
78
		$documentBuilderMock->expects( $this->any() )
79
			->method( 'buildIntegerForType' )
80
			->with( $this->equalTo( 'item' ) )
81
			->willReturn( 0 );
82
		$documentBuilderMock->expects( $this->any() )
83
			->method( 'buildSearchedStringValue' )
84
			->with( $this->equalTo( 'foo' ) )
85
			->willReturn( 'foo' );
86
87
		$lookup = new MongoDBEntityIdForQueryLookup( $databaseMock, $documentBuilderMock );
88
89
		$this->assertEquals(
90
			[ new ItemId( 'Q1' ) ],
91
			$lookup->getEntityIdsForQuery( $queryDescription, $queryOptions, $type )
92
		);
93
	}
94
95
	public function getEntityIdsForQueryProvider() {
96
		return [
97
			[
98
				new AnyValue(),
99
				new QueryOptions( 10, 0 ),
100
				null,
101
				[],
102
				0,
103
				10,
104
				[ [ '_id' => 'Q1' ] ]
105
			],
106
			[
107
				new SomeProperty(
108
					new EntityIdValue( new PropertyId( 'P1' ) ),
109
					new ValueDescription( new EntityIdValue( new ItemId( 'Q1' ) ) )
110
				),
111
				new QueryOptions( 20, 10 ),
112
				Item::ENTITY_TYPE,
113
				[ 'sclaims.wikibase-entityid' => 'P1-Q1' ],
114
				10,
115
				20,
116
				[ [ '_id' => 'Q1' ] ]
117
			],
118
			[
119
				new Conjunction( [
120
					new SomeProperty(
121
						new EntityIdValue( new PropertyId( 'P42' ) ),
122
						new ValueDescription( new StringValue( 'foo' ) )
123
					),
124
					new SomeProperty(
125
						new EntityIdValue( new PropertyId( 'P1' ) ),
126
						new ValueDescription( new EntityIdValue( new PropertyId( 'P42' ) ) )
127
					)
128
				] ),
129
				new QueryOptions( 10, 0 ),
130
				Item::ENTITY_TYPE,
131
				[
132
					'$and' => [
133
						[ 'sclaims.string' => 'P42-foo' ],
134
						[ 'sclaims.wikibase-entityid' => 'P1-P42' ]
135
					]
136
				],
137
				0,
138
				10,
139
				[ [ '_id' => 'Q1' ] ]
140
			],
141
			[
142
				new Disjunction( [
143
					new SomeProperty(
144
						new EntityIdValue( new PropertyId( 'P42' ) ),
145
						new ValueDescription( new StringValue( 'foo' ) )
146
					),
147
					new SomeProperty(
148
						new EntityIdValue( new PropertyId( 'P1' ) ),
149
						new ValueDescription( new EntityIdValue( new PropertyId( 'P42' ) ) )
150
					)
151
				] ),
152
				new QueryOptions( 10, 0 ),
153
				Item::ENTITY_TYPE,
154
				[
155
					'$or' => [
156
						[ 'sclaims.string' => 'P42-foo' ],
157
						[ 'sclaims.wikibase-entityid' => 'P1-P42' ]
158
					]
159
				],
160
				0,
161
				10,
162
				[ [ '_id' => 'Q1' ] ]
163
			],
164
			[
165
				new SomeProperty(
166
					new EntityIdValue( new PropertyId( 'P42' ) ),
167
					new Conjunction( [
168
						new Disjunction( [
169
							new ValueDescription( new StringValue( 'foo' ) )
170
						] ),
171
						new AnyValue(),
172
						new ValueDescription( new EntityIdValue( new PropertyId( 'P42' ) ) )
173
					] )
174
				),
175
				new QueryOptions( 10, 0 ),
176
				Item::ENTITY_TYPE,
177
				[
178
					'$and' => [
179
						[
180
							'$or' => [
181
								[ 'sclaims.string' => 'P42-foo' ]
182
							]
183
						],
184
						[],
185
						[ 'sclaims.wikibase-entityid' => 'P42-P42' ]
186
					]
187
				],
188
				0,
189
				10,
190
				[ [ '_id' => 'Q1' ] ]
191
			],
192
			[
193
				new SomeProperty(
194
					new EntityIdValue( new PropertyId( 'P42' ) ),
195
					new ValueDescription(
196
						new TimeValue( '+1952-03-11T00:00:00Z', 0, 0, 0, TimeValue::PRECISION_DAY, 'foo' )
197
					)
198
				),
199
				new QueryOptions( 10, 0 ),
200
				Item::ENTITY_TYPE,
201
				[ 'sclaims.time' => new MongoRegex( '/^P42\-\+1952\-03\-11/' ) ],
202
				0,
203
				10,
204
				[ [ '_id' => 'Q1' ] ]
205
			],
206
			[
207
				new SomeProperty(
208
					new EntityIdValue( new PropertyId( 'P42' ) ),
209
					new ValueDescription(
210
						new TimeValue( '+1952-00-00T00:00:00Z', 0, 0, 0, TimeValue::PRECISION_YEAR, 'foo' )
211
					)
212
				),
213
				new QueryOptions( 10, 0 ),
214
				Item::ENTITY_TYPE,
215
				[ 'sclaims.time' => new MongoRegex( '/^P42\-\+1952/' ) ],
216
				0,
217
				10,
218
				[ [ '_id' => 'Q1' ] ]
219
			],
220
		];
221
	}
222
223
	public function testGetEntityIdsForQueryWithoutLimits() {
224
225
		$collectionMock = $this->getMockBuilder( 'Doctrine\MongoDB\Collection' )
226
			->disableOriginalConstructor()
227
			->getMock();
228
		$collectionMock->expects( $this->once() )
229
			->method( 'find' )
230
			->with( $this->equalTo( [] ) )
231
			->willReturn( new ArrayIterator( [ [ '_id' => 'Q1' ] ] ) );
232
233
		$databaseMock = $this->getMockBuilder( 'Doctrine\MongoDB\Database' )
234
			->disableOriginalConstructor()
235
			->getMock();
236
		$databaseMock->expects( $this->once() )
237
			->method( 'selectCollection' )
238
			->with( $this->equalTo( Item::ENTITY_TYPE ) )
239
			->willReturn( $collectionMock );
240
241
		$documentBuilderMock = $this->getMockBuilder( 'Wikibase\EntityStore\MongoDB\MongoDBDocumentBuilder' )
242
			->disableOriginalConstructor()
243
			->getMock();
244
		$documentBuilderMock->expects( $this->once() )
245
			->method( 'buildEntityIdForDocument' )
246
			->with( $this->equalTo( [ '_id' => 'Q1' ] ) )
247
			->willReturn( new ItemId( 'Q1' ) );
248
		$documentBuilderMock->expects( $this->any() )
249
			->method( 'buildIntegerForType' )
250
			->with( $this->equalTo( 'item' ) )
251
			->willReturn( 0 );
252
253
		$lookup = new MongoDBEntityIdForQueryLookup( $databaseMock, $documentBuilderMock );
254
255
		$this->assertEquals(
256
			[ new ItemId( 'Q1' ) ],
257
			$lookup->getEntityIdsForQuery( new AnyValue(), null, Item::ENTITY_TYPE )
258
		);
259
	}
260
261
	/**
262
	 * @dataProvider getEntityIdsForQueryWithFeatureNotSupportedExceptionProvider
263
	 */
264
	public function testGetEntityIdsForQueryWithFeatureNotSupportedException( Description $queryDescription ) {
265
		$collectionMock = $this->getMockBuilder( 'Doctrine\MongoDB\Collection' )
266
			->disableOriginalConstructor()
267
			->getMock();
268
269
		$databaseMock = $this->getMockBuilder( 'Doctrine\MongoDB\Database' )
270
			->disableOriginalConstructor()
271
			->getMock();
272
		$databaseMock->expects( $this->once() )
273
			->method( 'selectCollection' )
274
			->willReturn( $collectionMock );
275
276
		$documentBuilderMock = $this->getMockBuilder( 'Wikibase\EntityStore\MongoDB\MongoDBDocumentBuilder' )
277
			->disableOriginalConstructor()
278
			->getMock();
279
		$documentBuilderMock->expects( $this->any() )
280
			->method( 'buildIntegerForType' )
281
			->with( $this->equalTo( 'foo' ) )
282
			->willThrowException( new FeatureNotSupportedException() );
283
284
		$lookup = new MongoDBEntityIdForQueryLookup( $databaseMock, $documentBuilderMock );
285
286
		$this->setExpectedException( 'Wikibase\EntityStore\FeatureNotSupportedException');
287
		$lookup->getEntityIdsForQuery( $queryDescription, null, 'item' );
288
	}
289
290
	public function getEntityIdsForQueryWithFeatureNotSupportedExceptionProvider() {
291
		return [
292
			[
293
				$this->getMockForAbstractClass( 'Ask\Language\Description\Description' )
294
			],
295
			[
296
				new SomeProperty(
297
					new StringValue( 'foo' ),
298
					new ValueDescription( new EntityIdValue( new ItemId( 'Q1' ) ) )
299
				)
300
			],
301
			[
302
				new SomeProperty(
303
					new EntityIdValue( new ItemId( 'Q1' ) ),
304
					new ValueDescription( new EntityIdValue( new ItemId( 'Q1' ) ) )
305
				)
306
			],
307
			[
308
				new SomeProperty(
309
					new EntityIdValue( new PropertyId( 'P42' ) ),
310
					new SomeProperty(
311
						new EntityIdValue( new PropertyId( 'P42' ) ),
312
						new ValueDescription( new EntityIdValue( new ItemId( 'Q1' ) ) ),
313
						true
314
					)
315
				)
316
			],
317
			[
318
				new SomeProperty(
319
					new EntityIdValue( new PropertyId( 'P42' ) ),
320
					new ValueDescription( new EntityIdValue( new ItemId( 'Q1' ) ), ValueDescription::COMP_GREATER )
321
				)
322
			],
323
			[
324
				new SomeProperty(
325
					new EntityIdValue( new PropertyId( 'P42' ) ),
326
					new ValueDescription( new MonolingualTextValue( 'en', 'Foo' ) )
327
				)
328
			],
329
			[
330
				new SomeProperty(
331
					new EntityIdValue( new PropertyId( 'P42' ) ),
332
					new ValueDescription( new EntityIdValue(
333
						$this->getMockForAbstractClass( 'Wikibase\DataModel\Entity\EntityId' )
334
					) )
335
				)
336
			],
337
		];
338
	}
339
}
340