This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | namespace Maketok\DataMigration\IntegrationTest; |
||
4 | |||
5 | use Faker\Generator; |
||
6 | use Faker\Provider\Address; |
||
7 | use Faker\Provider\Base; |
||
8 | use Faker\Provider\Internet; |
||
9 | use Faker\Provider\Lorem; |
||
10 | use Faker\Provider\Person; |
||
11 | use Maketok\DataMigration\Action\ConfigInterface; |
||
12 | use Maketok\DataMigration\Action\Type\AssembleInput; |
||
13 | use Maketok\DataMigration\Action\Type\CreateTmpFiles; |
||
14 | use Maketok\DataMigration\Action\Type\Delete; |
||
15 | use Maketok\DataMigration\Action\Type\Dump; |
||
16 | use Maketok\DataMigration\Action\Type\Generate; |
||
17 | use Maketok\DataMigration\Action\Type\Load; |
||
18 | use Maketok\DataMigration\Action\Type\Move; |
||
19 | use Maketok\DataMigration\Action\Type\ReverseMove; |
||
20 | use Maketok\DataMigration\ArrayMap; |
||
21 | use Maketok\DataMigration\Expression\HelperExpressionsProvider; |
||
22 | use Maketok\DataMigration\Expression\LanguageAdapter; |
||
23 | use Maketok\DataMigration\Hashmap\ArrayHashmap; |
||
24 | use Maketok\DataMigration\Input\Csv; |
||
25 | use Maketok\DataMigration\Input\Shaper\Processor\Duplicates; |
||
26 | use Maketok\DataMigration\Input\Shaper\Processor\Nulls; |
||
27 | use Maketok\DataMigration\QueueWorkflow; |
||
28 | use Maketok\DataMigration\Storage\Db\DBALMysqlResource; |
||
29 | use Maketok\DataMigration\Storage\Db\DBALMysqlResourceHelper; |
||
30 | use Maketok\DataMigration\Unit\SimpleBag; |
||
31 | use Maketok\DataMigration\Unit\Type\Unit; |
||
32 | use Maketok\DataMigration\Workflow\Result; |
||
33 | use Symfony\Component\ExpressionLanguage\ExpressionLanguage; |
||
34 | |||
35 | class QueueWorkflowTest extends \PHPUnit_Extensions_Database_TestCase |
||
0 ignored issues
–
show
Complexity
introduced
by
![]() |
|||
36 | { |
||
37 | /** |
||
38 | * @var ConfigInterface |
||
39 | */ |
||
40 | private $config; |
||
41 | /** |
||
42 | * @var DBALMysqlResource |
||
43 | */ |
||
44 | private $resource; |
||
45 | /** |
||
46 | * @var \PDO |
||
47 | */ |
||
48 | private $pdo; |
||
49 | |||
50 | /** |
||
51 | * {@inheritdoc} |
||
52 | */ |
||
53 | protected function setUp() |
||
54 | { |
||
55 | $config = include __DIR__ . '/Storage/Db/assets/config.php'; |
||
56 | if (isset($config) && $config instanceof ConfigInterface) { |
||
57 | $this->config = $config; |
||
58 | $this->config['tmp_folder'] = __DIR__ . '/assets'; |
||
59 | $this->config['tmp_file_mask'] = 'tmp%2$s/%1$s.csv'; |
||
60 | $this->config['tmp_table_mask'] = 'tmp_%1$s_%2$s'; |
||
61 | $this->config['local_infile'] = true; |
||
62 | $this->resource = new DBALMysqlResource($this->config); |
||
63 | $ref1 = new \ReflectionProperty(get_class($this->resource->getConnection()), '_conn'); |
||
64 | $ref1->setAccessible(true); |
||
65 | $this->pdo = $ref1->getValue($this->resource->getConnection()); |
||
66 | } else { |
||
67 | throw new \Exception("Can't find config file."); |
||
68 | } |
||
69 | |||
70 | parent::setUp(); |
||
71 | |||
72 | // assert that 2 pdo's are same |
||
73 | $pdo1 = $this->getConnection()->getConnection(); |
||
74 | $pdo2 = $ref1->getValue($this->resource->getConnection()); |
||
75 | |||
76 | $this->assertSame($pdo1, $pdo2); |
||
77 | } |
||
78 | |||
79 | protected function tearDown() |
||
80 | { |
||
81 | parent::tearDown(); |
||
82 | $this->resource->close(); |
||
83 | } |
||
84 | |||
85 | /** |
||
86 | * Set Up Schema |
||
87 | */ |
||
88 | public static function setUpBeforeClass() |
||
89 | { |
||
90 | require_once __DIR__ . '/bootstrap.php'; |
||
91 | } |
||
92 | |||
93 | /** |
||
94 | * {@inheritdoc} |
||
95 | */ |
||
96 | protected function getConnection() |
||
97 | { |
||
98 | if (isset($this->pdo)) { |
||
99 | return $this->createDefaultDBConnection($this->pdo); |
||
100 | } |
||
101 | throw new \Exception("Can't find pdo in config."); |
||
102 | } |
||
103 | |||
104 | /** |
||
105 | * {@inheritdoc} |
||
106 | */ |
||
107 | protected function getTearDownOperation() |
||
108 | { |
||
109 | if ($this->config['db_debug']) { |
||
110 | return \PHPUnit_Extensions_Database_Operation_Factory::NONE(); |
||
111 | } |
||
112 | return \PHPUnit_Extensions_Database_Operation_Factory::TRUNCATE(); |
||
113 | } |
||
114 | |||
115 | /** |
||
116 | * {@inheritdoc} |
||
117 | */ |
||
118 | protected function getDataSet() |
||
119 | { |
||
120 | return $this->createXMLDataSet(__DIR__ . '/assets/initialStructure.xml'); |
||
121 | } |
||
122 | |||
123 | /** |
||
124 | * @return LanguageAdapter |
||
125 | */ |
||
126 | public function getLanguageAdapter() |
||
127 | { |
||
128 | $language = new ExpressionLanguage(); |
||
129 | $language->registerProvider(new HelperExpressionsProvider()); |
||
130 | return new LanguageAdapter($language); |
||
131 | } |
||
132 | |||
133 | /** |
||
134 | * @return Unit |
||
135 | * @throws \Doctrine\DBAL\DBALException |
||
136 | */ |
||
137 | public function prepareCustomerImportUnit() |
||
138 | { |
||
139 | $customerUnit = new Unit('customers'); |
||
140 | $customerUnit->setTable('customers'); |
||
141 | $hashMap = new ArrayHashmap('email-id'); |
||
142 | $hashMap->load($this->resource->getConnection() |
||
143 | ->executeQuery("SELECT email,id FROM customers") |
||
144 | ->fetchAll(\PDO::FETCH_KEY_PAIR)); |
||
145 | $customerUnit->addHashmap($hashMap); |
||
146 | $contribution1 = <<<CONTRIBUTION |
||
147 | map.offsetSet( |
||
148 | 'customer_id', |
||
149 | (isset(hashmaps['email-id'][trim(map.email)]) ? |
||
150 | hashmaps['email-id'][trim(map.email)] : |
||
151 | map.frozenIncr('new_customer_id', 3)) |
||
152 | ) |
||
153 | CONTRIBUTION; |
||
154 | $customerUnit->addContribution($contribution1); |
||
155 | $contribution2 = <<<CONTRIBUTION |
||
156 | map.offsetSet( |
||
157 | 'complexName', |
||
158 | explode(' ', map.name) |
||
159 | ) |
||
160 | CONTRIBUTION; |
||
161 | $customerUnit->addContribution($contribution2); |
||
162 | $contribution3 = <<<CONTRIBUTION |
||
163 | map.offsetSet( |
||
164 | 'firstname', |
||
165 | (count(map.complexName) >= 2 && isset(map.complexName[0]) ? map.complexName[0] : map.name) |
||
166 | ) |
||
167 | CONTRIBUTION; |
||
168 | $customerUnit->addContribution($contribution3); |
||
169 | $contribution4 = <<<CONTRIBUTION |
||
170 | map.offsetSet( |
||
171 | 'lastname', |
||
172 | (count(map.complexName) >= 2 && isset(map.complexName[1]) ? map.complexName[1] : '') |
||
173 | ) |
||
174 | CONTRIBUTION; |
||
175 | $customerUnit->addContribution($contribution4); |
||
176 | $customerUnit->setMapping([ |
||
177 | 'id' => 'map.customer_id', |
||
178 | 'firstname' => 'map.firstname', |
||
179 | 'lastname' => 'map.lastname', |
||
180 | 'age' => 'map.age', |
||
181 | 'email' => 'trim(map.email)', |
||
182 | ]); |
||
183 | $customerUnit->setIsEntityCondition("trim(map.email) != trim(oldmap.email)"); |
||
184 | return $customerUnit; |
||
185 | } |
||
186 | |||
187 | /** |
||
188 | * @return Unit |
||
189 | */ |
||
190 | public function prepareAddressImportUnit() |
||
191 | { |
||
192 | $addressUnit = new Unit("addresses"); |
||
193 | $addressUnit->setTable('addresses'); |
||
194 | $addressUnit->setMapping([ |
||
195 | 'id' => 'map.incr("address_id", 4)', |
||
196 | 'street' => 'map.street', |
||
197 | 'city' => 'map.city', |
||
198 | 'parent_id' => 'map.customer_id', |
||
199 | ]); |
||
200 | return $addressUnit; |
||
201 | } |
||
202 | |||
203 | /** |
||
204 | * @test |
||
205 | * @throws \Doctrine\DBAL\DBALException |
||
206 | */ |
||
207 | public function testSimpleImport() |
||
208 | { |
||
209 | // SET THESE TO TRUE TO DEBUG |
||
210 | $this->config['db_debug'] = false; |
||
211 | $this->config['file_debug'] = false; |
||
212 | //===================================================================== |
||
213 | $customerUnit = $this->prepareCustomerImportUnit(); |
||
214 | $addressUnit = $this->prepareAddressImportUnit(); |
||
215 | $addressUnit->setParent($customerUnit); |
||
216 | //===================================================================== |
||
217 | $bag = new SimpleBag(); |
||
218 | // order matters ;) |
||
219 | $bag->add($customerUnit); |
||
220 | $bag->add($addressUnit); |
||
221 | //===================================================================== |
||
222 | $input = new Csv(__DIR__ . '/assets/customers_1.csv', 'r', new Duplicates( |
||
223 | $bag, |
||
224 | new ArrayMap(), |
||
225 | $this->getLanguageAdapter()) |
||
226 | ); |
||
227 | $createTmpFiles = new CreateTmpFiles($bag, $this->config, $this->getLanguageAdapter(), |
||
228 | $input, new ArrayMap(), new DBALMysqlResourceHelper($this->resource)); |
||
229 | $load = new Load($bag, $this->config, $this->resource); |
||
230 | $move = new Move($bag, $this->config, $this->resource); |
||
231 | //===================================================================== |
||
232 | $result = new Result(); |
||
233 | $workflow = new QueueWorkflow($this->config, $result); |
||
234 | $workflow->add($createTmpFiles); |
||
235 | $workflow->add($load); |
||
236 | $workflow->add($move); |
||
237 | $workflow->execute(); |
||
238 | //===================================================================== |
||
239 | // time to assert things |
||
240 | |||
241 | // assert schema |
||
242 | $expected = $this->createXMLDataSet(__DIR__ . '/assets/afterSimpleImportStructure.xml'); |
||
243 | $actual = $this->getConnection()->createDataSet(['customers', 'addresses']); |
||
244 | $this->assertDataSetsEqual($expected, $actual); |
||
245 | } |
||
246 | |||
247 | /** |
||
248 | * @test |
||
249 | * @throws \Doctrine\DBAL\DBALException |
||
250 | */ |
||
251 | public function testSimpleImport2Nulls() |
||
252 | { |
||
253 | // SET THESE TO TRUE TO DEBUG |
||
254 | $this->config['db_debug'] = false; |
||
255 | $this->config['file_debug'] = false; |
||
256 | //===================================================================== |
||
257 | $customerUnit = $this->prepareCustomerImportUnit(); |
||
258 | $addressUnit = $this->prepareAddressImportUnit(); |
||
259 | $addressUnit->setParent($customerUnit); |
||
260 | //===================================================================== |
||
261 | $bag = new SimpleBag(); |
||
262 | // order matters ;) |
||
263 | $bag->add($customerUnit); |
||
264 | $bag->add($addressUnit); |
||
265 | //===================================================================== |
||
266 | $input = new Csv(__DIR__ . '/assets/customers_2_nulls.csv', 'r', new Nulls( |
||
267 | $bag, |
||
268 | new ArrayMap(), |
||
269 | $this->getLanguageAdapter()) |
||
270 | ); |
||
271 | $createTmpFiles = new CreateTmpFiles($bag, $this->config, $this->getLanguageAdapter(), |
||
272 | $input, new ArrayMap(), new DBALMysqlResourceHelper($this->resource)); |
||
273 | $load = new Load($bag, $this->config, $this->resource); |
||
274 | $move = new Move($bag, $this->config, $this->resource); |
||
275 | //===================================================================== |
||
276 | $result = new Result(); |
||
277 | $workflow = new QueueWorkflow($this->config, $result); |
||
278 | $workflow->add($createTmpFiles); |
||
279 | $workflow->add($load); |
||
280 | $workflow->add($move); |
||
281 | $workflow->execute(); |
||
282 | //===================================================================== |
||
283 | // time to assert things |
||
284 | |||
285 | // assert schema |
||
286 | $expected = $this->createXMLDataSet(__DIR__ . '/assets/afterSimpleImportStructure.xml'); |
||
287 | $actual = $this->getConnection()->createDataSet(['customers', 'addresses']); |
||
288 | $this->assertDataSetsEqual($expected, $actual); |
||
289 | } |
||
290 | |||
291 | /** |
||
292 | * @test |
||
293 | */ |
||
294 | public function testImportWithExisting() |
||
295 | { |
||
296 | // SET THESE TO TRUE TO DEBUG |
||
297 | $this->config['db_debug'] = false; |
||
298 | $this->config['file_debug'] = false; |
||
299 | //===================================================================== |
||
300 | $customerUnit = $this->prepareCustomerImportUnit(); |
||
301 | $addressUnit = $this->prepareAddressImportUnit(); |
||
302 | $addressUnit->setParent($customerUnit); |
||
303 | //===================================================================== |
||
304 | // order matters ;) |
||
305 | $bag = new SimpleBag(); |
||
306 | $bag->add($customerUnit); |
||
307 | $bag->add($addressUnit); |
||
308 | //===================================================================== |
||
309 | $input = new Csv(__DIR__ . '/assets/customers_2.csv', 'r', new Duplicates( |
||
310 | $bag, |
||
311 | new ArrayMap(), |
||
312 | $this->getLanguageAdapter()) |
||
313 | ); |
||
314 | $createTmpFiles = new CreateTmpFiles($bag, $this->config, $this->getLanguageAdapter(), |
||
315 | $input, new ArrayMap(), new DBALMysqlResourceHelper($this->resource)); |
||
316 | $load = new Load($bag, $this->config, $this->resource); |
||
317 | $move = new Move($bag, $this->config, $this->resource); |
||
318 | //===================================================================== |
||
319 | $result = new Result(); |
||
320 | $workflow = new QueueWorkflow($this->config, $result); |
||
321 | $workflow->add($createTmpFiles); |
||
322 | $workflow->add($load); |
||
323 | $workflow->add($move); |
||
324 | $workflow->execute(); |
||
325 | //===================================================================== |
||
326 | // time to assert things |
||
327 | |||
328 | // assert schema |
||
329 | $expected = $this->createXMLDataSet(__DIR__ . '/assets/afterImportWithExistingStructure.xml'); |
||
330 | $actual = $this->getConnection()->createDataSet(['customers', 'addresses']); |
||
331 | $this->assertDataSetsEqual($expected, $actual); |
||
332 | } |
||
333 | |||
334 | /** |
||
335 | * @test |
||
336 | */ |
||
337 | public function testImportDeleteAddresses() |
||
338 | { |
||
339 | // SET THESE TO TRUE TO DEBUG |
||
340 | $this->config['db_debug'] = false; |
||
341 | $this->config['file_debug'] = false; |
||
342 | //===================================================================== |
||
343 | $customerUnit = $this->prepareCustomerImportUnit(); |
||
344 | $addressUnit = $this->prepareAddressImportUnit(); |
||
345 | $addressUnit->setParent($customerUnit); |
||
346 | //===================================================================== |
||
347 | // order matters ;) |
||
348 | $bag = new SimpleBag(); |
||
349 | $bag->add($customerUnit); |
||
350 | $bag->add($addressUnit); |
||
351 | //===================================================================== |
||
352 | $input = new Csv(__DIR__ . '/assets/customers_2.csv', 'r', new Duplicates( |
||
353 | $bag, |
||
354 | new ArrayMap(), |
||
355 | $this->getLanguageAdapter()) |
||
356 | ); |
||
357 | $createTmpFiles = new CreateTmpFiles($bag, $this->config, $this->getLanguageAdapter(), |
||
358 | $input, new ArrayMap(), new DBALMysqlResourceHelper($this->resource)); |
||
359 | $load = new Load($bag, $this->config, $this->resource); |
||
360 | $move = new Move($bag, $this->config, $this->resource); |
||
361 | //===================================================================== |
||
362 | $deleteAddressUnit = new Unit('deleteAddress'); |
||
363 | $deleteAddressUnit->setTable('addresses'); |
||
364 | $deleteAddressUnit->addWriteCondition("isset(map.address_id)"); |
||
365 | $contribution = <<<CONTRIBUTION |
||
366 | map.offsetSet( |
||
367 | 'address_id', |
||
368 | (isset(hashmaps['email-address'][trim(map.email)]) ? |
||
369 | hashmaps['email-address'][trim(map.email)] : |
||
370 | null) |
||
371 | ) |
||
372 | CONTRIBUTION; |
||
373 | |||
374 | $deleteAddressUnit->addContribution($contribution); |
||
375 | $deleteAddressUnit->setMapping(['id' => 'explode(",", map.address_id)']); |
||
376 | |||
377 | $hashMap = new ArrayHashmap('email-address'); |
||
378 | $sql = <<<MYSQL |
||
379 | SELECT c.email,GROUP_CONCAT(a.id) FROM customers c |
||
380 | LEFT JOIN addresses a ON a.parent_id = c.id |
||
381 | GROUP BY c.email |
||
382 | MYSQL; |
||
383 | |||
384 | $hashMap->load($this->resource->getConnection() |
||
385 | ->executeQuery($sql) |
||
386 | ->fetchAll(\PDO::FETCH_KEY_PAIR)); |
||
387 | $deleteAddressUnit->addHashmap($hashMap); |
||
388 | $deleteAddressUnit->setPk('id'); |
||
389 | |||
390 | $deleteBag = new SimpleBag(); |
||
391 | $deleteBag->add($deleteAddressUnit); |
||
392 | |||
393 | $delCreateTmpFiles = new CreateTmpFiles($deleteBag, $this->config, $this->getLanguageAdapter(), |
||
394 | $input, new ArrayMap(), new DBALMysqlResourceHelper($this->resource)); |
||
395 | $delLoad = new Load($deleteBag, $this->config, $this->resource); |
||
396 | $delete = new Delete($deleteBag, $this->config, $this->resource); |
||
397 | //===================================================================== |
||
398 | $result = new Result(); |
||
399 | $workflow = new QueueWorkflow($this->config, $result); |
||
400 | $workflow->add($createTmpFiles); |
||
401 | $workflow->add($load); |
||
402 | $workflow->add($delCreateTmpFiles); |
||
403 | $workflow->add($delLoad); |
||
404 | $workflow->add($delete); |
||
405 | $workflow->add($move); |
||
406 | try { |
||
407 | $this->resource->startTransaction(); |
||
408 | $workflow->execute(); |
||
409 | $this->resource->commit(); |
||
410 | } catch (\Exception $e) { |
||
411 | $this->resource->rollback(); |
||
412 | throw $e; |
||
413 | } |
||
414 | //===================================================================== |
||
415 | // time to assert things |
||
416 | |||
417 | // assert schema |
||
418 | $expected = $this->createXMLDataSet(__DIR__ . '/assets/afterImportDeleteAddressStructure.xml'); |
||
419 | $actual = $this->getConnection()->createDataSet(['customers', 'addresses']); |
||
420 | $this->assertDataSetsEqual($expected, $actual); |
||
421 | } |
||
422 | |||
423 | /** |
||
424 | * @test |
||
425 | * @throws \Doctrine\DBAL\DBALException |
||
426 | * @throws \Exception |
||
427 | */ |
||
428 | public function testImportGenerate() |
||
429 | { |
||
430 | // SET THESE TO TRUE TO DEBUG |
||
431 | $this->config['db_debug'] = false; |
||
432 | $this->config['file_debug'] = false; |
||
433 | //===================================================================== |
||
434 | $bag = new SimpleBag(); |
||
435 | $cu = $this->getGenerateCustomerUnit(); |
||
0 ignored issues
–
show
|
|||
436 | $au = $this->getGenerateAddressUnit(); |
||
0 ignored issues
–
show
|
|||
437 | $au->setParent($cu); |
||
438 | $bag->add($cu); |
||
439 | $bag->add($au); |
||
440 | |||
441 | $generator = new Generator(); |
||
442 | $generator->addProvider(new Base($generator)); |
||
443 | $generator->addProvider(new Lorem($generator)); |
||
444 | $generator->addProvider(new Person($generator)); |
||
445 | $generator->addProvider(new Address($generator)); |
||
446 | $generator->addProvider(new Internet($generator)); |
||
447 | |||
448 | // truncate all info beforehand to not run into issue with duplicate email |
||
449 | $this->resource->getConnection()->executeUpdate("DELETE FROM customers"); |
||
450 | |||
451 | $generate = new Generate($bag, $this->config, $this->getLanguageAdapter(), |
||
452 | $generator, 100, new ArrayMap(), new DBALMysqlResourceHelper($this->resource)); |
||
453 | $load = new Load($bag, $this->config, $this->resource); |
||
454 | $move = new Move($bag, $this->config, $this->resource); |
||
455 | |||
456 | $result = new Result(); |
||
457 | $workflow = new QueueWorkflow($this->config, $result); |
||
458 | $workflow->add($generate); |
||
459 | $workflow->add($load); |
||
460 | $workflow->add($move); |
||
461 | try { |
||
462 | $this->resource->startTransaction(); |
||
463 | $workflow->execute(); |
||
464 | $this->resource->commit(); |
||
465 | } catch (\Exception $e) { |
||
466 | $this->resource->rollback(); |
||
467 | throw $e; |
||
468 | } |
||
469 | |||
470 | $this->assertTableRowCount('customers', 100); |
||
471 | } |
||
472 | |||
473 | /** |
||
474 | * @return Unit |
||
475 | */ |
||
476 | protected function getGenerateCustomerUnit() |
||
477 | { |
||
478 | $customerUnit = new Unit('customers'); |
||
479 | $customerUnit->setGeneratorMapping([ |
||
480 | 'id' => 'map.frozenIncr("customer_id", resource.getLastIncrement("customers"))', |
||
481 | 'firstname' => 'generator.firstName', |
||
482 | 'lastname' => 'generator.lastName', |
||
483 | 'age' => 'generator.numberBetween(10, 60)', |
||
484 | 'email' => 'generator.unique().email', |
||
485 | ]); |
||
486 | $customerUnit->setMapping([ |
||
487 | 'id' => "", |
||
488 | 'firstname' => "", |
||
489 | 'lastname' => "", |
||
490 | 'age' => "", |
||
491 | 'email' => "", |
||
492 | ]); |
||
493 | $customerUnit->setTable("customers"); |
||
494 | return $customerUnit; |
||
495 | } |
||
496 | |||
497 | protected function getGenerateAddressUnit() |
||
498 | { |
||
499 | $addressUnit = new Unit('addresses'); |
||
500 | $seed = new \SplFixedArray(2); |
||
501 | $seed[0] = 4; |
||
502 | $seed[1] = 1; |
||
503 | $addressUnit->setGenerationSeed($seed); |
||
504 | $addressUnit->setGeneratorMapping([ |
||
505 | 'id' => 'map.incr("address_id", resource.getLastIncrement("addresses"))', |
||
506 | 'parent_id' => 'map.customer_id', |
||
507 | 'street' => 'generator.streetAddress', |
||
508 | 'city' => 'generator.city', |
||
509 | ]); |
||
510 | $addressUnit->setMapping([ |
||
511 | 'id' => '', |
||
512 | 'parent_id' => '', |
||
513 | 'street' => '', |
||
514 | 'city' => '', |
||
515 | ]); |
||
516 | $addressUnit->setTable('addresses'); |
||
517 | return $addressUnit; |
||
518 | } |
||
519 | |||
520 | /** |
||
521 | * @test |
||
522 | */ |
||
523 | public function testGenerateExport() |
||
524 | { |
||
525 | // SET THESE TO TRUE TO DEBUG |
||
526 | $this->config['db_debug'] = false; |
||
527 | $this->config['file_debug'] = false; |
||
528 | //===================================================================== |
||
529 | $cUnit = $this->getGenerateCustomerUnit(); |
||
530 | $cUnit->setReversedConnection([ |
||
531 | 'customer_id' => 'id', |
||
532 | ]); |
||
533 | $cUnit->setReversedMapping([ |
||
534 | 'email' => 'map.email', |
||
535 | 'name' => 'map.firstname ~ " " ~ map.lastname', |
||
536 | 'age' => 'map.age', |
||
537 | ]); |
||
538 | $aUnit = $this->getGenerateAddressUnit(); |
||
539 | $aUnit->setReversedConnection([ |
||
540 | 'customer_id' => 'parent_id', |
||
541 | ]); |
||
542 | $aUnit->setReversedMapping([ |
||
543 | 'street' => 'map.street', |
||
544 | 'city' => 'map.city', |
||
545 | ]); |
||
546 | $aUnit->setParent($cUnit); |
||
547 | |||
548 | $bag = new SimpleBag(); |
||
549 | $bag->add($cUnit); |
||
550 | $bag->add($aUnit); |
||
551 | |||
552 | $generator = new Generator(); |
||
553 | $generator->addProvider(new Base($generator)); |
||
554 | $generator->addProvider(new Lorem($generator)); |
||
555 | $generator->addProvider(new Person($generator)); |
||
556 | $generator->addProvider(new Address($generator)); |
||
557 | $generator->addProvider(new Internet($generator)); |
||
558 | |||
559 | // truncate all info beforehand to not run into issue with duplicate email |
||
560 | $this->resource->getConnection()->executeUpdate("DELETE FROM customers"); |
||
561 | |||
562 | $fname = __DIR__ . '/assets/results/customers_generated.csv'; |
||
563 | $input = new Csv($fname, 'w', new Duplicates($bag, new ArrayMap(), $this->getLanguageAdapter())); |
||
564 | |||
565 | $generate = new Generate($bag, $this->config, $this->getLanguageAdapter(), |
||
566 | $generator, 100, new ArrayMap(), new DBALMysqlResourceHelper($this->resource)); |
||
567 | $assemble = new AssembleInput($bag, $this->config, $this->getLanguageAdapter(), $input, new ArrayMap()); |
||
568 | |||
569 | $result = new Result(); |
||
570 | $workflow = new QueueWorkflow($this->config, $result); |
||
571 | $workflow->add($generate); |
||
572 | $workflow->add($assemble); |
||
573 | |||
574 | $workflow->execute(); |
||
575 | //===================================================================== |
||
576 | // assert that customers are in the file |
||
577 | |||
578 | $this->assertFileExists($fname); |
||
579 | $this->assertGreaterThan(100, $this->getNumberOfLines($fname)); |
||
580 | } |
||
581 | |||
582 | /** |
||
583 | * @test |
||
584 | */ |
||
585 | public function testGenerateExport2Branches() |
||
586 | { |
||
587 | // SET THESE TO TRUE TO DEBUG |
||
588 | $this->config['db_debug'] = false; |
||
589 | $this->config['file_debug'] = false; |
||
590 | //===================================================================== |
||
591 | $cUnit = $this->getGenerateCustomerUnit(); |
||
592 | $cUnit->setReversedConnection([ |
||
593 | 'customer_id' => 'id', |
||
594 | ]); |
||
595 | $cUnit->setReversedMapping([ |
||
596 | 'email' => 'map.email', |
||
597 | 'age' => 'map.age', |
||
598 | ]); |
||
599 | $cdUnit = new Unit('customer_data'); |
||
600 | $seed = new \SplFixedArray(2); |
||
601 | $seed[0] = 1; |
||
602 | $seed[1] = 1; |
||
603 | $cdUnit->setGenerationSeed($seed); |
||
604 | $cdUnit->setGeneratorMapping([ |
||
605 | 'id' => 'map.incr("gen_id", 1)', |
||
606 | 'parent_id' => 'map.customer_id', |
||
607 | 'firstname' => 'generator.firstName', |
||
608 | 'lastname' => 'generator.lastName', |
||
609 | ]); |
||
610 | $cdUnit->setMapping([ |
||
611 | 'id' => '', |
||
612 | 'parent_id' => '', |
||
613 | 'firstname' => '', |
||
614 | 'lastname' => '', |
||
615 | ]); |
||
616 | $cdUnit->setTable('customers'); |
||
617 | $cdUnit->setReversedConnection([ |
||
618 | 'customer_id' => 'parent_id', |
||
619 | ]); |
||
620 | $cdUnit->setReversedMapping([ |
||
621 | 'name' => 'map.firstname ~ " " ~ map.lastname', |
||
622 | ]); |
||
623 | $cdUnit->addSibling($cUnit); |
||
624 | |||
625 | $bag = new SimpleBag(); |
||
626 | $bag->add($cUnit); |
||
627 | $bag->add($cdUnit); |
||
628 | |||
629 | $generator = new Generator(); |
||
630 | $generator->addProvider(new Base($generator)); |
||
631 | $generator->addProvider(new Lorem($generator)); |
||
632 | $generator->addProvider(new Person($generator)); |
||
633 | $generator->addProvider(new Address($generator)); |
||
634 | $generator->addProvider(new Internet($generator)); |
||
635 | |||
636 | // truncate all info beforehand to not run into issue with duplicate email |
||
637 | $this->resource->getConnection()->executeUpdate("DELETE FROM customers"); |
||
638 | |||
639 | $fname = __DIR__ . '/assets/results/customers_data_generated.csv'; |
||
640 | $input = new Csv($fname, 'w', new Duplicates($bag, new ArrayMap(), $this->getLanguageAdapter())); |
||
641 | |||
642 | $generate = new Generate($bag, $this->config, $this->getLanguageAdapter(), |
||
643 | $generator, 100, new ArrayMap(), new DBALMysqlResourceHelper($this->resource)); |
||
644 | $assemble = new AssembleInput($bag, $this->config, $this->getLanguageAdapter(), $input, new ArrayMap()); |
||
645 | |||
646 | $result = new Result(); |
||
647 | $workflow = new QueueWorkflow($this->config, $result); |
||
648 | $workflow->add($generate); |
||
649 | $workflow->add($assemble); |
||
650 | |||
651 | $workflow->execute(); |
||
652 | //===================================================================== |
||
653 | // assert that customers are in the file |
||
654 | |||
655 | $this->assertFileExists($fname); |
||
656 | $this->assertEquals(101, $this->getNumberOfLines($fname)); |
||
657 | } |
||
658 | |||
659 | /** |
||
660 | * @test |
||
661 | */ |
||
662 | public function testSimpleExport() |
||
663 | { |
||
664 | // SET THESE TO TRUE TO DEBUG |
||
665 | $this->config['db_debug'] = false; |
||
666 | $this->config['file_debug'] = false; |
||
667 | //===================================================================== |
||
668 | $this->config['dump_limit'] = 100; |
||
669 | |||
670 | $cUnit = new Unit('customers'); |
||
671 | $aUnit = new Unit('addresses'); |
||
672 | //===================================================================== |
||
673 | $cUnit->setTable('customers'); |
||
674 | $aUnit->setTable('addresses'); |
||
675 | $cUnit->setReverseMoveOrder(['id']); |
||
676 | $cUnit->setReverseMoveDirection('asc'); |
||
677 | $aUnit->setReverseMoveOrder(['parent_id']); |
||
678 | $aUnit->setReverseMoveDirection('asc'); |
||
679 | //===================================================================== |
||
680 | $cUnit->setMapping([ |
||
681 | 'id' => "", |
||
682 | 'firstname' => "", |
||
683 | 'lastname' => "", |
||
684 | 'age' => "", |
||
685 | 'email' => "", |
||
686 | ]); |
||
687 | $aUnit->setMapping([ |
||
688 | 'id' => '', |
||
689 | 'parent_id' => '', |
||
690 | 'street' => '', |
||
691 | 'city' => '', |
||
692 | ]); |
||
693 | $cUnit->setReversedConnection([ |
||
694 | 'customer_id' => 'id', |
||
695 | ]); |
||
696 | $cUnit->setReversedMapping([ |
||
697 | 'email' => 'map.email', |
||
698 | 'name' => 'map.firstname ~ " " ~ map.lastname', |
||
699 | 'age' => 'map.age', |
||
700 | ]); |
||
701 | $aUnit->setReversedConnection([ |
||
702 | 'customer_id' => 'parent_id', |
||
703 | ]); |
||
704 | $aUnit->setReversedMapping([ |
||
705 | 'street' => 'map.street', |
||
706 | 'city' => 'map.city', |
||
707 | ]); |
||
708 | $aUnit->setParent($cUnit); |
||
709 | //===================================================================== |
||
710 | $bag = new SimpleBag(); |
||
711 | $bag->addSet([$cUnit, $aUnit]); |
||
712 | |||
713 | $fname = __DIR__ . '/assets/results/customers_data_exported.csv'; |
||
714 | $input = new Csv($fname, 'w', new Duplicates($bag, new ArrayMap(), $this->getLanguageAdapter())); |
||
715 | |||
716 | $reverseMove = new ReverseMove($bag, $this->config, $this->resource); |
||
717 | $dump = new Dump($bag, $this->config, $this->resource); |
||
718 | $assemble = new AssembleInput($bag, $this->config, $this->getLanguageAdapter(), $input, new ArrayMap()); |
||
719 | |||
720 | $result = new Result(); |
||
721 | $workflow = new QueueWorkflow($this->config, $result); |
||
722 | $workflow->add($reverseMove); |
||
723 | $workflow->add($dump); |
||
724 | $workflow->add($assemble); |
||
725 | |||
726 | $workflow->execute(); |
||
727 | //===================================================================== |
||
728 | // assert that customers are in the file |
||
729 | |||
730 | $this->assertFileExists($fname); |
||
731 | $this->assertEquals(4, $this->getNumberOfLines($fname)); |
||
732 | } |
||
733 | |||
734 | public function testExportNull() |
||
735 | { |
||
736 | // SET THESE TO TRUE TO DEBUG |
||
737 | $this->config['db_debug'] = false; |
||
738 | $this->config['file_debug'] = false; |
||
739 | //===================================================================== |
||
740 | $this->config['dump_limit'] = 100; |
||
741 | |||
742 | $cUnit = new Unit('customers'); |
||
743 | //===================================================================== |
||
744 | $cUnit->setTable('customers'); |
||
745 | $cUnit->setReverseMoveOrder(['id']); |
||
746 | $cUnit->setReverseMoveDirection('asc'); |
||
747 | //===================================================================== |
||
748 | $cUnit->setMapping([ |
||
749 | 'id' => "", |
||
750 | 'firstname' => "", |
||
751 | 'lastname' => "", |
||
752 | 'age' => "", |
||
753 | 'email' => "", |
||
754 | ]); |
||
755 | $cUnit->setReversedConnection([ |
||
756 | 'customer_id' => 'id', |
||
757 | ]); |
||
758 | $cUnit->setReversedMapping([ |
||
759 | 'email' => 'map.email', |
||
760 | 'name' => 'map.firstname ~ " " ~ map.lastname', |
||
761 | 'age' => 'map.age', |
||
762 | ]); |
||
763 | //===================================================================== |
||
764 | $bag = new SimpleBag(); |
||
765 | $bag->add($cUnit); |
||
766 | |||
767 | // truncate all info beforehand to not run into issue with duplicate email |
||
768 | $this->resource->getConnection()->executeUpdate("DELETE FROM customers"); |
||
769 | $this->resource->getConnection()->insert('customers', [ |
||
770 | 'id' => 1, |
||
771 | 'firstname' => 'test1', |
||
772 | 'lastname' => 'test1', |
||
773 | 'age' => null, |
||
774 | 'email' => '[email protected]', |
||
775 | ]); |
||
776 | |||
777 | $fname = __DIR__ . '/assets/results/customers_data_exported_with_nulls.csv'; |
||
778 | $input = new Csv($fname, 'w', new Duplicates($bag, new ArrayMap(), $this->getLanguageAdapter())); |
||
779 | |||
780 | $reverseMove = new ReverseMove($bag, $this->config, $this->resource); |
||
781 | $dump = new Dump($bag, $this->config, $this->resource); |
||
782 | $assemble = new AssembleInput($bag, $this->config, $this->getLanguageAdapter(), $input, new ArrayMap()); |
||
783 | |||
784 | $result = new Result(); |
||
785 | $workflow = new QueueWorkflow($this->config, $result); |
||
786 | $workflow->add($reverseMove); |
||
787 | $workflow->add($dump); |
||
788 | $workflow->add($assemble); |
||
789 | |||
790 | $workflow->execute(); |
||
791 | //===================================================================== |
||
792 | // assert that customers are in the file |
||
793 | |||
794 | $this->assertFileExists($fname); |
||
795 | $this->assertEquals(2, $this->getNumberOfLines($fname)); |
||
796 | $csvObject = new \SplFileObject($fname, 'r'); |
||
797 | $csvObject->fgetcsv(); |
||
798 | $actual = $csvObject->fgetcsv(); |
||
799 | $this->assertEquals([ |
||
800 | '[email protected]', |
||
801 | 'test1 test1', |
||
802 | '\N', |
||
803 | ], $actual); |
||
804 | } |
||
805 | |||
806 | /** |
||
807 | * @param string $fname |
||
808 | * @return int |
||
809 | */ |
||
810 | public function getNumberOfLines($fname) |
||
811 | { |
||
812 | $fileObject = new \SplFileObject($fname, 'r'); |
||
813 | $i = 0; |
||
814 | while (!$fileObject->eof()) { |
||
815 | $fileObject->next(); |
||
816 | $current = $fileObject->current(); |
||
817 | if (!empty($current)) { |
||
818 | $i++; |
||
819 | } |
||
820 | } |
||
821 | return $i; |
||
822 | } |
||
823 | } |
||
824 |