1
|
|
|
<?php |
2
|
|
|
/* Copyright (C) 2016 Michael Giesler |
3
|
|
|
* |
4
|
|
|
* This file is part of Dembelo. |
5
|
|
|
* |
6
|
|
|
* Dembelo is free software: you can redistribute it and/or modify |
7
|
|
|
* it under the terms of the GNU Affero General Public License as published by |
8
|
|
|
* the Free Software Foundation, either version 3 of the License, or |
9
|
|
|
* (at your option) any later version. |
10
|
|
|
* |
11
|
|
|
* Dembelo is distributed in the hope that it will be useful, |
12
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
13
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14
|
|
|
* GNU Affero General Public License 3 for more details. |
15
|
|
|
* |
16
|
|
|
* You should have received a copy of the GNU Affero General Public License 3 |
17
|
|
|
* along with Dembelo. If not, see <http://www.gnu.org/licenses/>. |
18
|
|
|
*/ |
19
|
|
|
|
20
|
|
|
/** |
21
|
|
|
* @package AdminBundle\Test |
22
|
|
|
*/ |
23
|
|
|
|
24
|
|
|
// @codingStandardsIgnoreStart |
25
|
|
|
namespace AdminBundle\Model; |
26
|
|
|
|
27
|
|
|
use AdminBundle\Tests\Model\ImportTwineTest; |
28
|
|
|
|
29
|
|
|
/** |
30
|
|
|
* mock function |
31
|
|
|
* |
32
|
|
|
* @param string $filename |
33
|
|
|
* @return bool |
34
|
|
|
*/ |
35
|
|
|
function fopen($filename) |
36
|
|
|
{ |
37
|
|
|
return strpos($filename, 'readable') !== false; |
38
|
|
|
} |
39
|
|
|
|
40
|
|
|
/** |
41
|
|
|
* mock function |
42
|
|
|
*/ |
43
|
|
|
function fclose(): bool |
44
|
|
|
{ |
45
|
|
|
return ImportTwineTest::$fcloseReturnValue; |
46
|
|
|
} |
47
|
|
|
|
48
|
|
|
/** |
49
|
|
|
* mock function |
50
|
|
|
* |
51
|
|
|
* @return bool|mixed |
52
|
|
|
*/ |
53
|
|
|
function fread() |
54
|
|
|
{ |
55
|
|
|
if (empty(ImportTwineTest::$freadStack)) { |
56
|
|
|
return false; |
57
|
|
|
} |
58
|
|
|
|
59
|
|
|
return array_shift(ImportTwineTest::$freadStack); |
60
|
|
|
} |
61
|
|
|
|
62
|
|
|
/** |
63
|
|
|
* mock function |
64
|
|
|
* |
65
|
|
|
* @return bool |
66
|
|
|
*/ |
67
|
|
|
function feof() |
68
|
|
|
{ |
69
|
|
|
return empty(ImportTwineTest::$freadStack); |
70
|
|
|
} |
71
|
|
|
|
72
|
|
|
/** |
73
|
|
|
* @param Resource $parser |
74
|
|
|
* @return void |
75
|
|
|
*/ |
76
|
|
|
function xml_parser_free($parser) |
77
|
|
|
{ |
78
|
|
|
ImportTwineTest::$parserFreeCalled = true; |
79
|
|
|
\xml_parser_free($parser); |
80
|
|
|
} |
81
|
|
|
|
82
|
|
|
namespace AdminBundle\Tests\Model; |
83
|
|
|
|
84
|
|
|
use AdminBundle\Model\ImportTwine; |
85
|
|
|
use AdminBundle\Service\TwineImport\FileCheck; |
86
|
|
|
use AdminBundle\Service\TwineImport\FileExtractor; |
87
|
|
|
use AdminBundle\Service\TwineImport\HitchParser; |
88
|
|
|
use DembeloMain\Document\Importfile; |
89
|
|
|
use DembeloMain\Document\Textnode; |
90
|
|
|
use DembeloMain\Model\Repository\Doctrine\ODM\TextNodeRepository; |
91
|
|
|
use DembeloMain\Model\Repository\TextNodeRepositoryInterface; |
92
|
|
|
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; |
93
|
|
|
|
94
|
|
|
// @codingStandardsIgnoreEnd |
95
|
|
|
|
96
|
|
|
/** |
97
|
|
|
* Class ImportTwineTest |
98
|
|
|
* @package AdminBundle\Tests\Model |
99
|
|
|
*/ |
100
|
|
|
class ImportTwineTest extends WebTestCase |
101
|
|
|
{ |
102
|
|
|
|
103
|
|
|
public static $freadStack = []; |
104
|
|
|
public static $parserFreeCalled = false; |
105
|
|
|
public static $fcloseReturnValue = true; |
106
|
|
|
private $mocks; |
107
|
|
|
|
108
|
|
|
/** |
109
|
|
|
* @var ImportTwine |
110
|
|
|
*/ |
111
|
|
|
private $importTwine; |
112
|
|
|
|
113
|
|
|
/** |
114
|
|
|
* @var \PHPUnit_Framework_MockObject_MockObject|TextNodeRepositoryInterface |
115
|
|
|
*/ |
116
|
|
|
private $textnodeRepository; |
117
|
|
|
|
118
|
|
|
/** |
119
|
|
|
* @var \PHPUnit_Framework_MockObject_MockObject|HitchParser |
120
|
|
|
*/ |
121
|
|
|
private $hitchParserMock; |
122
|
|
|
|
123
|
|
|
/** |
124
|
|
|
* @var \PHPUnit_Framework_MockObject_MockObject|FileExtractor |
125
|
|
|
*/ |
126
|
|
|
private $fileExtractorMock; |
127
|
|
|
|
128
|
|
|
/** |
129
|
|
|
* @var \PHPUnit_Framework_MockObject_MockObject|FileCheck |
130
|
|
|
*/ |
131
|
|
|
private $fileCheckMock; |
132
|
|
|
|
133
|
|
|
/** |
134
|
|
|
* resets some variables |
135
|
|
|
*/ |
136
|
|
|
public function setUp() |
137
|
|
|
{ |
138
|
|
|
self::$freadStack = []; |
139
|
|
|
$this->mocks = []; |
140
|
|
|
self::$parserFreeCalled = false; |
141
|
|
|
self::$fcloseReturnValue = true; |
142
|
|
|
|
143
|
|
|
$this->textnodeRepository = $this->getTextnodeRepositoryMock(); |
144
|
|
|
$this->hitchParserMock = $this->createHitchParserMock(); |
145
|
|
|
$this->fileExtractorMock = $this->createFileExtractorMock(); |
146
|
|
|
$this->fileCheckMock = $this->createFileCheckMock(); |
147
|
|
|
|
148
|
|
|
$this->importTwine = new ImportTwine( |
149
|
|
|
$this->textnodeRepository, |
150
|
|
|
$this->hitchParserMock, |
151
|
|
|
$this->fileExtractorMock, |
152
|
|
|
$this->fileCheckMock |
153
|
|
|
); |
154
|
|
|
} |
155
|
|
|
|
156
|
|
|
/** |
157
|
|
|
* @expectedException \Exception |
158
|
|
|
* @expectedExceptionMessageRegExp /Couldn't open file/ |
159
|
|
|
*/ |
160
|
|
|
public function testRunWithUnreadableFile() |
161
|
|
|
{ |
162
|
|
|
$dm = $this->getDmMock(); |
163
|
|
|
$importfile = $this->getDummyImportfile(); |
164
|
|
|
|
165
|
|
|
$this->fileCheckMock->expects(self::never()) |
166
|
|
|
->method('check'); |
167
|
|
|
|
168
|
|
|
$this->fileExtractorMock->expects(self::any()) |
169
|
|
|
->method('extract') |
170
|
|
|
->willReturn('file.extracted'); |
171
|
|
|
|
172
|
|
|
$this->importTwine->run($importfile); |
173
|
|
|
$dm->expects($this->never()) |
174
|
|
|
->method('persist'); |
175
|
|
|
$dm->expects($this->never()) |
176
|
|
|
->method('flush'); |
177
|
|
|
} |
178
|
|
|
|
179
|
|
|
/** |
180
|
|
|
* @expectedException \Exception |
181
|
|
|
* @expectedExceptionMessage File 'somefilename_readable' isn't a Twine archive file |
182
|
|
|
*/ |
183
|
|
View Code Duplication |
public function testRunWithWrongFileFormat() |
|
|
|
|
184
|
|
|
{ |
185
|
|
|
$dm = $this->getDmMock(); |
186
|
|
|
$importfile = $this->getDummyImportfile(); |
187
|
|
|
|
188
|
|
|
$this->fileCheckMock->expects(self::once()) |
189
|
|
|
->method('check') |
190
|
|
|
->willThrowException(new \Exception('File \'somefilename_readable\' isn\'t a Twine archive file')); |
191
|
|
|
|
192
|
|
|
$this->fileExtractorMock->expects(self::any()) |
193
|
|
|
->method('extract') |
194
|
|
|
->willReturn('readable.extracted'); |
195
|
|
|
|
196
|
|
|
self::$freadStack = ['erste Zeile', 'zweite Zeile']; |
197
|
|
|
|
198
|
|
|
$this->importTwine->run($importfile); |
199
|
|
|
$dm->expects($this->never()) |
200
|
|
|
->method('persist'); |
201
|
|
|
$dm->expects($this->never()) |
202
|
|
|
->method('flush'); |
203
|
|
|
} |
204
|
|
|
|
205
|
|
|
/** |
206
|
|
|
* @expectedException \Exception |
207
|
|
|
* @expectedExceptionMessage File 'somefilename_readable' seems to be empty. |
208
|
|
|
*/ |
209
|
|
View Code Duplication |
public function testRunWithEmptyFirstLine() |
|
|
|
|
210
|
|
|
{ |
211
|
|
|
$dm = $this->getDmMock(); |
212
|
|
|
$importfile = $this->getDummyImportfile(); |
213
|
|
|
|
214
|
|
|
$this->fileCheckMock->expects(self::once()) |
215
|
|
|
->method('check') |
216
|
|
|
->willThrowException(new \Exception('Failed asserting that exception message \'File \'somefilename_readable\' isn\'t a Twine archive file\' contains \'File \'somefilename_readable\' seems to be empty.')); |
217
|
|
|
|
218
|
|
|
$this->fileExtractorMock->expects(self::any()) |
219
|
|
|
->method('extract') |
220
|
|
|
->willReturn('readable.extracted'); |
221
|
|
|
|
222
|
|
|
self::$freadStack = ['']; |
223
|
|
|
|
224
|
|
|
$this->importTwine->run($importfile); |
225
|
|
|
$dm->expects($this->never()) |
226
|
|
|
->method('persist'); |
227
|
|
|
$dm->expects($this->never()) |
228
|
|
|
->method('flush'); |
229
|
|
|
} |
230
|
|
|
|
231
|
|
|
/** |
232
|
|
|
* tests the run method with correct but incomplete data |
233
|
|
|
* |
234
|
|
|
* @throws \Exception |
235
|
|
|
*/ |
236
|
|
|
public function testRunWithCorrectButIncompleteData() |
237
|
|
|
{ |
238
|
|
|
$dm = $this->getDmMock(); |
239
|
|
|
$importfile = $this->getDummyImportfile(); |
240
|
|
|
|
241
|
|
|
$this->fileExtractorMock->expects(self::any()) |
242
|
|
|
->method('extract') |
243
|
|
|
->willReturn('readable.extracted'); |
244
|
|
|
|
245
|
|
|
self::$freadStack = ['zweite Zeile']; |
246
|
|
|
|
247
|
|
|
$retVal = $this->importTwine->run($importfile); |
248
|
|
|
$this->assertTrue($retVal); |
249
|
|
|
$dm->expects($this->never()) |
250
|
|
|
->method('persist'); |
251
|
|
|
$dm->expects($this->never()) |
252
|
|
|
->method('flush'); |
253
|
|
|
} |
254
|
|
|
|
255
|
|
|
/** |
256
|
|
|
* tests the run method when no textnode is written |
257
|
|
|
* |
258
|
|
|
* @throws \Exception |
259
|
|
|
*/ |
260
|
|
|
public function testRunButNoTextnodeIsWritten() |
261
|
|
|
{ |
262
|
|
|
$importfile = $this->getDummyImportfile(); |
263
|
|
|
|
264
|
|
|
$this->fileExtractorMock->expects(self::any()) |
265
|
|
|
->method('extract') |
266
|
|
|
->willReturn('readable.extracted'); |
267
|
|
|
|
268
|
|
|
self::$freadStack = [ |
269
|
|
|
'<tw-storydata name="someStoryName" startnode="1" creator="Twine" creator-version="2.0.8" ifid="8E30D51C-4980-4161-B57F-B11C752E879A" format="Harlowe" options=""><style role="stylesheet" id="twine-user-stylesheet" type="text/twine-css"></style>'."\n", |
270
|
|
|
'<script role="script" id="twine-user-script" type="text/twine-javascript"></script>'."\n", |
271
|
|
|
'<tw-passagedata pid="1" name="someNodeName" tags="Freigegeben ID:foobar" position="104,30">lorem impsum', |
272
|
|
|
'lorem impsum</tw-passagedata></tw-storydata>', |
273
|
|
|
]; |
274
|
|
|
|
275
|
|
|
$textnode = new Textnode(); |
276
|
|
|
$textnode->setId('someTextnodeId'); |
277
|
|
|
|
278
|
|
|
$this->textnodeRepository->expects($this->any()) |
279
|
|
|
->method('find') |
280
|
|
|
->will($this->returnValue($textnode)); |
281
|
|
|
|
282
|
|
|
$this->textnodeRepository->expects($this->any()) |
283
|
|
|
->method('findByTwineId') |
284
|
|
|
->willReturn($textnode); |
285
|
|
|
|
286
|
|
|
$retVal = $this->importTwine->run($importfile); |
287
|
|
|
$this->assertTrue($retVal); |
288
|
|
|
$this->textnodeRepository->expects($this->never()) |
289
|
|
|
->method('save'); |
290
|
|
|
} |
291
|
|
|
|
292
|
|
|
/** |
293
|
|
|
* tests the run method with a single node containing text |
294
|
|
|
* |
295
|
|
|
* @throws \Exception |
296
|
|
|
*/ |
297
|
|
|
public function testRunWithSingleNodeWithText() |
298
|
|
|
{ |
299
|
|
|
$importfile = $this->getDummyImportfile(); |
300
|
|
|
|
301
|
|
|
$this->fileExtractorMock->expects(self::any()) |
302
|
|
|
->method('extract') |
303
|
|
|
->willReturn('readable.extracted'); |
304
|
|
|
|
305
|
|
|
self::$freadStack = [ |
306
|
|
|
'<tw-storydata name="someStoryName" startnode="1" creator="Twine" creator-version="2.0.8" ifid="8E30D51C-4980-4161-B57F-B11C752E879A" format="Harlowe" options=""><style role="stylesheet" id="twine-user-stylesheet" type="text/twine-css"></style>'."\n", |
307
|
|
|
'<script role="script" id="twine-user-script" type="text/twine-javascript"></script>'."\n", |
308
|
|
|
'<tw-passagedata pid="1" name="someNodeName1" tags="Freigegeben ID:foobar" position="104,30">lorem ipsum', |
309
|
|
|
'lorem ipsum</tw-passagedata></tw-storydata>', |
310
|
|
|
]; |
311
|
|
|
|
312
|
|
|
$textnode = new Textnode(); |
313
|
|
|
$textnode->setId('someTextnodeId'); |
314
|
|
|
|
315
|
|
|
$this->textnodeRepository->expects($this->any()) |
316
|
|
|
->method('find') |
317
|
|
|
->willReturn($textnode); |
318
|
|
|
|
319
|
|
|
$this->textnodeRepository->expects($this->any()) |
320
|
|
|
->method('findByTwineId') |
321
|
|
|
->willReturn($textnode); |
322
|
|
|
|
323
|
|
|
$this->textnodeRepository->expects($this->once()) |
324
|
|
|
->method('save') |
325
|
|
|
->with($this->callback(function ($textnode) { |
|
|
|
|
326
|
|
|
return $textnode instanceof Textnode |
327
|
|
|
&& $textnode->getText() === "lorem ipsumlorem ipsum"; |
328
|
|
|
})); |
329
|
|
|
|
330
|
|
|
$retVal = $this->importTwine->run($importfile); |
331
|
|
|
$this->assertTrue($retVal); |
332
|
|
|
} |
333
|
|
|
|
334
|
|
|
/** |
335
|
|
|
* check if exception is thrown when no licensee is available |
336
|
|
|
* |
337
|
|
|
* @expectedException Exception |
338
|
|
|
* @expectedExceptionMessage no licensee available |
339
|
|
|
*/ |
340
|
|
|
public function testRunWithExceptionWhenNoLicenseeIsAvailable() |
341
|
|
|
{ |
342
|
|
|
$importfile = $this->getDummyImportfile(['licenseeId' => null]); |
343
|
|
|
|
344
|
|
|
$this->importTwine->run($importfile); |
345
|
|
|
} |
346
|
|
|
|
347
|
|
|
/** |
348
|
|
|
* check if exception is thrown when no licensee is available |
349
|
|
|
* |
350
|
|
|
* @expectedException Exception |
351
|
|
|
* @expectedExceptionMessage no filename available |
352
|
|
|
*/ |
353
|
|
|
public function testRunWithExceptionWhenNoFilenameIsAvailable() |
354
|
|
|
{ |
355
|
|
|
$importfile = $this->getDummyImportfile(['filename' => null]); |
356
|
|
|
|
357
|
|
|
$this->importTwine->run($importfile); |
358
|
|
|
} |
359
|
|
|
|
360
|
|
|
/** |
361
|
|
|
* @expectedException Exception |
362
|
|
|
* @expectedExceptionMessage no ID given for Textnode "someNodeName1" |
363
|
|
|
*/ |
364
|
|
View Code Duplication |
public function testRunWithTextnodeWithoutTwineID() |
|
|
|
|
365
|
|
|
{ |
366
|
|
|
$importfile = $this->getDummyImportfile(); |
367
|
|
|
|
368
|
|
|
$this->fileExtractorMock->expects(self::any()) |
369
|
|
|
->method('extract') |
370
|
|
|
->willReturn('readable.extracted'); |
371
|
|
|
|
372
|
|
|
self::$freadStack = [ |
373
|
|
|
'<tw-storydata name="someStoryName" startnode="1" creator="Twine" creator-version="2.0.8" ifid="8E30D51C-4980-4161-B57F-B11C752E879A" format="Harlowe" options=""><style role="stylesheet" id="twine-user-stylesheet" type="text/twine-css"></style>'."\n", |
374
|
|
|
'<script role="script" id="twine-user-script" type="text/twine-javascript"></script>'."\n", |
375
|
|
|
'<tw-passagedata pid="1" name="someNodeName1" tags="Freigegeben" position="104,30">lorem ipsum', |
376
|
|
|
'lorem ipsum</tw-passagedata></tw-storydata>', |
377
|
|
|
]; |
378
|
|
|
|
379
|
|
|
$textnode = new Textnode(); |
380
|
|
|
|
381
|
|
|
$this->textnodeRepository->expects($this->any()) |
382
|
|
|
->method('find') |
383
|
|
|
->will($this->returnValue($textnode)); |
384
|
|
|
|
385
|
|
|
$this->textnodeRepository->expects($this->never()) |
386
|
|
|
->method('save'); |
387
|
|
|
|
388
|
|
|
$this->importTwine->run($importfile); |
389
|
|
|
} |
390
|
|
|
|
391
|
|
|
/** |
392
|
|
|
* @expectedException Exception |
393
|
|
|
* @expectedExceptionMessage no ID given for Textnode "someNodeName1" |
394
|
|
|
*/ |
395
|
|
View Code Duplication |
public function testRunWithTextnodeWithoutAnyTag() |
|
|
|
|
396
|
|
|
{ |
397
|
|
|
$importfile = $this->getDummyImportfile(); |
398
|
|
|
|
399
|
|
|
$this->fileExtractorMock->expects(self::any()) |
400
|
|
|
->method('extract') |
401
|
|
|
->willReturn('readable.extracted'); |
402
|
|
|
|
403
|
|
|
self::$freadStack = [ |
404
|
|
|
'<tw-storydata name="someStoryName" startnode="1" creator="Twine" creator-version="2.0.8" ifid="8E30D51C-4980-4161-B57F-B11C752E879A" format="Harlowe" options=""><style role="stylesheet" id="twine-user-stylesheet" type="text/twine-css"></style>'."\n", |
405
|
|
|
'<script role="script" id="twine-user-script" type="text/twine-javascript"></script>'."\n", |
406
|
|
|
'<tw-passagedata pid="1" name="someNodeName1" tags="" position="104,30">lorem ipsum', |
407
|
|
|
'lorem ipsum</tw-passagedata></tw-storydata>', |
408
|
|
|
]; |
409
|
|
|
|
410
|
|
|
$textnode = new Textnode(); |
411
|
|
|
|
412
|
|
|
$this->textnodeRepository->expects($this->any()) |
413
|
|
|
->method('find') |
414
|
|
|
->will($this->returnValue($textnode)); |
415
|
|
|
|
416
|
|
|
$this->textnodeRepository->expects($this->never()) |
417
|
|
|
->method('save'); |
418
|
|
|
|
419
|
|
|
$this->importTwine->run($importfile); |
420
|
|
|
} |
421
|
|
|
|
422
|
|
|
/** |
423
|
|
|
* tests identifying a textnode by a twine ID |
424
|
|
|
* @throws \Exception |
425
|
|
|
*/ |
426
|
|
View Code Duplication |
public function testRunWithTextnodeWithTwineID() |
|
|
|
|
427
|
|
|
{ |
428
|
|
|
$importfile = $this->getDummyImportfile(); |
429
|
|
|
|
430
|
|
|
$this->fileExtractorMock->expects(self::any()) |
431
|
|
|
->method('extract') |
432
|
|
|
->willReturn('readable.extracted'); |
433
|
|
|
|
434
|
|
|
self::$freadStack = [ |
435
|
|
|
'<tw-storydata name="someStoryName" startnode="1" creator="Twine" creator-version="2.0.8" ifid="8E30D51C-4980-4161-B57F-B11C752E879A" format="Harlowe" options=""><style role="stylesheet" id="twine-user-stylesheet" type="text/twine-css"></style>'."\n", |
436
|
|
|
'<script role="script" id="twine-user-script" type="text/twine-javascript"></script>'."\n", |
437
|
|
|
'<tw-passagedata pid="1" name="someNodeName1" tags="Freigegeben ID:foobar" position="104,30">lorem ipsum', |
438
|
|
|
'lorem ipsum</tw-passagedata></tw-storydata>', |
439
|
|
|
]; |
440
|
|
|
|
441
|
|
|
$textnode = new Textnode(); |
442
|
|
|
$textnode->setId('someTextnodeId'); |
443
|
|
|
|
444
|
|
|
$this->textnodeRepository->expects($this->any()) |
445
|
|
|
->method('find') |
446
|
|
|
->will($this->returnValue($textnode)); |
447
|
|
|
|
448
|
|
|
$this->textnodeRepository->expects($this->once()) |
449
|
|
|
->method('findByTwineId') |
450
|
|
|
->with($importfile, 'foobar') |
|
|
|
|
451
|
|
|
->willReturn($textnode); |
452
|
|
|
|
453
|
|
|
$this->importTwine->run($importfile); |
454
|
|
|
} |
455
|
|
|
|
456
|
|
|
/** |
457
|
|
|
* tests the freeing of xml parser |
458
|
|
|
* @throws \Exception |
459
|
|
|
*/ |
460
|
|
View Code Duplication |
public function testParserFree() |
|
|
|
|
461
|
|
|
{ |
462
|
|
|
$importfile = $this->getDummyImportfile(); |
463
|
|
|
|
464
|
|
|
$this->fileExtractorMock->expects(self::any()) |
465
|
|
|
->method('extract') |
466
|
|
|
->willReturn('readable.extracted'); |
467
|
|
|
|
468
|
|
|
self::$freadStack = [ |
469
|
|
|
'<tw-storydata name="someStoryName" startnode="1" creator="Twine" creator-version="2.0.8" ifid="8E30D51C-4980-4161-B57F-B11C752E879A" format="Harlowe" options=""><style role="stylesheet" id="twine-user-stylesheet" type="text/twine-css"></style>'."\n", |
470
|
|
|
'<script role="script" id="twine-user-script" type="text/twine-javascript"></script>'."\n", |
471
|
|
|
'<tw-passagedata pid="1" name="someNodeName1" tags="Freigegeben ID:foobar" position="104,30">lorem ipsum', |
472
|
|
|
'lorem ipsum</tw-passagedata></tw-storydata>', |
473
|
|
|
]; |
474
|
|
|
|
475
|
|
|
$textnode = new Textnode(); |
476
|
|
|
$textnode->setId('someTextnodeId'); |
477
|
|
|
|
478
|
|
|
$this->textnodeRepository->expects($this->any()) |
479
|
|
|
->method('find') |
480
|
|
|
->will($this->returnValue($textnode)); |
481
|
|
|
|
482
|
|
|
$this->textnodeRepository->expects($this->once()) |
483
|
|
|
->method('findByTwineId') |
484
|
|
|
->with($importfile, 'foobar') |
|
|
|
|
485
|
|
|
->willReturn($textnode); |
486
|
|
|
|
487
|
|
|
$this->importTwine->run($importfile); |
488
|
|
|
|
489
|
|
|
$this->assertTrue(self::$parserFreeCalled); |
490
|
|
|
} |
491
|
|
|
|
492
|
|
|
/** |
493
|
|
|
* tests disabling of a textnode that is no longer found in import file |
494
|
|
|
* @throws \Exception |
495
|
|
|
*/ |
496
|
|
|
public function testRunWithTextnodeDeletedInImportfile() |
497
|
|
|
{ |
498
|
|
|
$importfile = $this->getDummyImportfile(); |
499
|
|
|
|
500
|
|
|
$this->fileExtractorMock->expects(self::any()) |
501
|
|
|
->method('extract') |
502
|
|
|
->willReturn('readable.extracted'); |
503
|
|
|
|
504
|
|
|
self::$freadStack = [ |
505
|
|
|
'<tw-storydata name="someStoryName" startnode="1" creator="Twine" creator-version="2.0.8" ifid="8E30D51C-4980-4161-B57F-B11C752E879A" format="Harlowe" options=""><style role="stylesheet" id="twine-user-stylesheet" type="text/twine-css"></style>'."\n", |
506
|
|
|
'<script role="script" id="twine-user-script" type="text/twine-javascript"></script>'."\n", |
507
|
|
|
'<tw-passagedata pid="1" name="someNodeName1" tags="Freigegeben ID:foobar" position="104,30">lorem ipsum', |
508
|
|
|
'lorem ipsum</tw-passagedata></tw-storydata>', |
509
|
|
|
]; |
510
|
|
|
|
511
|
|
|
$textnode = new Textnode(); |
512
|
|
|
$textnode->setId('someTextnodeId'); |
513
|
|
|
|
514
|
|
|
$this->textnodeRepository->expects($this->any()) |
515
|
|
|
->method('find') |
516
|
|
|
->will($this->returnValue($textnode)); |
517
|
|
|
|
518
|
|
|
$this->textnodeRepository->expects($this->once()) |
519
|
|
|
->method('findByTwineId') |
520
|
|
|
->with($importfile, 'foobar') |
|
|
|
|
521
|
|
|
->will($this->returnValue($textnode)); |
522
|
|
|
|
523
|
|
|
$this->textnodeRepository->expects($this->once()) |
524
|
|
|
->method('disableOrphanedNodes') |
525
|
|
|
->with($importfile, [$textnode->getId()]); |
526
|
|
|
|
527
|
|
|
$this->importTwine->run($importfile); |
528
|
|
|
} |
529
|
|
|
|
530
|
|
|
/** |
531
|
|
|
* @expectedException Exception |
532
|
|
|
* @expectedExceptionMessage There is a 'tw-passagedata' in the Twine archive file 'somefilename_readable' which has a non unique 'id' tag [someTwineId], in node 'someNodeName2' |
533
|
|
|
*/ |
534
|
|
|
public function testRunWithDuplicateTwineId() |
535
|
|
|
{ |
536
|
|
|
$importfile = $this->getDummyImportfile(); |
537
|
|
|
|
538
|
|
|
$this->fileExtractorMock->expects(self::any()) |
539
|
|
|
->method('extract') |
540
|
|
|
->willReturn('readable.extracted'); |
541
|
|
|
|
542
|
|
|
self::$freadStack = [ |
543
|
|
|
'<tw-storydata name="someStoryName" startnode="1" creator="Twine" creator-version="2.0.8" ifid="8E30D51C-4980-4161-B57F-B11C752E879A" format="Harlowe" options=""><style role="stylesheet" id="twine-user-stylesheet" type="text/twine-css"></style>'."\n", |
544
|
|
|
'<script role="script" id="twine-user-script" type="text/twine-javascript"></script>'."\n", |
545
|
|
|
'<tw-passagedata pid="1" name="someNodeName1" tags="ID:someTwineId" position="104,30">lorem ipsum', |
546
|
|
|
'lorem ipsum</tw-passagedata>', |
547
|
|
|
'<tw-passagedata pid="2" name="someNodeName2" tags="ID:someTwineId" position="104,30">lorem ipsum', |
548
|
|
|
'lorem ipsum</tw-passagedata>', |
549
|
|
|
'</tw-storydata>', |
550
|
|
|
]; |
551
|
|
|
|
552
|
|
|
$textnode = new Textnode(); |
553
|
|
|
|
554
|
|
|
$this->textnodeRepository->expects($this->any()) |
555
|
|
|
->method('find') |
556
|
|
|
->will($this->returnValue($textnode)); |
557
|
|
|
|
558
|
|
|
$this->textnodeRepository->expects($this->once()) |
559
|
|
|
->method('save'); |
560
|
|
|
|
561
|
|
|
$this->importTwine->run($importfile); |
562
|
|
|
} |
563
|
|
|
|
564
|
|
|
/** |
565
|
|
|
* tests a hitch to another textnode |
566
|
|
|
* @throws \Exception |
567
|
|
|
*/ |
568
|
|
View Code Duplication |
public function testRunWithLinkToAnotherTextnode() |
|
|
|
|
569
|
|
|
{ |
570
|
|
|
$importfile = $this->getDummyImportfile(); |
571
|
|
|
|
572
|
|
|
$this->fileExtractorMock->expects(self::any()) |
573
|
|
|
->method('extract') |
574
|
|
|
->willReturn('readable.extracted'); |
575
|
|
|
|
576
|
|
|
self::$freadStack = [ |
577
|
|
|
'<tw-storydata name="someStoryName" startnode="1" creator="Twine" creator-version="2.0.8" ifid="8E30D51C-4980-4161-B57F-B11C752E879A" format="Harlowe" options=""><style role="stylesheet" id="twine-user-stylesheet" type="text/twine-css"></style>'."\n", |
578
|
|
|
'<script role="script" id="twine-user-script" type="text/twine-javascript"></script>'."\n", |
579
|
|
|
'<tw-passagedata pid="1" name="someNodeName1" tags="ID:someTwineId1" position="104,30">lorem ipsum', |
580
|
|
|
'lorem ipsum</tw-passagedata>', |
581
|
|
|
'</tw-storydata>', |
582
|
|
|
]; |
583
|
|
|
|
584
|
|
|
$textnode1 = new Textnode(); |
585
|
|
|
$textnode1->setText('lorem ipsum [[Linkdata->someNodeName2]]'); |
586
|
|
|
$textnode1->setId('someId0'); |
587
|
|
|
|
588
|
|
|
$textnode2 = new Textnode(); |
589
|
|
|
$textnode2->setId('someId1'); |
590
|
|
|
|
591
|
|
|
$this->hitchParserMock->expects(self::once()) |
592
|
|
|
->method('parseSingleArrowRight') |
593
|
|
|
->with('Linkdata->someNodeName2') |
|
|
|
|
594
|
|
|
->willReturn( |
595
|
|
|
[ |
596
|
|
|
'description' => 'some description', |
597
|
|
|
'textnodeId' => 'someTextnodeId', |
598
|
|
|
'status' => Textnode::HITCH_STATUS_ACTIVE, |
599
|
|
|
] |
600
|
|
|
); |
601
|
|
|
|
602
|
|
|
$this->textnodeRepository->expects($this->any()) |
603
|
|
|
->method('find') |
604
|
|
|
->will($this->returnValue($textnode1)); |
605
|
|
|
|
606
|
|
|
$this->textnodeRepository->expects($this->any()) |
607
|
|
|
->method('save') |
608
|
|
|
->willReturnCallback(function ($textnode) { |
609
|
|
|
static $counter = 0; |
610
|
|
|
$textnode->setId('someTextnode'.$counter++); |
611
|
|
|
}); |
612
|
|
|
|
613
|
|
|
$returnValue = $this->importTwine->run($importfile); |
614
|
|
|
|
615
|
|
|
self::assertTrue($returnValue); |
616
|
|
|
self::assertEquals('<p>lorem ipsum</p>', $textnode1->getText()); |
617
|
|
|
self::assertEquals(1, $textnode1->getHitchCount()); |
618
|
|
|
} |
619
|
|
|
|
620
|
|
|
/** |
621
|
|
|
* tests a hitch to another textnode |
622
|
|
|
* @throws \Exception |
623
|
|
|
*/ |
624
|
|
View Code Duplication |
public function testRunWithLinkToAnotherTextnodeDoubleArrowRight() |
|
|
|
|
625
|
|
|
{ |
626
|
|
|
$importfile = $this->getDummyImportfile(); |
627
|
|
|
|
628
|
|
|
$this->fileExtractorMock->expects(self::any()) |
629
|
|
|
->method('extract') |
630
|
|
|
->willReturn('readable.extracted'); |
631
|
|
|
|
632
|
|
|
self::$freadStack = [ |
633
|
|
|
'<tw-storydata name="someStoryName" startnode="1" creator="Twine" creator-version="2.0.8" ifid="8E30D51C-4980-4161-B57F-B11C752E879A" format="Harlowe" options=""><style role="stylesheet" id="twine-user-stylesheet" type="text/twine-css"></style>'."\n", |
634
|
|
|
'<script role="script" id="twine-user-script" type="text/twine-javascript"></script>'."\n", |
635
|
|
|
'<tw-passagedata pid="1" name="someNodeName1" tags="ID:someTwineId1" position="104,30">lorem ipsum', |
636
|
|
|
'lorem ipsum</tw-passagedata>', |
637
|
|
|
'</tw-storydata>', |
638
|
|
|
]; |
639
|
|
|
|
640
|
|
|
$textnode1 = new Textnode(); |
641
|
|
|
$textnode1->setText('lorem ipsum [[description1-->textnodeId1]]'); |
642
|
|
|
$textnode1->setId('someId0'); |
643
|
|
|
|
644
|
|
|
$this->hitchParserMock->expects(self::once()) |
645
|
|
|
->method('parseDoubleArrowRight') |
646
|
|
|
->with('description1-->textnodeId1') |
|
|
|
|
647
|
|
|
->willReturn( |
648
|
|
|
[ |
649
|
|
|
'description' => 'description1', |
650
|
|
|
'textnodeId' => 'textnodeId1', |
651
|
|
|
'status' => Textnode::HITCH_STATUS_ACTIVE, |
652
|
|
|
] |
653
|
|
|
); |
654
|
|
|
|
655
|
|
|
$this->textnodeRepository->expects($this->any()) |
656
|
|
|
->method('find') |
657
|
|
|
->will($this->returnValue($textnode1)); |
658
|
|
|
|
659
|
|
|
$this->textnodeRepository->expects($this->any()) |
660
|
|
|
->method('save') |
661
|
|
|
->willReturnCallback(function ($textnode) { |
662
|
|
|
static $counter = 0; |
663
|
|
|
$textnode->setId('someTextnode'.$counter++); |
664
|
|
|
}); |
665
|
|
|
|
666
|
|
|
$returnValue = $this->importTwine->run($importfile); |
667
|
|
|
|
668
|
|
|
self::assertTrue($returnValue); |
669
|
|
|
self::assertEquals('<p>lorem ipsum</p>', $textnode1->getText()); |
670
|
|
|
self::assertEquals(1, $textnode1->getHitchCount()); |
671
|
|
|
} |
672
|
|
|
|
673
|
|
|
/** |
674
|
|
|
* tests a hitch to another textnode |
675
|
|
|
* @throws \Exception |
676
|
|
|
*/ |
677
|
|
View Code Duplication |
public function testRunWithLinkToAnotherTextnodeSingleArrowLeft() |
|
|
|
|
678
|
|
|
{ |
679
|
|
|
$importfile = $this->getDummyImportfile(); |
680
|
|
|
|
681
|
|
|
$this->fileExtractorMock->expects(self::any()) |
682
|
|
|
->method('extract') |
683
|
|
|
->willReturn('readable.extracted'); |
684
|
|
|
|
685
|
|
|
self::$freadStack = [ |
686
|
|
|
'<tw-storydata name="someStoryName" startnode="1" creator="Twine" creator-version="2.0.8" ifid="8E30D51C-4980-4161-B57F-B11C752E879A" format="Harlowe" options=""><style role="stylesheet" id="twine-user-stylesheet" type="text/twine-css"></style>'."\n", |
687
|
|
|
'<script role="script" id="twine-user-script" type="text/twine-javascript"></script>'."\n", |
688
|
|
|
'<tw-passagedata pid="1" name="someNodeName1" tags="ID:someTwineId1" position="104,30">lorem ipsum', |
689
|
|
|
'lorem ipsum</tw-passagedata>', |
690
|
|
|
'</tw-storydata>', |
691
|
|
|
]; |
692
|
|
|
|
693
|
|
|
$textnode1 = new Textnode(); |
694
|
|
|
$textnode1->setText('lorem ipsum [[description1<-textnodeId1]]'); |
695
|
|
|
$textnode1->setId('someId0'); |
696
|
|
|
|
697
|
|
|
$this->hitchParserMock->expects(self::once()) |
698
|
|
|
->method('parseSingleArrowLeft') |
699
|
|
|
->with('description1<-textnodeId1') |
|
|
|
|
700
|
|
|
->willReturn( |
701
|
|
|
[ |
702
|
|
|
'description' => 'description1', |
703
|
|
|
'textnodeId' => 'textnodeId1', |
704
|
|
|
'status' => Textnode::HITCH_STATUS_ACTIVE, |
705
|
|
|
] |
706
|
|
|
); |
707
|
|
|
|
708
|
|
|
$this->textnodeRepository->expects($this->any()) |
709
|
|
|
->method('find') |
710
|
|
|
->will($this->returnValue($textnode1)); |
711
|
|
|
|
712
|
|
|
$this->textnodeRepository->expects($this->any()) |
713
|
|
|
->method('save') |
714
|
|
|
->willReturnCallback(function ($textnode) { |
715
|
|
|
static $counter = 0; |
716
|
|
|
$textnode->setId('someTextnode'.$counter++); |
717
|
|
|
}); |
718
|
|
|
|
719
|
|
|
$returnValue = $this->importTwine->run($importfile); |
720
|
|
|
|
721
|
|
|
self::assertTrue($returnValue); |
722
|
|
|
self::assertEquals('<p>lorem ipsum</p>', $textnode1->getText()); |
723
|
|
|
self::assertEquals(1, $textnode1->getHitchCount()); |
724
|
|
|
} |
725
|
|
|
|
726
|
|
|
/** |
727
|
|
|
* tests a hitch to another textnode |
728
|
|
|
* @throws \Exception |
729
|
|
|
*/ |
730
|
|
View Code Duplication |
public function testRunWithLinkToAnotherTextnodeSimpleHitch() |
|
|
|
|
731
|
|
|
{ |
732
|
|
|
$importfile = $this->getDummyImportfile(); |
733
|
|
|
|
734
|
|
|
$this->fileExtractorMock->expects(self::any()) |
735
|
|
|
->method('extract') |
736
|
|
|
->willReturn('readable.extracted'); |
737
|
|
|
|
738
|
|
|
self::$freadStack = [ |
739
|
|
|
'<tw-storydata name="someStoryName" startnode="1" creator="Twine" creator-version="2.0.8" ifid="8E30D51C-4980-4161-B57F-B11C752E879A" format="Harlowe" options=""><style role="stylesheet" id="twine-user-stylesheet" type="text/twine-css"></style>'."\n", |
740
|
|
|
'<script role="script" id="twine-user-script" type="text/twine-javascript"></script>'."\n", |
741
|
|
|
'<tw-passagedata pid="1" name="someNodeName1" tags="ID:someTwineId1" position="104,30">lorem ipsum', |
742
|
|
|
'lorem ipsum</tw-passagedata>', |
743
|
|
|
'</tw-storydata>', |
744
|
|
|
]; |
745
|
|
|
|
746
|
|
|
$textnode1 = new Textnode(); |
747
|
|
|
$textnode1->setText('lorem ipsum [[description1]]'); |
748
|
|
|
$textnode1->setId('someId0'); |
749
|
|
|
|
750
|
|
|
$this->hitchParserMock->expects(self::once()) |
751
|
|
|
->method('parseSimpleHitch') |
752
|
|
|
->with('description1') |
|
|
|
|
753
|
|
|
->willReturn( |
754
|
|
|
[ |
755
|
|
|
'description' => 'description1', |
756
|
|
|
'textnodeId' => 'textnodeId1', |
757
|
|
|
'status' => Textnode::HITCH_STATUS_ACTIVE, |
758
|
|
|
] |
759
|
|
|
); |
760
|
|
|
|
761
|
|
|
$this->textnodeRepository->expects($this->any()) |
762
|
|
|
->method('find') |
763
|
|
|
->will($this->returnValue($textnode1)); |
764
|
|
|
|
765
|
|
|
$this->textnodeRepository->expects($this->any()) |
766
|
|
|
->method('save') |
767
|
|
|
->willReturnCallback(function ($textnode) { |
768
|
|
|
static $counter = 0; |
769
|
|
|
$textnode->setId('someTextnode'.$counter++); |
770
|
|
|
}); |
771
|
|
|
|
772
|
|
|
$returnValue = $this->importTwine->run($importfile); |
773
|
|
|
|
774
|
|
|
self::assertTrue($returnValue); |
775
|
|
|
self::assertEquals('<p>lorem ipsum</p>', $textnode1->getText()); |
776
|
|
|
self::assertEquals(1, $textnode1->getHitchCount()); |
777
|
|
|
} |
778
|
|
|
|
779
|
|
|
/** |
780
|
|
|
* tests a hitch to another textnode |
781
|
|
|
* @throws \Exception |
782
|
|
|
*/ |
783
|
|
|
public function testRunWithLineBreakInText() |
784
|
|
|
{ |
785
|
|
|
$importfile = $this->getDummyImportfile(); |
786
|
|
|
|
787
|
|
|
$this->fileExtractorMock->expects(self::any()) |
788
|
|
|
->method('extract') |
789
|
|
|
->willReturn('readable.extracted'); |
790
|
|
|
|
791
|
|
|
self::$freadStack = [ |
792
|
|
|
'<tw-storydata name="someStoryName" startnode="1" creator="Twine" creator-version="2.0.8" ifid="8E30D51C-4980-4161-B57F-B11C752E879A" format="Harlowe" options=""><style role="stylesheet" id="twine-user-stylesheet" type="text/twine-css"></style>'."\n", |
793
|
|
|
'<script role="script" id="twine-user-script" type="text/twine-javascript"></script>'."\n", |
794
|
|
|
'<tw-passagedata pid="1" name="someNodeName1" tags="ID:someTwineId1" position="104,30">lorem ipsum', |
795
|
|
|
'lorem ipsum</tw-passagedata>', |
796
|
|
|
'</tw-storydata>', |
797
|
|
|
]; |
798
|
|
|
|
799
|
|
|
$textnode1 = new Textnode(); |
800
|
|
|
$textnode1->setText('lorem ipsum'."\n"."foo bar"); |
801
|
|
|
$textnode1->setId('someId0'); |
802
|
|
|
|
803
|
|
|
$this->textnodeRepository->expects($this->any()) |
804
|
|
|
->method('find') |
805
|
|
|
->will($this->returnValue($textnode1)); |
806
|
|
|
|
807
|
|
|
$this->textnodeRepository->expects($this->any()) |
808
|
|
|
->method('save') |
809
|
|
|
->willReturnCallback(function ($textnode) { |
810
|
|
|
static $counter = 0; |
811
|
|
|
$textnode->setId('someTextnode'.$counter++); |
812
|
|
|
}); |
813
|
|
|
|
814
|
|
|
$returnValue = $this->importTwine->run($importfile); |
815
|
|
|
|
816
|
|
|
self::assertTrue($returnValue); |
817
|
|
|
self::assertEquals('<p>lorem ipsum</p><p>foo bar</p>', $textnode1->getText()); |
818
|
|
|
} |
819
|
|
|
|
820
|
|
|
/** |
821
|
|
|
* tests a hitch to multiple other textnodes |
822
|
|
|
* @throws \Exception |
823
|
|
|
*/ |
824
|
|
|
public function testRunWithLinkToMultipleOtherTextnodes() |
825
|
|
|
{ |
826
|
|
|
$importfile = $this->getDummyImportfile(); |
827
|
|
|
|
828
|
|
|
$this->fileExtractorMock->expects(self::any()) |
829
|
|
|
->method('extract') |
830
|
|
|
->willReturn('readable.extracted'); |
831
|
|
|
|
832
|
|
|
self::$freadStack = [ |
833
|
|
|
'<tw-storydata name="someStoryName" startnode="1" creator="Twine" creator-version="2.0.8" ifid="8E30D51C-4980-4161-B57F-B11C752E879A" format="Harlowe" options=""><style role="stylesheet" id="twine-user-stylesheet" type="text/twine-css"></style>'."\n", |
834
|
|
|
'<script role="script" id="twine-user-script" type="text/twine-javascript"></script>'."\n", |
835
|
|
|
'<tw-passagedata pid="1" name="someNodeName1" tags="ID:someTwineId1" position="104,30">lorem ipsum', |
836
|
|
|
'lorem ipsum</tw-passagedata>', |
837
|
|
|
'</tw-storydata>', |
838
|
|
|
]; |
839
|
|
|
|
840
|
|
|
$textnode1 = new Textnode(); |
841
|
|
|
$textnode1->setText('lorem ipsum [[Linkdata->someNodeName2]] [[Linkdata2->someNodeName3]]'); |
842
|
|
|
$textnode1->setId('someId0'); |
843
|
|
|
|
844
|
|
|
$textnode2 = new Textnode(); |
845
|
|
|
$textnode2->setId('someId1'); |
846
|
|
|
|
847
|
|
|
$textnode3 = new Textnode(); |
848
|
|
|
$textnode3->setId('someId2'); |
849
|
|
|
|
850
|
|
|
$this->hitchParserMock->expects(self::any()) |
851
|
|
|
->method('parseSingleArrowRight') |
852
|
|
|
->willReturnCallback(function ($content, $name) { |
|
|
|
|
853
|
|
View Code Duplication |
if ($content !== 'Linkdata->someNodeName2') { |
|
|
|
|
854
|
|
|
return [ |
855
|
|
|
'description' => 'some description', |
856
|
|
|
'textnodeId' => 'someTextnodeId1', |
857
|
|
|
'status' => Textnode::HITCH_STATUS_ACTIVE, |
858
|
|
|
]; |
859
|
|
|
} |
860
|
|
View Code Duplication |
if ($content !== 'Linkdata2->someNodeName3') { |
|
|
|
|
861
|
|
|
return [ |
862
|
|
|
'description' => 'some description', |
863
|
|
|
'textnodeId' => 'someTextnodeId2', |
864
|
|
|
'status' => Textnode::HITCH_STATUS_ACTIVE, |
865
|
|
|
]; |
866
|
|
|
} |
867
|
|
|
self:: fail(); |
868
|
|
|
}); |
869
|
|
|
|
870
|
|
|
$this->textnodeRepository->expects($this->any()) |
871
|
|
|
->method('find') |
872
|
|
|
->will($this->returnValue($textnode1)); |
873
|
|
|
|
874
|
|
|
$this->textnodeRepository->expects($this->any()) |
875
|
|
|
->method('save') |
876
|
|
|
->willReturnCallback(function ($textnode) { |
877
|
|
|
static $counter = 0; |
878
|
|
|
$textnode->setId('someTextnode'.$counter++); |
879
|
|
|
}); |
880
|
|
|
|
881
|
|
|
$returnValue = $this->importTwine->run($importfile); |
882
|
|
|
|
883
|
|
|
self::assertTrue($returnValue); |
884
|
|
|
self::assertEquals('<p>lorem ipsum</p>', $textnode1->getText()); |
885
|
|
|
self::assertEquals(2, $textnode1->getHitchCount()); |
886
|
|
|
} |
887
|
|
|
|
888
|
|
|
/** |
889
|
|
|
* tests run() with setting of metadata |
890
|
|
|
*/ |
891
|
|
|
public function testRunWithMetadataSetting() |
892
|
|
|
{ |
893
|
|
|
$importfile = $this->getDummyImportfile(); |
894
|
|
|
|
895
|
|
|
$this->fileExtractorMock->expects(self::any()) |
896
|
|
|
->method('extract') |
897
|
|
|
->willReturn('readable.extracted'); |
898
|
|
|
|
899
|
|
|
self::$freadStack = [ |
900
|
|
|
'<tw-storydata name="someStoryName" startnode="1" creator="Twine" creator-version="2.0.8" ifid="8E30D51C-4980-4161-B57F-B11C752E879A" format="Harlowe" options=""><style role="stylesheet" id="twine-user-stylesheet" type="text/twine-css"></style>'."\n", |
901
|
|
|
'<script role="script" id="twine-user-script" type="text/twine-javascript"></script>'."\n", |
902
|
|
|
'<tw-passagedata pid="1" name="someNodeName1" tags="ID:someTwineId1" position="104,30">lorem ipsum', |
903
|
|
|
'lorem ipsum [[Linkdata->someNodeName2]]</tw-passagedata>', |
904
|
|
|
'<tw-passagedata pid="2" name="someNodeName2" tags="ID:someTwineId2" position="104,30">lorem ipsum', |
905
|
|
|
'lorem ipsum [[metakey>:<metavalue]]</tw-passagedata>', |
906
|
|
|
'</tw-storydata>', |
907
|
|
|
]; |
908
|
|
|
|
909
|
|
|
$textnode1 = new Textnode(); |
910
|
|
|
$textnode1->setText('lorem ipsum [[metakey>:<metavalue]]'); |
911
|
|
|
$textnode1->setId('someId0'); |
912
|
|
|
|
913
|
|
|
$this->textnodeRepository->expects($this->any()) |
914
|
|
|
->method('find') |
915
|
|
|
->will($this->returnValue($textnode1)); |
916
|
|
|
|
917
|
|
|
$this->textnodeRepository->expects($this->any()) |
918
|
|
|
->method('findByTwineId') |
919
|
|
|
->will($this->returnValue($textnode1)); |
920
|
|
|
|
921
|
|
|
$returnValue = $this->importTwine->run($importfile); |
922
|
|
|
self::assertTrue($returnValue); |
923
|
|
|
$metadata = $textnode1->getMetadata(); |
924
|
|
|
self::assertInternalType('array', $metadata); |
925
|
|
|
self::assertArrayHasKey('metakey', $metadata); |
926
|
|
|
self::assertEquals('metavalue', $metadata['metakey']); |
927
|
|
|
} |
928
|
|
|
|
929
|
|
|
/** |
930
|
|
|
* @return void |
931
|
|
|
* @expectedException \Exception |
932
|
|
|
* @expectedExceptionMessage There is a 'tw-passagedata' in the Twine archive file 'somefilename_readable' which is missing its 'pid' attribute. |
933
|
|
|
*/ |
934
|
|
View Code Duplication |
public function testRunWithMissingPid(): void |
|
|
|
|
935
|
|
|
{ |
936
|
|
|
$importfile = $this->getDummyImportfile(); |
937
|
|
|
|
938
|
|
|
$this->fileExtractorMock->expects(self::any()) |
939
|
|
|
->method('extract') |
940
|
|
|
->willReturn('readable.extracted'); |
941
|
|
|
|
942
|
|
|
self::$freadStack = [ |
943
|
|
|
'<tw-storydata name="someStoryName" startnode="1" creator="Twine" creator-version="2.0.8" ifid="8E30D51C-4980-4161-B57F-B11C752E879A" format="Harlowe" options=""><style role="stylesheet" id="twine-user-stylesheet" type="text/twine-css"></style>'."\n", |
944
|
|
|
'<script role="script" id="twine-user-script" type="text/twine-javascript"></script>'."\n", |
945
|
|
|
'<tw-passagedata name="someNodeName1" tags="ID:someTwineId1" position="104,30">lorem ipsum', |
946
|
|
|
'lorem ipsum</tw-passagedata>', |
947
|
|
|
'</tw-storydata>', |
948
|
|
|
]; |
949
|
|
|
|
950
|
|
|
$this->textnodeRepository->expects($this->never()) |
951
|
|
|
->method('find'); |
952
|
|
|
|
953
|
|
|
$this->textnodeRepository->expects($this->never()) |
954
|
|
|
->method('findByTwineId'); |
955
|
|
|
|
956
|
|
|
$this->importTwine->run($importfile); |
957
|
|
|
} |
958
|
|
|
|
959
|
|
|
/** |
960
|
|
|
* @return void |
961
|
|
|
* @expectedException \Exception |
962
|
|
|
* @expectedExceptionMessage There is a 'tw-passagedata' in the Twine archive file 'somefilename_readable' which hasn't a numeric value in its 'pid' attribute ('nonnumeric' was found instead). |
963
|
|
|
*/ |
964
|
|
View Code Duplication |
public function testRunWithNonNumericPid(): void |
|
|
|
|
965
|
|
|
{ |
966
|
|
|
$importfile = $this->getDummyImportfile(); |
967
|
|
|
|
968
|
|
|
$this->fileExtractorMock->expects(self::any()) |
969
|
|
|
->method('extract') |
970
|
|
|
->willReturn('readable.extracted'); |
971
|
|
|
|
972
|
|
|
self::$freadStack = [ |
973
|
|
|
'<tw-storydata name="someStoryName" startnode="1" creator="Twine" creator-version="2.0.8" ifid="8E30D51C-4980-4161-B57F-B11C752E879A" format="Harlowe" options=""><style role="stylesheet" id="twine-user-stylesheet" type="text/twine-css"></style>'."\n", |
974
|
|
|
'<script role="script" id="twine-user-script" type="text/twine-javascript"></script>'."\n", |
975
|
|
|
'<tw-passagedata pid="nonnumeric" name="someNodeName1" tags="ID:someTwineId1" position="104,30">lorem ipsum', |
976
|
|
|
'lorem ipsum</tw-passagedata>', |
977
|
|
|
'</tw-storydata>', |
978
|
|
|
]; |
979
|
|
|
|
980
|
|
|
$this->textnodeRepository->expects($this->never()) |
981
|
|
|
->method('find'); |
982
|
|
|
|
983
|
|
|
$this->textnodeRepository->expects($this->never()) |
984
|
|
|
->method('findByTwineId'); |
985
|
|
|
|
986
|
|
|
$this->importTwine->run($importfile); |
987
|
|
|
} |
988
|
|
|
|
989
|
|
|
/** |
990
|
|
|
* @return void |
991
|
|
|
* @expectedException \Exception |
992
|
|
|
* @expectedExceptionMessage Nested 'tw-passagedata' found in Twine archive file 'somefilename_readable |
993
|
|
|
*/ |
994
|
|
View Code Duplication |
public function testRunWithNestedPassageData(): void |
|
|
|
|
995
|
|
|
{ |
996
|
|
|
$importfile = $this->getDummyImportfile(); |
997
|
|
|
|
998
|
|
|
$this->fileExtractorMock->expects(self::any()) |
999
|
|
|
->method('extract') |
1000
|
|
|
->willReturn('readable.extracted'); |
1001
|
|
|
|
1002
|
|
|
self::$freadStack = [ |
1003
|
|
|
'<tw-storydata name="someStoryName" startnode="1" creator="Twine" creator-version="2.0.8" ifid="8E30D51C-4980-4161-B57F-B11C752E879A" format="Harlowe" options=""><style role="stylesheet" id="twine-user-stylesheet" type="text/twine-css"></style>'."\n", |
1004
|
|
|
'<script role="script" id="twine-user-script" type="text/twine-javascript"></script>'."\n", |
1005
|
|
|
'<tw-passagedata pid="1" name="someNodeName1" tags="ID:someTwineId1" position="104,30">', |
1006
|
|
|
'<tw-passagedata pid="2" name="someNodeName2" tags="ID:someTwineId2" position="104,40">Lorem Ipsum', |
1007
|
|
|
'lorem ipsum</tw-passagedata>', |
1008
|
|
|
'</tw-passagedata>', |
1009
|
|
|
'</tw-storydata>', |
1010
|
|
|
]; |
1011
|
|
|
|
1012
|
|
|
$this->textnodeRepository->expects($this->never()) |
1013
|
|
|
->method('find'); |
1014
|
|
|
|
1015
|
|
|
$this->textnodeRepository->expects($this->once()) |
1016
|
|
|
->method('findByTwineId'); |
1017
|
|
|
|
1018
|
|
|
$this->importTwine->run($importfile); |
1019
|
|
|
} |
1020
|
|
|
|
1021
|
|
|
/** |
1022
|
|
|
* @expectedException \Exception |
1023
|
|
|
* @expectedExceptionMessageRegExp /invalid element.*>:</ |
1024
|
|
|
*/ |
1025
|
|
View Code Duplication |
public function testRunWithMetadataSettingForInvalidFormat() |
|
|
|
|
1026
|
|
|
{ |
1027
|
|
|
$importfile = $this->getDummyImportfile(); |
1028
|
|
|
|
1029
|
|
|
$this->fileExtractorMock->expects(self::any()) |
1030
|
|
|
->method('extract') |
1031
|
|
|
->willReturn('readable.extracted'); |
1032
|
|
|
|
1033
|
|
|
self::$freadStack = [ |
1034
|
|
|
'<tw-storydata name="someStoryName" startnode="1" creator="Twine" creator-version="2.0.8" ifid="8E30D51C-4980-4161-B57F-B11C752E879A" format="Harlowe" options=""><style role="stylesheet" id="twine-user-stylesheet" type="text/twine-css"></style>'."\n", |
1035
|
|
|
'<script role="script" id="twine-user-script" type="text/twine-javascript"></script>'."\n", |
1036
|
|
|
'<tw-passagedata pid="1" name="someNodeName1" tags="ID:someTwineId1" position="104,30">lorem ipsum', |
1037
|
|
|
'lorem ipsum [[Linkdata->someNodeName2]]</tw-passagedata>', |
1038
|
|
|
'<tw-passagedata pid="2" name="someNodeName2" tags="ID:someTwineId2" position="104,30">lorem ipsum', |
1039
|
|
|
'lorem ipsum [[>:<metavalue]]</tw-passagedata>', |
1040
|
|
|
'</tw-storydata>', |
1041
|
|
|
]; |
1042
|
|
|
|
1043
|
|
|
$textnode1 = new Textnode(); |
1044
|
|
|
$textnode1->setText('lorem ipsum [[>:<metavalue]]'); |
1045
|
|
|
$textnode1->setId('someId0'); |
1046
|
|
|
|
1047
|
|
|
$this->textnodeRepository->expects($this->any()) |
1048
|
|
|
->method('find') |
1049
|
|
|
->will($this->returnValue($textnode1)); |
1050
|
|
|
|
1051
|
|
|
$this->textnodeRepository->expects($this->any()) |
1052
|
|
|
->method('findByTwineId') |
1053
|
|
|
->will($this->returnValue($textnode1)); |
1054
|
|
|
|
1055
|
|
|
$this->importTwine->run($importfile); |
1056
|
|
|
} |
1057
|
|
|
|
1058
|
|
|
/** |
1059
|
|
|
* @expectedException \Exception |
1060
|
|
|
* @expectedExceptionMessageRegExp /contains the metadata field/ |
1061
|
|
|
*/ |
1062
|
|
View Code Duplication |
public function testRunWithMetadataSettingForAnAlreadyExistingMetadataKey() |
|
|
|
|
1063
|
|
|
{ |
1064
|
|
|
$importfile = $this->getDummyImportfile(); |
1065
|
|
|
|
1066
|
|
|
$this->fileExtractorMock->expects(self::any()) |
1067
|
|
|
->method('extract') |
1068
|
|
|
->willReturn('readable.extracted'); |
1069
|
|
|
|
1070
|
|
|
self::$freadStack = [ |
1071
|
|
|
'<tw-storydata name="someStoryName" startnode="1" creator="Twine" creator-version="2.0.8" ifid="8E30D51C-4980-4161-B57F-B11C752E879A" format="Harlowe" options=""><style role="stylesheet" id="twine-user-stylesheet" type="text/twine-css"></style>'."\n", |
1072
|
|
|
'<script role="script" id="twine-user-script" type="text/twine-javascript"></script>'."\n", |
1073
|
|
|
'<tw-passagedata pid="1" name="someNodeName1" tags="ID:someTwineId1" position="104,30">lorem ipsum', |
1074
|
|
|
'lorem ipsum [[Linkdata->someNodeName2]]</tw-passagedata>', |
1075
|
|
|
'<tw-passagedata pid="2" name="someNodeName2" tags="ID:someTwineId2" position="104,30">lorem ipsum', |
1076
|
|
|
'lorem ipsum [[Autor>:<metavalue]]</tw-passagedata>', |
1077
|
|
|
'</tw-storydata>', |
1078
|
|
|
]; |
1079
|
|
|
|
1080
|
|
|
$textnode1 = new Textnode(); |
1081
|
|
|
$textnode1->setId('someId0'); |
1082
|
|
|
$textnode1->setMetadata(['metakey' => 'someValue']); |
1083
|
|
|
|
1084
|
|
|
$this->textnodeRepository->expects($this->any()) |
1085
|
|
|
->method('find') |
1086
|
|
|
->will($this->returnValue($textnode1)); |
1087
|
|
|
|
1088
|
|
|
$this->textnodeRepository->expects($this->any()) |
1089
|
|
|
->method('findByTwineId') |
1090
|
|
|
->will($this->returnValue($textnode1)); |
1091
|
|
|
|
1092
|
|
|
$this->importTwine->run($importfile); |
1093
|
|
|
} |
1094
|
|
|
|
1095
|
|
|
/** |
1096
|
|
|
* @return void |
1097
|
|
|
* @expectedException \Exception |
1098
|
|
|
* @expectedExceptionMessageRegExp /Error .* occurred while parsing the Twine archive file 'somefilename_readable'/ |
1099
|
|
|
*/ |
1100
|
|
View Code Duplication |
public function testRunWithParserException(): void |
|
|
|
|
1101
|
|
|
{ |
1102
|
|
|
self::$freadStack = [ |
1103
|
|
|
'<tw-storydata name="someStoryName" startnode="1" creator="Twine" creator-version="2.0.8" ifid="8E30D51C-4980-4161-B57F-B11C752E879A" format="Harlowe" options=""><style role="stylesheet" id="twine-user-stylesheet" type="text/twine-css"></style>'."\n", |
1104
|
|
|
'<tw-passagedata pid"1" name="someNodeName1" tags="ID:someTwineId1" position="104,30">lorem ipsum', |
1105
|
|
|
'lorem ipsum</tw-passagedata>', |
1106
|
|
|
'</tw-storydata>', |
1107
|
|
|
]; |
1108
|
|
|
|
1109
|
|
|
$textnode1 = new Textnode(); |
1110
|
|
|
$textnode1->setId('someId0'); |
1111
|
|
|
|
1112
|
|
|
$this->textnodeRepository->expects($this->any()) |
1113
|
|
|
->method('findByTwineId') |
1114
|
|
|
->willReturn($textnode1); |
1115
|
|
|
|
1116
|
|
|
$this->textnodeRepository->expects($this->any()) |
1117
|
|
|
->method('find') |
1118
|
|
|
->willReturn($textnode1); |
1119
|
|
|
|
1120
|
|
|
$this->fileExtractorMock->expects(self::any()) |
1121
|
|
|
->method('extract') |
1122
|
|
|
->willReturn('readable.extracted'); |
1123
|
|
|
|
1124
|
|
|
$importfile = $this->getDummyImportfile(); |
1125
|
|
|
|
1126
|
|
|
$this->importTwine->run($importfile); |
1127
|
|
|
} |
1128
|
|
|
|
1129
|
|
|
/** |
1130
|
|
|
* @return void |
1131
|
|
|
* @expectedException \Exception |
1132
|
|
|
* @expectedExceptionMessage There is a 'tw-storydata' in the Twine archive file 'somefilename_readable' which is missing its 'name' attribute |
1133
|
|
|
*/ |
1134
|
|
View Code Duplication |
public function testRunWithInvalidStoryDataElement(): void |
|
|
|
|
1135
|
|
|
{ |
1136
|
|
|
self::$freadStack = [ |
1137
|
|
|
'<tw-storydata startnode="1" creator="Twine" creator-version="2.0.8" ifid="8E30D51C-4980-4161-B57F-B11C752E879A" format="Harlowe" options=""><style role="stylesheet" id="twine-user-stylesheet" type="text/twine-css"></style>'."\n", |
1138
|
|
|
'<tw-passagedata pid="1" name="someNodeName1" tags="ID:someTwineId1" position="104,30">lorem ipsum', |
1139
|
|
|
'lorem ipsum</tw-passagedata>', |
1140
|
|
|
'</tw-storydata>', |
1141
|
|
|
]; |
1142
|
|
|
|
1143
|
|
|
$textnode1 = new Textnode(); |
1144
|
|
|
$textnode1->setId('someId0'); |
1145
|
|
|
|
1146
|
|
|
$this->textnodeRepository->expects($this->any()) |
1147
|
|
|
->method('findByTwineId') |
1148
|
|
|
->willReturn($textnode1); |
1149
|
|
|
|
1150
|
|
|
$this->textnodeRepository->expects($this->any()) |
1151
|
|
|
->method('find') |
1152
|
|
|
->willReturn($textnode1); |
1153
|
|
|
|
1154
|
|
|
$this->fileExtractorMock->expects(self::any()) |
1155
|
|
|
->method('extract') |
1156
|
|
|
->willReturn('readable.extracted'); |
1157
|
|
|
|
1158
|
|
|
$importfile = $this->getDummyImportfile(); |
1159
|
|
|
|
1160
|
|
|
$this->importTwine->run($importfile); |
1161
|
|
|
} |
1162
|
|
|
|
1163
|
|
|
private function getDummyImportfile(array $data = []): Importfile |
1164
|
|
|
{ |
1165
|
|
|
$default = [ |
1166
|
|
|
'filename' => 'somefilename_readable', |
1167
|
|
|
'licenseeId' => 'somelicenseeId', |
1168
|
|
|
'author' => 'someAuthor', |
1169
|
|
|
'publisher' => 'somePublisher', |
1170
|
|
|
'id' => 'someImportFileId', |
1171
|
|
|
]; |
1172
|
|
|
|
1173
|
|
|
$importfileData = array_merge($default, $data); |
1174
|
|
|
|
1175
|
|
|
$importfile = new Importfile(); |
1176
|
|
|
if (null !== $importfileData['filename']) { |
1177
|
|
|
$importfile->setFilename($importfileData['filename']); |
1178
|
|
|
} |
1179
|
|
|
if (null !== $importfileData['licenseeId']) { |
1180
|
|
|
$importfile->setLicenseeId($importfileData['licenseeId']); |
1181
|
|
|
} |
1182
|
|
|
if (null !== $importfileData['author']) { |
1183
|
|
|
$importfile->setAuthor($importfileData['author']); |
1184
|
|
|
} |
1185
|
|
|
if (null !== $importfileData['publisher']) { |
1186
|
|
|
$importfile->setPublisher($importfileData['publisher']); |
1187
|
|
|
} |
1188
|
|
|
if (null !== $importfileData['id']) { |
1189
|
|
|
$importfile->setId($importfileData['id']); |
1190
|
|
|
} |
1191
|
|
|
|
1192
|
|
|
return $importfile; |
1193
|
|
|
} |
1194
|
|
|
|
1195
|
|
|
/** |
1196
|
|
|
* @return \PHPUnit_Framework_MockObject_MockObject|TextNodeRepository |
1197
|
|
|
*/ |
1198
|
|
|
private function getTextnodeRepositoryMock() |
1199
|
|
|
{ |
1200
|
|
|
return $this->getMockBuilder(TextNodeRepository::class)->disableOriginalConstructor()->setMethods(['createQueryBuilder', 'field', 'equals', 'getQuery', 'save', 'find', 'findByTwineId', 'disableOrphanedNodes', 'setHyphenatedText'])->getMock(); |
1201
|
|
|
} |
1202
|
|
|
|
1203
|
|
|
private function getDmMock() |
1204
|
|
|
{ |
1205
|
|
|
return $this->getMockBuilder('dmMock')->setMethods(['flush', 'persist', 'find'])->getMock(); |
1206
|
|
|
} |
1207
|
|
|
|
1208
|
|
|
/** |
1209
|
|
|
* @return \PHPUnit_Framework_MockObject_MockObject|HitchParser |
1210
|
|
|
*/ |
1211
|
|
|
private function createHitchParserMock(): HitchParser |
1212
|
|
|
{ |
1213
|
|
|
return $this->createMock(HitchParser::class); |
|
|
|
|
1214
|
|
|
} |
1215
|
|
|
|
1216
|
|
|
/** |
1217
|
|
|
* @return \PHPUnit_Framework_MockObject_MockObject|FileExtractor |
1218
|
|
|
*/ |
1219
|
|
|
private function createFileExtractorMock(): FileExtractor |
1220
|
|
|
{ |
1221
|
|
|
return $this->createMock(FileExtractor::class); |
|
|
|
|
1222
|
|
|
} |
1223
|
|
|
|
1224
|
|
|
/** |
1225
|
|
|
* @return \PHPUnit_Framework_MockObject_MockObject|FileCheck |
1226
|
|
|
*/ |
1227
|
|
|
private function createFileCheckMock(): FileCheck |
1228
|
|
|
{ |
1229
|
|
|
return $this->createMock(FileCheck::class); |
|
|
|
|
1230
|
|
|
} |
1231
|
|
|
} |
1232
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.