Completed
Push — master ( f2f6e8...470987 )
by mw
33:59
created

SemanticDataStorageDBIntegrationTest   A

Complexity

Total Complexity 10

Size/Duplication

Total Lines 255
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 15

Importance

Changes 0
Metric Value
dl 0
loc 255
rs 9.1666
c 0
b 0
f 0
wmc 10
lcom 1
cbo 15

10 Methods

Rating   Name   Duplication   Size   Complexity  
A setUp() 0 17 1
A tearDown() 0 10 1
A testAddUserDefinedPagePropertyAsObjectToSemanticDataForStorage() 0 19 1
A testAddUserDefinedBlobPropertyAsObjectToSemanticDataForStorage() 0 20 1
A testAddUserDefinedPropertyAsDataValueToSemanticDataForStorage() 0 23 1
B testAddSubobjectToSemanticDataForStorage() 0 33 1
B testFetchSemanticDataForPreExistingSimpleRedirect() 0 29 1
B testFetchSemanticDataForPreExistingDoubleRedirect() 0 36 1
A testPrepareToFetchCorrectSemanticDataFromInternalCache() 0 22 1
A testVerifyToFetchCorrectSemanticDataFromInternalCache() 0 18 1
1
<?php
2
3
namespace SMW\Tests\Integration;
4
5
use SMW\ApplicationFactory;
6
use SMW\DataValueFactory;
7
use SMW\DIProperty;
8
use SMW\DIWikiPage;
9
use SMW\SemanticData;
10
use SMW\Subobject;
11
use SMW\Tests\MwDBaseUnitTestCase;
12
use SMW\Tests\Utils\UtilityFactory;
13
use SMWDIBlob as DIBlob;
14
use Title;
15
16
/**
17
 * @group SMW
18
 * @group SMWExtension
19
 *
20
 * @group semantic-mediawiki-integration
21
 * @group mediawiki-database
22
 *
23
 * @group medium
24
 *
25
 * @license GNU GPL v2+
26
 * @since 2.0
27
 *
28
 * @author mwjames
29
 */
