Files
admin.juergenandClaude Fable 5.1 142afa6e52 Initial version of the W&K sync bundle for Contao 5.7
Import of W&K seminar exports with preview, booking form via form generator
with event-dependent field rules, notification routing, inbox with folders
and CSV export for W&K.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-24 17:42:34 +02:00

134 lines
5.5 KiB
PHP

<?php
declare(strict_types=1);
namespace Mummert\ContaoWkSyncBundle\Tests\Import;
use Mummert\ContaoWkSyncBundle\Import\ImportMessage;
use Mummert\ContaoWkSyncBundle\Import\RowMapper;
use PHPUnit\Framework\TestCase;
class RowMapperTest extends TestCase
{
/**
* @param array<string, string> $overrides
*
* @return array<string, string>
*/
private function row(array $overrides = []): array
{
return [
'kbnr' => '0003259',
'kbtitel' => 'Pause für den Kopf',
'kbanreise' => '29.09.2026',
'kbabreise' => '30.09.2026',
'kbuanreise' => '09.00',
'kbuabreise' => '16.00',
'kbstatus1' => '2',
'kbsgebiet' => 'Alle Schularten',
'kbvsnr' => 'EXTP00557',
'kbvort' => 'TPI Moritzburg',
'kbkp1' => '240,00',
'kbkp2' => '1.250,50',
'kbanzmax' => '20',
'kbanztat' => '6',
'kbkdemail' => 'info@example.org',
'kbkln1' => 'Tobias Richter',
'kbmref' => "Johanna Fabel\nN.N.\nUwe Hahn\nJohanna Fabel",
'kbwmemo' => 'Lehrkräfte, alle Schularten, Lehrkräfte',
'kbpmemo' => "Absatz eins\nZeile zwei\n\nAbsatz zwei",
'kbzusatz' => "- Punkt 1\n- Punkt 2",
'kbvsart' => '2',
...$overrides,
];
}
public function testMapsAValidRow(): void
{
$mapped = (new RowMapper())->map($this->row(), 2);
self::assertFalse($mapped->skipped);
self::assertSame('0003259', $mapped->wkId);
self::assertSame('Pause für den Kopf', $mapped->data['title']);
self::assertSame(mktime(0, 0, 0, 9, 29, 2026), $mapped->data['startDate']);
self::assertSame(mktime(0, 0, 0, 9, 30, 2026), $mapped->data['endDate']);
self::assertTrue($mapped->data['addTime']);
self::assertSame(mktime(9, 0, 0, 9, 29, 2026), $mapped->data['startTime']);
self::assertSame(mktime(16, 0, 0, 9, 30, 2026), $mapped->data['endTime']);
self::assertSame('2', $mapped->data['wkState']);
self::assertSame('EXTP00557', $mapped->data['wkInternalEventNumber']);
self::assertSame(240.0, $mapped->data['wkPrice1']);
self::assertSame(1250.5, $mapped->data['wkPrice2']);
self::assertSame(20, $mapped->data['wkMaxPlaces']);
self::assertSame(14, $mapped->data['wkPlacesLeft']);
self::assertSame('Tobias Richter', $mapped->instructorName);
self::assertSame(['Johanna Fabel', 'Uwe Hahn'], $mapped->speakerNames);
self::assertSame('Lehrkräfte, alle Schularten', $mapped->data['wkTags']);
self::assertSame('<p>Absatz eins<br>Zeile zwei</p>'."\n".'<p>Absatz zwei</p>', $mapped->data['teaser']);
self::assertSame('<ul><li>Punkt 1</li><li>Punkt 2</li></ul>', $mapped->data['wkTopics']);
self::assertSame('Alle Schularten', $mapped->categoryText);
self::assertSame(2, $mapped->data['wkEventType']);
self::assertSame([], $mapped->messages);
}
public function testAllDayEventGetsMidnightAndEndOfDay(): void
{
$mapped = (new RowMapper())->map($this->row(['kbuanreise' => '', 'kbuabreise' => '']), 2);
self::assertFalse($mapped->data['addTime']);
self::assertSame(mktime(0, 0, 0, 9, 29, 2026), $mapped->data['startTime']);
self::assertSame(mktime(0, 0, 0, 10, 1, 2026) - 1, $mapped->data['endTime']);
}
public function testSkipsRowsWithoutLeadingZeroOrInternalNumberOrTitle(): void
{
$mapper = new RowMapper();
self::assertTrue($mapper->map($this->row(['kbnr' => '3259']), 2)->skipped);
self::assertTrue($mapper->map($this->row(['kbvsnr' => '']), 2)->skipped);
self::assertTrue($mapper->map($this->row(['kbtitel' => '']), 2)->skipped);
self::assertTrue($mapper->map($this->row(['kbanreise' => '. .']), 2)->skipped);
}
public function testKeineBecomesEmptyInternalNumberCaseInsensitive(): void
{
$mapper = new RowMapper();
self::assertSame('', $mapper->map($this->row(['kbvsnr' => 'Keine']), 2)->data['wkInternalEventNumber']);
self::assertSame('', $mapper->map($this->row(['kbvsnr' => 'keine']), 2)->data['wkInternalEventNumber']);
}
public function testInvalidEmailBecomesWarningAndEmptyField(): void
{
$mapped = (new RowMapper())->map($this->row(['kbkdemail' => 'kaputt']), 2);
self::assertSame('', $mapped->data['wkOrganizerEmail']);
self::assertCount(1, $mapped->messages);
self::assertSame(ImportMessage::WARNING, $mapped->messages[0]->type);
}
public function testExternalRegistrationUrlIsKept(): void
{
$mapped = (new RowMapper())->map($this->row(['kbkdemail' => 'https://example.org/anmeldung?x=1']), 2);
self::assertSame('https://example.org/anmeldung?x=1', $mapped->data['wkOrganizerEmail']);
self::assertSame([], $mapped->messages);
}
public function testEndDateBeforeStartFallsBackToStart(): void
{
$mapped = (new RowMapper())->map($this->row(['kbabreise' => '01.01.2020']), 2);
self::assertSame($mapped->data['startDate'], $mapped->data['endDate']);
self::assertSame(ImportMessage::WARNING, $mapped->messages[0]->type);
}
public function testStreetAndCountryAreMappedCorrectly(): void
{
$mapped = (new RowMapper())->map($this->row(['kbkdstr' => 'Bahnhofstraße 9', 'kbkdlkz' => 'D']), 2);
self::assertSame('Bahnhofstraße 9', $mapped->data['wkOrganizerStreet']);
self::assertSame('D', $mapped->data['wkOrganizerCountryCode']);
}
}