Index: trunk/extensions/DataTransclusion/tests/DataTransclusionTest.php |
— | — | @@ -34,35 +34,36 @@ |
35 | 35 | |
36 | 36 | function runTest() |
37 | 37 | { |
| 38 | + $this->testNormalizeRecord(); |
38 | 39 | $this->testErrorMessage(); |
39 | 40 | $this->testSanitizeValue(); |
40 | | - $this->testNormalizeRecord(); |
41 | 41 | $this->testBuildAssociativeArguments(); |
42 | 42 | $this->testGetDataSource(); |
43 | 43 | $this->testCachedFetchRecord(); |
44 | 44 | $this->testRender(); |
45 | | - $this->testHandleRecordFunction(); |
46 | | - $this->testHandleRecordTag(); |
| 45 | + $this->testHandleRecordTransclusion(); |
| 46 | + $this->testDBDataTransclusionSource(); |
| 47 | + $this->testWebDataTransclusionSource(); |
47 | 48 | } |
48 | 49 | |
49 | 50 | function testErrorMessage() { |
50 | 51 | $m = DataTransclusionHandler::errorMessage('datatransclusion-test-wikitext', false); |
51 | | - $this->assertEquals( $m, '<span class="error">some <span class="test">html</span> and \'\'markup\'\'.</span>' ); |
| 52 | + $this->assertEquals( $m, '<span class="error datatransclusion-test-wikitext">some <span class="test">html</span> and \'\'markup\'\'.</span>' ); |
52 | 53 | |
53 | 54 | $m = DataTransclusionHandler::errorMessage('datatransclusion-test-evil-html', false); |
54 | | - $this->assertEquals( $m, '<span class="error">some <object>evil</object> html.</span>' ); |
| 55 | + $this->assertEquals( $m, '<span class="error datatransclusion-test-evil-html">some <object>evil</object> html.</span>' ); |
55 | 56 | |
56 | 57 | $m = DataTransclusionHandler::errorMessage('datatransclusion-test-nowiki', false); |
57 | | - $this->assertEquals( $m, '<span class="error">some <nowiki>{{nowiki}}</nowiki> code.</span>' ); |
| 58 | + $this->assertEquals( $m, '<span class="error datatransclusion-test-nowiki">some <nowiki>{{nowiki}}</nowiki> code.</span>' ); |
58 | 59 | |
59 | 60 | $m = DataTransclusionHandler::errorMessage('datatransclusion-test-wikitext', true); |
60 | | - $this->assertEquals( $m, '<span class="error">some <span class="test">html</span> and <i>markup</i>.</span>' ); |
| 61 | + $this->assertEquals( $m, '<span class="error datatransclusion-test-wikitext">some <span class="test">html</span> and <i>markup</i>.</span>' ); |
61 | 62 | |
62 | 63 | $m = DataTransclusionHandler::errorMessage('datatransclusion-test-evil-html', true); |
63 | | - $this->assertEquals( $m, '<span class="error">some <object>evil</object> html.</span>' ); |
| 64 | + $this->assertEquals( $m, '<span class="error datatransclusion-test-evil-html">some <object>evil</object> html.</span>' ); |
64 | 65 | |
65 | 66 | $m = DataTransclusionHandler::errorMessage('datatransclusion-test-nowiki', true); |
66 | | - $this->assertEquals( $m, '<span class="error">some {{nowiki}} code.</span>' ); |
| 67 | + $this->assertEquals( $m, '<span class="error datatransclusion-test-nowiki">some {{nowiki}} code.</span>' ); |
67 | 68 | } |
68 | 69 | |
69 | 70 | function testSanitizeValue() { |
— | — | @@ -82,14 +83,14 @@ |
83 | 84 | $this->assertEquals( DataTransclusionHandler::sanitizeValue( 'foo:bar' ), 'foo:bar' ); |
84 | 85 | $this->assertEquals( DataTransclusionHandler::sanitizeValue( ';foo bar' ), ';foo bar' ); |
85 | 86 | $this->assertEquals( DataTransclusionHandler::sanitizeValue( 'foo;bar' ), 'foo;bar' ); |
| 87 | + $this->assertEquals( DataTransclusionHandler::sanitizeValue( '==foo bar==' ), '==foo bar==' ); |
| 88 | + $this->assertEquals( DataTransclusionHandler::sanitizeValue( 'foo=bar' ), 'foo=bar' ); |
| 89 | + $this->assertEquals( DataTransclusionHandler::sanitizeValue( '---- foo bar' ), '---- foo bar' ); |
| 90 | + $this->assertEquals( DataTransclusionHandler::sanitizeValue( 'foo-bar' ), 'foo-bar' ); |
86 | 91 | $this->assertEquals( DataTransclusionHandler::sanitizeValue( "foo\r\nbar" ), 'foo bar' ); |
87 | 92 | $this->assertEquals( DataTransclusionHandler::sanitizeValue( ' foo bar' ), '  foo bar' ); |
88 | 93 | } |
89 | 94 | |
90 | | - function testNormalizeRecord() { |
91 | | - //TODO... |
92 | | - } |
93 | | - |
94 | 95 | function testBuildAssociativeArguments() { |
95 | 96 | $args = array( "foo bar", "x=y", " ah = \"be\" ", "blubber bla" ); |
96 | 97 | $assoc = DataTransclusionhandler::buildAssociativeArguments( $args ); |
— | — | @@ -131,7 +132,7 @@ |
132 | 133 | |
133 | 134 | $wgDataTransclusionSources[ 'BAR' ] = $spec; |
134 | 135 | |
135 | | - $src = DataTransclusionHandler::getdataSource( 'BAR' ); |
| 136 | + $src = DataTransclusionHandler::getDataSource( 'BAR' ); |
136 | 137 | $this->assertTrue( $src instanceof FakeDataTransclusionSource ); |
137 | 138 | $this->assertEquals( $src->getName(), 'BAR' ); |
138 | 139 | |
— | — | @@ -149,10 +150,94 @@ |
150 | 151 | $this->assertTrue( $src === null || $src === false ); |
151 | 152 | } |
152 | 153 | |
153 | | - function testHandleRecordFunction() { |
| 154 | + function testHandleRecordTransclusion() { |
| 155 | + global $wgParser; |
| 156 | + global $wgDataTransclusionSources; |
| 157 | + |
| 158 | + $data[] = array( "name" => "foo", "id" => "3", "info" => 'test&X'); |
| 159 | + $spec = array( |
| 160 | + 'class' => 'FakeDataTransclusionSource', |
| 161 | + 'data' => $data, |
| 162 | + 'keyFields' => 'name,id', |
| 163 | + 'fieldNames' => 'id,name,info', |
| 164 | + 'defaultKey' => 'id' |
| 165 | + ); |
| 166 | + |
| 167 | + $wgDataTransclusionSources[ 'FOO' ] = $spec; |
| 168 | + |
| 169 | + # failure mode: no source given |
| 170 | + $s = DataTransclusionHandler::handleRecordTransclusion( "3", array( 'foo' => 'bar' ), $wgParser, false ); |
| 171 | + $this->assertTrue( preg_match('/class="error datatransclusion-missing-source"/', $s) === 1 ); |
| 172 | + |
| 173 | + # failure mode: bad source given |
| 174 | + $s = DataTransclusionHandler::handleRecordTransclusion( "3", array( 'source' => '*** nonsense ***', 'template' => 'Dummy' ), $wgParser, false ); |
| 175 | + $this->assertTrue( preg_match('/class="error datatransclusion-unknown-source"/', $s) === 1 ); |
| 176 | + |
| 177 | + # failure mode: bad source given (alternative) |
| 178 | + $s = DataTransclusionHandler::handleRecordTransclusion( "3", array( 1 => '*** nonsense ***', 'template' => 'Dummy' ), $wgParser, false ); |
| 179 | + $this->assertTrue( preg_match('/class="error datatransclusion-unknown-source"/', $s) === 1 ); |
| 180 | + |
| 181 | + # failure mode: illegal value for by= (must be a key field) |
| 182 | + $s = DataTransclusionHandler::handleRecordTransclusion( "3", array( 'source' => 'FOO', 'by' => 'info', 'template' => 'Dummy' ), $wgParser, false ); |
| 183 | + $this->assertTrue( preg_match('/class="error datatransclusion-bad-argument-by"/', $s) === 1 ); |
| 184 | + |
| 185 | + # failure mode: no key value specified |
| 186 | + $s = DataTransclusionHandler::handleRecordTransclusion( null, array( 'source' => 'FOO', 'template' => 'Dummy' ), $wgParser, false ); |
| 187 | + $this->assertTrue( preg_match('/class="error datatransclusion-missing-argument-key"/', $s) === 1 ); |
| 188 | + |
| 189 | + # failure mode: no template specified |
| 190 | + $s = DataTransclusionHandler::handleRecordTransclusion( "3", array( 'source' => 'FOO' ), $wgParser, false ); |
| 191 | + $this->assertTrue( preg_match('/class="error datatransclusion-missing-argument-template"/', $s) === 1 ); |
| 192 | + |
| 193 | + # failure mode: illegal template specified |
| 194 | + $s = DataTransclusionHandler::handleRecordTransclusion( "3", array( 'source' => 'FOO', 'template' => '#' ), $wgParser, false ); |
| 195 | + $this->assertTrue( preg_match('/class="error datatransclusion-bad-template-name"/', $s) === 1 ); |
| 196 | + |
| 197 | + # failure mode: record can't be found for that key |
| 198 | + $s = DataTransclusionHandler::handleRecordTransclusion( "xxxxxxxxxx", array( 'source' => 'FOO', 'template' => 'Dummy' ), $wgParser, false ); |
| 199 | + $this->assertTrue( preg_match('/class="error datatransclusion-record-not-found"/', $s) === 1 ); |
| 200 | + |
| 201 | + # failure mode: unknown template |
| 202 | + $s = DataTransclusionHandler::handleRecordTransclusion( "3", array( 'source' => 'FOO', 'template' => '---SomeTemplateThatHopefullyDoesNotExist---' ), $wgParser, false ); |
| 203 | + $this->assertTrue( preg_match('/class="error datatransclusion-unknown-template"/', $s) === 1 ); |
| 204 | + |
| 205 | + # success: render record |
| 206 | + $res = DataTransclusionHandler::handleRecordTransclusion( "3", array( 'source' => 'FOO', 'template' => 'Test' ), $wgParser, false, "'''{{{id}}}'''|{{{name}}}|{{{info}}}" ); |
| 207 | + $this->assertEquals( $res, '\'\'\'3\'\'\'|foo|test&X' ); |
| 208 | + |
| 209 | + # success: render record (find by name) |
| 210 | + $res = DataTransclusionHandler::handleRecordTransclusion( "foo", array( 'source' => 'FOO', 'template' => 'Test', 'by' => 'name' ), $wgParser, false, "'''{{{id}}}'''|{{{name}}}|{{{info}}}" ); |
| 211 | + $this->assertEquals( $res, '\'\'\'3\'\'\'|foo|test&X' ); |
| 212 | + |
| 213 | + # success: render record (as HTML) |
| 214 | + $res = DataTransclusionHandler::handleRecordTransclusion( "3", array( 'source' => 'FOO', 'template' => 'Test' ), $wgParser, true, "'''{{{id}}}'''|{{{name}}}|{{{info}}}" ); |
| 215 | + $this->assertEquals( $res, '<b>3</b>|foo|test&X' ); //FIXME: & should have been escaped to & here, no? why not? |
154 | 216 | } |
155 | 217 | |
156 | | - function testHandleRecordTag() { |
| 218 | + function testNormalizeRecord() { |
| 219 | + global $wgParser; |
| 220 | + |
| 221 | + $spec = array( 'name' => 'FOO', |
| 222 | + 'keyFields' => 'name,id', |
| 223 | + 'fieldNames' => 'id,name,info', |
| 224 | + 'sourceInfo' => array( 'x' => 43, 'quux' => 'xyzzy' ), |
| 225 | + ); |
| 226 | + $data[] = $rec = array( "name" => "foo", "id" => 3, "info" => '{{test}}=[[x]] 1&2 ', 'stuff' => 'bla bla bla' ); |
| 227 | + |
| 228 | + $source = new FakeDataTransclusionSource( $spec, $data ); |
| 229 | + |
| 230 | + $handler = new DataTransclusionHandler( $wgParser, $source, null ); |
| 231 | + |
| 232 | + $rec = $handler->normalizeRecord( $rec ); |
| 233 | + |
| 234 | + $this->assertEquals( $rec['source.name'], 'FOO' ); |
| 235 | + $this->assertEquals( $rec['source.quux'], 'xyzzy' ); |
| 236 | + $this->assertEquals( $rec['source.x'], 43 ); |
| 237 | + $this->assertEquals( $rec['name'], 'foo' ); |
| 238 | + $this->assertEquals( $rec['id'], '3' ); |
| 239 | + $this->assertEquals( $rec['info'], '{{test}}=[[x]] 1&2 ' ); |
| 240 | + $this->assertTrue( !isset($rec['stuff']) ); |
| 241 | + $this->assertTrue( !isset($rec['name.keyFields']) ); |
157 | 242 | } |
158 | 243 | |
159 | 244 | function testRender() { |
— | — | @@ -209,15 +294,55 @@ |
210 | 295 | $this->assertEquals( $rec['info'], 'test X' ); |
211 | 296 | } |
212 | 297 | |
213 | | - /* |
214 | | - function testWebFetchRecord() { |
215 | | - //TODO: decode, extract, etc |
| 298 | + function testDBDataTransclusionSource() { |
| 299 | + $spec = array( |
| 300 | + 'name' => 'FOO', |
| 301 | + 'keyTypes' => array( 'id' => 'int', 'name' => 'string' ), |
| 302 | + 'query' => 'SELECT * FROM foo ', |
| 303 | + 'querySuffix' => ' GROUP BY id', |
| 304 | + ); |
| 305 | + |
| 306 | + $source = new DBDataTransclusionSource( $spec ); |
| 307 | + $sql = $source->getQuery( 'name', 'foo"' ); |
| 308 | + |
| 309 | + $this->assertTrue( preg_match('/^SELECT \* FROM foo/', $sql) === 1 ); |
| 310 | + $this->assertTrue( preg_match('/GROUP BY id$/', $sql) === 1 ); |
| 311 | + $this->assertTrue( preg_match("/WHERE \\( *name *= *'foo\\\\\"' *\\)/", $sql) === 1 ); |
| 312 | + |
| 313 | + $sql = $source->getQuery( 'id', '3' ); |
| 314 | + $this->assertTrue( preg_match('/WHERE \( *id *= *3 *\)/', $sql) === 1 ); |
216 | 315 | } |
217 | 316 | |
218 | | - function testDBFetchRecord() { |
219 | | - //TODO: convert value, escape, build sql |
| 317 | + function testWebDataTransclusionSource() { |
| 318 | + $spec = array( |
| 319 | + 'name' => 'FOO', |
| 320 | + 'keyFields' => 'id,name', |
| 321 | + 'url' => 'http://acme.com/', |
| 322 | + 'dataFormat' => 'php', |
| 323 | + 'dataPath' => 'response/content/@0', |
| 324 | + 'errorPath' => 'response/error', |
| 325 | + ); |
| 326 | + |
| 327 | + $source = new WebDataTransclusionSource( $spec ); |
| 328 | + |
| 329 | + $u = $source->getRecordURL( 'name', 'foo&bar' ); |
| 330 | + $this->assertEquals( $u, 'http://acme.com/?name=foo%26bar' ); |
| 331 | + |
| 332 | + $rec = array( "name" => "foo", "id" => 3, "info" => 'test X'); |
| 333 | + $data = array( 'response' => array( |
| 334 | + 'error' => 'test error', |
| 335 | + 'content' => array( |
| 336 | + 'foo' => $rec |
| 337 | + ) |
| 338 | + ) ); |
| 339 | + |
| 340 | + $data = serialize( $data ); |
| 341 | + $rec = $source->extractRecord( $source->decodeData( $data, 'php' ) ); |
| 342 | + $err = $source->extractError( $source->decodeData( $data, 'php' ) ); |
| 343 | + |
| 344 | + $this->assertEquals( $err, 'test error' ); |
| 345 | + $this->assertEquals( $rec['id'], 3 ); |
220 | 346 | } |
221 | | - */ |
222 | 347 | } |
223 | 348 | |
224 | 349 | $wgShowExceptionDetails = true; |