30
class SemanticDataStorageDBIntegrationTest extends MwDBaseUnitTestCase {
31
32
	private $applicationFactory;
33
	private $mwHooksHandler;
34
35
	private $semanticDataValidator;
36
	private $subjects = array();
37
38
	private $pageDeleter;
39
	private $pageCreator;
40
41
	protected function setUp() {
42
		parent::setUp();
43
44
		$utilityFactory = UtilityFactory::getInstance();
45
46
		$this->mwHooksHandler = $utilityFactory->newMwHooksHandler();
47
48
		$this->mwHooksHandler
49
			->deregisterListedHooks()
50
			->invokeHooksFromRegistry();
51
52
		$this->semanticDataValidator = $utilityFactory->newValidatorFactory()->newSemanticDataValidator();
53
		$this->pageDeleter = $utilityFactory->newPageDeleter();
54
		$this->pageCreator = $utilityFactory->newPageCreator();
55
56
		$this->applicationFactory = ApplicationFactory::getInstance();
57
	}
58
59
	protected function tearDown() {
60
61
		$this->pageDeleter
62
			->doDeletePoolOfPages( $this->subjects );
63
64
		$this->applicationFactory->clear();
65
		$this->mwHooksHandler->restoreListedHooks();
66
67
		parent::tearDown();
68
	}
69
70
	public function testAddUserDefinedPagePropertyAsObjectToSemanticDataForStorage() {
71
72
		$property = new DIProperty( 'SomePageProperty' );
73
74
		$this->subjects[] = $subject = DIWikiPage::newFromTitle( Title::newFromText( __METHOD__ ) );
75
		$semanticData = new SemanticData( $subject );
76
77
		$semanticData->addPropertyObjectValue(
78
			$property,
79
			new DIWikiPage( 'SomePropertyPageValue', NS_MAIN, '' )
80
		);
81
82
		$this->getStore()->updateData( $semanticData );
83
84
		$this->assertArrayHasKey(
85
			$property->getKey(),
86
			$this->getStore()->getSemanticData( $subject )->getProperties()
87
		);
88
	}
89
90
	public function testAddUserDefinedBlobPropertyAsObjectToSemanticDataForStorage() {
91
92
		$property = new DIProperty( 'SomeBlobProperty' );
93
		$property->setPropertyTypeId( '_txt' );
94
95
		$this->subjects[] = $subject = DIWikiPage::newFromTitle( Title::newFromText( __METHOD__ ) );
96
		$semanticData = new SemanticData( $subject );
97
98
		$semanticData->addPropertyObjectValue(
99
			$property,
100
			new DIBlob( 'SomePropertyBlobValue' )
101
		);
102
103
		$this->getStore()->updateData( $semanticData );
104
105
		$this->assertArrayHasKey(
106
			$property->getKey(),
107
			$this->getStore()->getSemanticData( $subject )->getProperties()
108
		);
109
	}
110
111
	public function testAddUserDefinedPropertyAsDataValueToSemanticDataForStorage() {
112
113
		$propertyAsString = 'SomePropertyAsString';
114
115
		$this->subjects[] = $subject = DIWikiPage::newFromTitle( Title::newFromText( __METHOD__ ) );
116
		$semanticData = new SemanticData( $subject );
117
118
		$dataValue = DataValueFactory::getInstance()->newDataValueByText(
119
			$propertyAsString,
120
			'Foo',
121
			false,
122
			$subject
123
		);
124
125
		$semanticData->addDataValue( $dataValue );
126
127
		$this->getStore()->updateData( $semanticData );
128
129
		$this->assertArrayHasKey(
130
			$propertyAsString,
131
			$this->getStore()->getSemanticData( $subject )->getProperties()
132
		);
133
	}
134
135
	public function testAddSubobjectToSemanticDataForStorage() {
136
137
		$this->subjects[] = $subject = DIWikiPage::newFromTitle( Title::newFromText( __METHOD__ ) );
138
		$semanticData = new SemanticData( $subject );
139
140
		$subobject = new Subobject( $subject->getTitle() );
0 ignored issues
show
Bug introduced by
It seems like $subject->getTitle() can be null; however, __construct() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
141
		$subobject->setEmptyContainerForId( 'SomeSubobject' );
142
143
		$subobject->getSemanticData()->addDataValue(
144
			DataValueFactory::getInstance()->newDataValueByText( 'Foo', 'Bar' )
145
		);
146
147
		$semanticData->addPropertyObjectValue(
148
			$subobject->getProperty(),
149
			$subobject->getContainer()
150
		);
151
152
		$this->getStore()->updateData( $semanticData );
153
154
		$expected = array(
155
			'propertyCount'  => 2,
156
			'properties' => array(
157
				new DIProperty( 'Foo' ),
158
				new DIProperty( '_SKEY' )
159
			),
160
			'propertyValues' => array( 'Bar', __METHOD__ )
161
		);
162
163
		$this->semanticDataValidator->assertThatPropertiesAreSet(
164
			$expected,
165
			$this->getStore()->getSemanticData( $subject )->findSubSemanticData( 'SomeSubobject' )
166
		);
167
	}
168
169
	public function testFetchSemanticDataForPreExistingSimpleRedirect() {
170
171
		$this->applicationFactory->clear();
172
173
		$this->pageCreator
174
			->createPage( Title::newFromText( 'Foo-B' ) )
175
			->doEdit( '#REDIRECT [[Foo-A]]' );
176
177
		$subject = DIWikiPage::newFromTitle( Title::newFromText( 'Foo-A' ) );
178
179
		$this->pageCreator
180
			->createPage( $subject->getTitle() )
0 ignored issues
show
Bug introduced by
It seems like $subject->getTitle() can be null; however, createPage() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
181
			->doEdit( '[[HasNoDisplayRedirectInconsistencyFor::Foo-B]]' );
182
183
		$expected = array(
184
			'propertyCount' => 3,
185
			'propertyKeys'  => array( '_SKEY', '_MDAT', 'HasNoDisplayRedirectInconsistencyFor' )
186
		);
187
188
		$this->semanticDataValidator->assertThatPropertiesAreSet(
189
			$expected,
190
			$this->getStore()->getSemanticData( $subject )
191
		);
192
193
		$this->subjects = array(
194
			$subject,
195
			Title::newFromText( 'Foo-B' )
196
		);
197
	}
198
199
	public function testFetchSemanticDataForPreExistingDoubleRedirect() {
200
201
		$this->pageCreator
202
			->createPage( Title::newFromText( 'Foo-B' ) )
203
			->doEdit( '#REDIRECT [[Foo-C]]' );
204
205
		$this->pageCreator
206
			->createPage( Title::newFromText( 'Foo-C' ) )
207
			->doEdit( '#REDIRECT [[Foo-A]]' );
208
209
		$subject = DIWikiPage::newFromTitle( Title::newFromText( 'Foo-A' ) );
210
211
		$this->pageCreator
212
			->createPage( $subject->getTitle() )
0 ignored issues
show
Bug introduced by
It seems like $subject->getTitle() can be null; however, createPage() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
213
			->doEdit( '[[HasNoDisplayRedirectInconsistencyFor::Foo-B]]' );
214
215
		$this->pageCreator
216
			->createPage( Title::newFromText( 'Foo-C' ) )
217
			->doEdit( '[[Has page::{{PAGENAME}}' );
218
219
		$expected = array(
220
			'propertyCount' => 3,
221
			'propertyKeys'  => array( '_SKEY', '_MDAT', 'HasNoDisplayRedirectInconsistencyFor' )
222
		);
223
224
		$this->semanticDataValidator->assertThatPropertiesAreSet(
225
			$expected,
226
			$this->getStore()->getSemanticData( $subject )
227
		);
228
229
		$this->subjects = array(
230
			$subject,
231
			Title::newFromText( 'Foo-B' ),
232
			Title::newFromText( 'Foo-C' )
233
		);
234
	}
235
236
	/**
237
	 * Issue 622/619
238
	 */
239
	public function testPrepareToFetchCorrectSemanticDataFromInternalCache() {
240
241
		$redirect = DIWikiPage::newFromTitle( Title::newFromText( 'Foo-A' ) );
242
243
		$this->pageCreator
244
			->createPage( $redirect->getTitle() )
0 ignored issues
show
Bug introduced by
It seems like $redirect->getTitle() can be null; however, createPage() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
245
			->doEdit( '#REDIRECT [[Foo-C]]' );
246
247
		$target = DIWikiPage::newFromTitle( Title::newFromText( 'Foo-C' ) );
248
249
		$this->pageCreator
250
			->createPage( $target->getTitle() )
0 ignored issues
show
Bug introduced by
It seems like $target->getTitle() can be null; however, createPage() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
251
			->doEdit( '{{#subobject:test|HasSomePageProperty=Foo-A}}' );
252
253
		$this->assertEmpty(
254
			$this->getStore()->getSemanticData( $redirect )->findSubSemanticData( 'test' )
255
		);
256
257
		$this->assertNotEmpty(
258
			$this->getStore()->getSemanticData( $target )->findSubSemanticData( 'test' )
259
		);
260
	}
261
262
	/**
263
	 * @depends testPrepareToFetchCorrectSemanticDataFromInternalCache
264
	 */
265
	public function testVerifyToFetchCorrectSemanticDataFromInternalCache() {
266
267
		$redirect = DIWikiPage::newFromTitle( Title::newFromText( 'Foo-A' ) );
268
		$target = DIWikiPage::newFromTitle( Title::newFromText( 'Foo-C' ) );
269
270
		$this->assertEmpty(
271
			$this->getStore()->getSemanticData( $redirect )->findSubSemanticData( 'test' )
272
		);
273
274
		$this->assertNotEmpty(
275
			$this->getStore()->getSemanticData( $target )->findSubSemanticData( 'test' )
276
		);
277
278
		$this->subjects = array(
279
			$redirect,
280
			$target
281
		);
282
	}
283
284
}
285