Compare commits

...

13 Commits

37 changed files with 3321 additions and 68 deletions

View File

@ -19,13 +19,11 @@ use D3\DataWizard\Application\Model\Configuration;
use D3\DataWizard\Application\Model\Exceptions\DataWizardException;
use D3\DataWizard\Application\Model\Exceptions\DebugException;
use D3\ModCfg\Application\Model\d3database;
use D3\ModCfg\Application\Model\Exception\d3_cfg_mod_exception;
use D3\ModCfg\Application\Model\Exception\d3ShopCompatibilityAdapterException;
use Doctrine\DBAL\DBALException;
use OxidEsales\Eshop\Application\Controller\Admin\AdminDetailsController;
use OxidEsales\Eshop\Core\Config;
use OxidEsales\Eshop\Core\Exception\DatabaseConnectionException;
use OxidEsales\Eshop\Core\Exception\DatabaseErrorException;
use OxidEsales\Eshop\Core\Exception\StandardException;
use OxidEsales\Eshop\Core\Registry;
class d3ActionWizard extends AdminDetailsController
@ -42,7 +40,7 @@ class d3ActionWizard extends AdminDetailsController
$this->configuration = oxNew(Configuration::class);
}
public function getGroups()
public function getGroups(): array
{
return $this->configuration->getActionGroups();
}
@ -54,9 +52,6 @@ class d3ActionWizard extends AdminDetailsController
/**
* @throws DatabaseConnectionException
* @throws StandardException
* @throws d3ShopCompatibilityAdapterException
* @throws d3_cfg_mod_exception
*/
public function runTask()
{
@ -79,7 +74,7 @@ class d3ActionWizard extends AdminDetailsController
[ $queryString, $parameters ] = $action->getQuery();
if (Registry::getConfig()->getConfigParam('d3datawizard_debug')) {
if ($this->d3GetConfig()->getConfigParam('d3datawizard_debug')) {
throw oxNew(
DebugException::class,
d3database::getInstance()->getPreparedStatementQuery($queryString, $parameters)
@ -89,6 +84,14 @@ class d3ActionWizard extends AdminDetailsController
$action->run();
}
/**
* @return Config
*/
public function d3GetConfig(): Config
{
return Registry::getConfig();
}
public function getUserMessages()
{
return null;

View File

@ -25,6 +25,7 @@ use D3\ModCfg\Application\Model\Exception\d3_cfg_mod_exception;
use D3\ModCfg\Application\Model\Exception\d3ShopCompatibilityAdapterException;
use Doctrine\DBAL\DBALException;
use OxidEsales\Eshop\Application\Controller\Admin\AdminDetailsController;
use OxidEsales\Eshop\Core\Config;
use OxidEsales\Eshop\Core\Exception\DatabaseConnectionException;
use OxidEsales\Eshop\Core\Exception\DatabaseErrorException;
use OxidEsales\Eshop\Core\Exception\StandardException;
@ -44,7 +45,7 @@ class d3ExportWizard extends AdminDetailsController
$this->configuration = oxNew(Configuration::class);
}
public function getGroups()
public function getGroups(): array
{
return $this->configuration->getExportGroups();
}
@ -87,7 +88,7 @@ class d3ExportWizard extends AdminDetailsController
[ $queryString, $parameters ] = $export->getQuery();
if (Registry::getConfig()->getConfigParam('d3datawizard_debug')) {
if ($this->d3GetConfig()->getConfigParam('d3datawizard_debug')) {
throw oxNew(
DebugException::class,
d3database::getInstance()->getPreparedStatementQuery($queryString, $parameters)
@ -97,6 +98,14 @@ class d3ExportWizard extends AdminDetailsController
$export->run(Registry::getRequest()->getRequestEscapedParameter('format'));
}
/**
* @return Config
*/
public function d3GetConfig(): Config
{
return Registry::getConfig();
}
public function getUserMessages()
{
return null;

View File

@ -19,6 +19,7 @@ use D3\DataWizard\Application\Model\Exceptions\InputUnvalidException;
use FormManager\Inputs\Checkbox;
use FormManager\Inputs\Input;
use FormManager\Inputs\Radio;
use OxidEsales\Eshop\Core\Database\Adapter\DatabaseInterface;
use OxidEsales\Eshop\Core\DatabaseProvider;
use OxidEsales\Eshop\Core\Exception\DatabaseConnectionException;
use OxidEsales\Eshop\Core\Exception\DatabaseErrorException;
@ -76,7 +77,7 @@ abstract class ActionBase implements QueryBase
);
}
$affected = DatabaseProvider::getDb( DatabaseProvider::FETCH_MODE_ASSOC )->execute( $queryString, $parameters );
$affected = $this->d3GetDb()->execute( $queryString, $parameters );
throw oxNew(
Exceptions\TaskException::class,
@ -90,6 +91,15 @@ abstract class ActionBase implements QueryBase
);
}
/**
* @return DatabaseInterface|null
* @throws DatabaseConnectionException
*/
public function d3GetDb(): ?DatabaseInterface
{
return DatabaseProvider::getDb( DatabaseProvider::FETCH_MODE_ASSOC );
}
/**
* @return string
*/
@ -103,15 +113,12 @@ abstract class ActionBase implements QueryBase
*/
public function registerFormElement(Input $input)
{
switch (get_class($input)) {
case Radio::class:
case Checkbox::class:
$input->setTemplate('<p class="form-check">{{ input }} {{ label }}</p>');
$input->setAttribute('class', 'form-check-input');
break;
default:
$input->setTemplate('<p class="formElements">{{ label }} {{ input }}</p>');
$input->setAttribute('class', 'form-control');
if ($input instanceof Radio || $input instanceof Checkbox) {
$input->setTemplate('<p class="form-check">{{ input }} {{ label }}</p>');
$input->setAttribute('class', 'form-check-input');
} else {
$input->setTemplate('<p class="formElements">{{ label }} {{ input }}</p>');
$input->setAttribute('class', 'form-control');
}
$this->formElements[] = $input;
}

View File

@ -15,11 +15,7 @@ declare(strict_types=1);
namespace D3\DataWizard\Application\Model;
use D3\DataWizard\Application\Model\Actions\FixArtextendsItems;
use D3\DataWizard\Application\Model\Exceptions\DataWizardException;
use D3\DataWizard\Application\Model\Exports\InactiveCategories;
use D3\DataWizard\Application\Model\Exports\KeyFigures;
use OxidEsales\Eshop\Core\Registry;
class Configuration
{
@ -149,7 +145,13 @@ class Configuration
*/
public function getActionById($id) : ActionBase
{
return $this->getAllActions()[$id];
$allActions = $this->getAllActions();
if (false == $allActions[$id]) {
throw oxNew(DataWizardException::class, 'no action with id '.$id);
}
return $allActions[$id];
}
/**

View File

@ -25,6 +25,7 @@ use Doctrine\DBAL\DBALException;
use FormManager\Inputs\Checkbox;
use FormManager\Inputs\Input;
use FormManager\Inputs\Radio;
use OxidEsales\Eshop\Core\Database\Adapter\DatabaseInterface;
use OxidEsales\Eshop\Core\DatabaseProvider;
use OxidEsales\Eshop\Core\Exception\DatabaseConnectionException;
use OxidEsales\Eshop\Core\Exception\DatabaseErrorException;
@ -69,23 +70,7 @@ abstract class ExportBase implements QueryBase
}
}
[ $rows, $fieldNames ] = $this->getExportData( $this->getQuery() );
$content = $this->renderContent($rows, $fieldNames, $format);
/** @var $oFS d3filesystem */
$oFS = oxNew( d3filesystem::class );
if (is_null($path)) {
$oFS->startDirectDownload( $oFS->filterFilename( $this->getExportFileName( $format ) ), $content );
} else {
$filePath = $oFS->trailingslashit($path).$oFS->filterFilename( $this->getExportFileName( $format ) );
if (false === $oFS->createFile($filePath, $content,true)) {
throw oxNew(ExportFileException::class, $filePath);
}
return $filePath;
}
return '';
return $this->executeExport($format, $path);
}
/**
@ -110,7 +95,7 @@ abstract class ExportBase implements QueryBase
/**
* @return RendererBridge
*/
public function getRendererBridge()
public function getRendererBridge(): RendererBridge
{
return oxNew(RendererBridge::class);
}
@ -180,7 +165,7 @@ abstract class ExportBase implements QueryBase
);
}
$rows = DatabaseProvider::getDb( DatabaseProvider::FETCH_MODE_ASSOC )->getAll( $queryString, $parameters );
$rows = $this->d3GetDb()->getAll( $queryString, $parameters );
if ( count( $rows ) <= 0 ) {
throw oxNew(
@ -200,15 +185,12 @@ abstract class ExportBase implements QueryBase
*/
public function registerFormElement(Input $input)
{
switch (get_class($input)) {
case Radio::class:
case Checkbox::class:
$input->setTemplate('<p class="form-check">{{ input }} {{ label }}</p>');
$input->setAttribute('class', 'form-check-input');
break;
default:
$input->setTemplate('<p class="formElements">{{ label }} {{ input }}</p>');
$input->setAttribute('class', 'form-control');
if ($input instanceof Radio || $input instanceof Checkbox) {
$input->setTemplate('<p class="form-check">{{ input }} {{ label }}</p>');
$input->setAttribute('class', 'form-check-input');
} else {
$input->setTemplate('<p class="formElements">{{ label }} {{ input }}</p>');
$input->setAttribute('class', 'form-control');
}
$this->formElements[] = $input;
}
@ -228,4 +210,54 @@ abstract class ExportBase implements QueryBase
{
return $this->formElements;
}
/**
* @param string $format
* @param $path
* @return string
* @throws DBALException
* @throws DatabaseConnectionException
* @throws DatabaseErrorException
* @throws Exceptions\NoSuitableRendererException
* @throws StandardException
* @throws d3ShopCompatibilityAdapterException
* @throws d3_cfg_mod_exception
*/
protected function executeExport(string $format, $path): string
{
[$rows, $fieldNames] = $this->getExportData($this->getQuery());
$content = $this->renderContent($rows, $fieldNames, $format);
/** @var $oFS d3filesystem */
$oFS = $this->getFileSystem();
if (is_null($path)) {
$oFS->startDirectDownload($oFS->filterFilename($this->getExportFileName($format)), $content);
} else {
$filePath = $oFS->trailingslashit($path) . $oFS->filterFilename($this->getExportFileName($format));
if (false === $oFS->createFile($filePath, $content, true)) {
throw oxNew(ExportFileException::class, $filePath);
}
return $filePath;
}
return '';
}
/**
* @return DatabaseInterface|null
* @throws DatabaseConnectionException
*/
protected function d3GetDb(): ?DatabaseInterface
{
return DatabaseProvider::getDb(DatabaseProvider::FETCH_MODE_ASSOC);
}
/**
* @return d3filesystem|mixed
*/
protected function getFileSystem()
{
return oxNew(d3filesystem::class);
}
}

View File

@ -19,6 +19,7 @@ use D3\DataWizard\Application\Model\Exceptions\RenderException;
use League\Csv\EncloseField;
use League\Csv\Exception;
use League\Csv\Writer;
use OxidEsales\Eshop\Core\Config;
use OxidEsales\Eshop\Core\Registry;
class Csv implements RendererInterface
@ -36,7 +37,7 @@ class Csv implements RendererInterface
$csv = $this->getCsv();
$csv->insertOne( $fieldNames );
$csv->insertAll( $rows );
return method_exists($csv, 'getContent') ? $csv->getContent() : (string) $csv;
return (string) $csv;
} catch (Exception $e) {
/** @var RenderException $newException */
$newException = oxNew(RenderException::class, $e->getMessage(), $e->getCode(), $e );
@ -59,13 +60,13 @@ class Csv implements RendererInterface
EncloseField::addTo($csv, "\t\x1f");
$sEncloser = Registry::getConfig()->getConfigParam('sGiCsvFieldEncloser');
$sEncloser = $this->d3GetConfig()->getConfigParam('sGiCsvFieldEncloser');
if (false == $sEncloser) {
$sEncloser = '"';
}
$csv->setEnclosure($sEncloser);
$sDelimiter = Registry::getConfig()->getConfigParam('sCSVSign');
$sDelimiter = $this->d3GetConfig()->getConfigParam('sCSVSign');
if (false == $sDelimiter) {
$sDelimiter = ';';
}
@ -81,4 +82,12 @@ class Csv implements RendererInterface
{
return 'D3_DATAWIZARD_EXPORT_FORMAT_CSV';
}
/**
* @return Config
*/
public function d3GetConfig(): Config
{
return Registry::getConfig();
}
}

View File

@ -16,6 +16,7 @@ declare(strict_types=1);
namespace D3\DataWizard\Application\Model\ExportRenderer;
use D3\DataWizard\Application\Model\Exceptions\RenderException;
use JsonException;
class Json implements RendererInterface
{
@ -28,12 +29,15 @@ class Json implements RendererInterface
*/
public function getContent($rows, $fieldNames): string
{
$flags = JSON_PRETTY_PRINT;
$json = json_encode( $rows, $flags );
if ( $json === false ) {
throw oxNew( RenderException::class, json_last_error_msg(), json_last_error());
try {
$flags = JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR;
$json = json_encode( $rows, $flags );
return $json;
} catch ( JsonException $e) {
/** @var RenderException $newException */
$newException = oxNew(RenderException::class, $e->getMessage(), $e->getCode(), $e );
throw $newException;
}
return $json;
}
public function getFileExtension(): string

View File

@ -27,10 +27,19 @@ class Pretty implements RendererInterface
*/
public function getContent($rows, $fieldNames) : string
{
$renderer = oxNew(ArrayToTextTable::class, $rows);
$renderer = $this->getArrayToTextTableInstance($rows);
return $renderer->getTable();
}
/**
* @param $rows
* @return ArrayToTextTable
*/
public function getArrayToTextTableInstance($rows): ArrayToTextTable
{
return oxNew(ArrayToTextTable::class, $rows);
}
/**
* @return string
*/

View File

@ -35,7 +35,7 @@ class RendererBridge
];
}
public function getTranslatedRendererIdList()
public function getTranslatedRendererIdList(): array
{
$rendererList = $this->getRendererList();
array_walk($rendererList, [$this, 'translateRendererId']);

View File

@ -1,5 +1,16 @@
# Changelog
## 2.0.0.0
#### Added
- add tests
- make installable in OXID 6.4
#### Changed
- adjust code to PHP 7.3 and up
---
## 1.4.0.0 (2021-11-11)
#### Added

View File

@ -18,7 +18,7 @@ Sample exports are included in the package d3/datawizardtasks. These are intende
In the console in the shop root (above source and vendor), execute the following command:
```bash
php composer require d3/datawizard
php composer require d3/datawizard:^2.0
```
Activate the module in the admin area of the shop in "Extensions -> Modules".

View File

@ -18,7 +18,7 @@ Im Paket d3/datawizardtasks sind Beispielexporte enthalten. Diese sollen als Imp
Auf der Konsole im Shoproot (oberhalb von source und vendor) folgenden Befehl ausfĂĽhren:
```bash
php composer require d3/datawizard
php composer require d3/datawizard:^2.0
```
Aktivieren Sie das Modul im Shopadmin unter "Erweiterungen -> Module".

View File

@ -25,12 +25,15 @@
"GPL-3.0-or-later"
],
"require": {
"php": ">=7.1",
"oxid-esales/oxideshop-ce": "6.3 - 6.9",
"php": ">=7.3",
"oxid-esales/oxideshop-ce": "6.8 - 6.10",
"league/csv": "^9.0",
"mathieuviossat/arraytotexttable": "^1.0",
"form-manager/form-manager": "^5.1 || ^6.1"
},
"require-dev": {
"oxid-esales/oxideshop-ce": "6.8 - 6.9"
},
"extra": {
"oxideshop": {
"blacklist-filter": [

View File

@ -32,7 +32,7 @@ $aModule = [
'en' => '',
],
'thumbnail' => '',
'version' => '1.4.0.0',
'version' => '2.0.0.0',
'author' => 'D&sup3; Data Development (Inh.: Thomas Dartsch)',
'email' => 'support@shopmodule.com',
'url' => 'https://www.oxidmodule.com/',

2
tests/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
reports
.phpunit.result.cache

52
tests/README.md Normal file
View File

@ -0,0 +1,52 @@
# D3 Datawizard Tests
## Requirements
Both unit and acceptance tests require OXID Testing Library installed.
See https://github.com/OXID-eSales/testing_library.
### Configuration
Please install the packages listed in the composer.json in "require-dev". Unfortunately Composer does not provide an automatic installation.
Here is an example of Testing Library configuration file `oxideshop/test_config.yml`
```
# This file is auto-generated during the composer install
mandatory_parameters:
shop_path: /var/www/oxideshop/source
shop_tests_path: /var/www/oxideshop/tests
partial_module_paths: d3/datawizard
optional_parameters:
shop_url: null
shop_serial: ''
enable_varnish: false
is_subshop: false
install_shop: false
remote_server_dir: null
shop_setup_path: null
restore_shop_after_tests_suite: false
test_database_name: null
restore_after_acceptance_tests: false
restore_after_unit_tests: false
tmp_path: /tmp/oxid_test_library/
database_restoration_class: DatabaseRestorer
activate_all_modules: false
run_tests_for_shop: false
run_tests_for_modules: true
screen_shots_path: null
screen_shots_url: null
browser_name: firefox
selenium_server_ip: 127.0.0.1
selenium_server_port: '4444'
additional_test_paths: null
```
## Unit Tests
To execute unit tests run the following:
```
cd /var/www/oxideshop/
vendor/bin/runtests
```

39
tests/additional.inc.php Executable file
View File

@ -0,0 +1,39 @@
<?php
/**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* https://www.d3data.de
*
* @copyright (C) D3 Data Development (Inh. Thomas Dartsch)
* @author D3 Data Development - Daniel Seifert <info@shopmodule.com>
* @link https://www.oxidmodule.com
*/
// Include datawizard test config
namespace D3\DataWizard\tests;
use D3\ModCfg\Tests\additional_abstract;
use Exception;
use OxidEsales\Eshop\Core\Exception\StandardException;
include(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'd3datawizard_config.php');
class additional extends additional_abstract
{
/**
* additional constructor.
* @throws StandardException
*/
public function __construct()
{
if (D3DATAWIZARD_REQUIRE_MODCFG) {
$this->reactivateModCfg();
}
}
}
try {
d3GetModCfgDIC()->get(additional::class);
} catch (Exception $e) {}

15
tests/d3datawizard_config.php Executable file
View File

@ -0,0 +1,15 @@
<?php
/**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* https://www.d3data.de
*
* @copyright (C) D3 Data Development (Inh. Thomas Dartsch)
* @author D3 Data Development - Daniel Seifert <info@shopmodule.com>
* @link https://www.oxidmodule.com
*/
const D3DATAWIZARD_REQUIRE_MODCFG = true;

27
tests/phpunit.xml Normal file
View File

@ -0,0 +1,27 @@
<phpunit backupGlobals="true"
backupStaticAttributes="false"
beStrictAboutTestsThatDoNotTestAnything="false"
cacheTokens="true"
colors="false"
convertErrorsToExceptions="true"
convertNoticesToExceptions="false"
convertWarningsToExceptions="true"
forceCoversAnnotation="false"
processIsolation="false"
stopOnError="false"
stopOnFailure="false"
stopOnIncomplete="false"
stopOnSkipped="false"
verbose="false">
<filter>
<whitelist processUncoveredFilesFromWhitelist="true">
<directory suffix=".php">../Application</directory>
<directory suffix=".php">../Modules</directory>
<directory suffix=".php">../public</directory>
<directory suffix=".php">../Setup</directory>
</whitelist>
</filter>
<logging>
<log type="junit" target="reports/logfile.xml"/>
</logging>
</phpunit>

View File

@ -0,0 +1,18 @@
<?php
namespace D3\DataWizard\tests\tools;
use D3\DataWizard\Application\Model\ActionBase;
class d3TestAction extends ActionBase
{
public function getTitle(): string
{
return 'TestTitle';
}
public function getQuery(): array
{
return ["UPDATE 1"];
}
}

View File

@ -0,0 +1,18 @@
<?php
namespace D3\DataWizard\tests\tools;
use D3\DataWizard\Application\Model\ExportBase;
class d3TestExport extends ExportBase
{
public function getTitle(): string
{
return 'TestTitle';
}
public function getQuery(): array
{
return ["SELECT 1"];
}
}

View File

@ -0,0 +1,193 @@
<?php
/**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* https://www.d3data.de
*
* @copyright (C) D3 Data Development (Inh. Thomas Dartsch)
* @author D3 Data Development - Daniel Seifert <info@shopmodule.com>
* @link https://www.oxidmodule.com
*/
declare(strict_types=1);
namespace D3\DataWizard\tests\unit\Application\Controller\Admin;
use D3\DataWizard\Application\Controller\Admin\d3ActionWizard;
use D3\DataWizard\Application\Model\Configuration;
use D3\DataWizard\Application\Model\Exceptions\DebugException;
use D3\DataWizard\Application\Model\ExportRenderer\RendererBridge;
use D3\DataWizard\tests\tools\d3TestAction;
use OxidEsales\Eshop\Core\Config;
use OxidEsales\Eshop\Core\Registry;
use OxidEsales\Eshop\Core\Request;
use PHPUnit\Framework\MockObject\MockObject;
use ReflectionException;
class d3ActionWizardTest extends d3AdminControllerTest
{
/** @var d3ActionWizard */
protected $_oController;
protected $testClassName = d3ActionWizard::class;
public function setUp() : void
{
parent::setUp();
$this->_oController = oxNew($this->testClassName);
}
/**
* @covers \D3\DataWizard\Application\Controller\Admin\d3ActionWizard::getGroups()
* @test
* @throws ReflectionException
*/
public function canGetGroups()
{
$expected = ['expected' => 'array'];
/** @var Configuration|MockObject $configurationMock */
$configurationMock = $this->getMockBuilder(Configuration::class)
->onlyMethods(['getActionGroups'])
->getMock();
$configurationMock->expects($this->atLeastOnce())->method('getActionGroups')->willReturn($expected);
$this->setValue($this->_oController, 'configuration', $configurationMock);
$this->assertSame(
$expected,
$this->callMethod(
$this->_oController,
'getGroups'
)
);
}
/**
* @covers \D3\DataWizard\Application\Controller\Admin\d3ActionWizard::getGroupTasks()
* @test
* @throws ReflectionException
* @dataProvider canGetGroupTasksDataProvider
*/
public function canGetGroupTasks($argument)
{
$expected = ['expected' => 'array'];
/** @var Configuration|MockObject $configurationMock */
$configurationMock = $this->getMockBuilder(Configuration::class)
->onlyMethods(['getActionsByGroup'])
->getMock();
$configurationMock->expects($this->atLeastOnce())->method('getActionsByGroup')->with($argument)->willReturn($expected);
$this->setValue($this->_oController, 'configuration', $configurationMock);
$this->assertSame(
$expected,
$this->callMethod(
$this->_oController,
'getGroupTasks',
[$argument]
)
);
}
/**
* @return array
*/
public function canGetGroupTasksDataProvider(): array
{
return [
['test1'],
['test2']
];
}
/**
* @covers \D3\DataWizard\Application\Controller\Admin\d3ActionWizard::execute()
* @test
* @throws ReflectionException
* @dataProvider executePassDataProvider
*/
public function executePass($blDebug)
{
/** @var Request|MockObject $requestMock */
$requestMock = $this->getMockBuilder(get_class(Registry::getRequest()))
->onlyMethods(['getRequestEscapedParameter'])
->getMock();
$requestMock->expects($this->any())->method('getRequestEscapedParameter')->willReturnCallback([$this, 'executePassRequestCallback']);
Registry::set(Request::class, $requestMock);
/** @var Config|MockObject $configMock */
$configMock = $this->getMockBuilder(Config::class)
->onlyMethods(['getConfigParam'])
->getMock();
$configMock->expects($this->atLeastOnce())->method('getConfigParam')->willReturnCallback(
function ($argName) use ($blDebug) {
switch ($argName) {
case 'd3datawizard_debug':
return $blDebug;
default:
return Registry::getConfig()->getConfigParam($argName);
}
}
);
/** @var d3ActionWizard|MockObject $controllerMock */
$controllerMock = $this->getMockBuilder(d3ActionWizard::class)
->onlyMethods(['d3GetConfig'])
->getMock();
$controllerMock->method('d3GetConfig')->willReturn($configMock);
$this->_oController = $controllerMock;
/** @var d3TestAction|MockObject $actionMock */
$actionMock = $this->getMockBuilder(d3TestAction::class)
->onlyMethods([
'getQuery',
'run'
])
->getMock();
$actionMock->expects($this->atLeastOnce())->method('getQuery')->willReturn(['SELECT 1', ['1']]);
$actionMock->expects($this->exactly((int) !$blDebug))->method('run')->willReturn(true);
/** @var Configuration|MockObject $configurationMock */
$configurationMock = $this->getMockBuilder(Configuration::class)
->onlyMethods(['getActionById'])
->disableOriginalConstructor()
->getMock();
$configurationMock->expects($this->atLeastOnce())->method('getActionById')->with('testTaskId')->willReturn($actionMock);
$this->setValue($this->_oController, 'configuration', $configurationMock);
if ($blDebug) {
$this->expectException(DebugException::class);
}
$this->callMethod(
$this->_oController,
'execute'
);
}
public function executePassRequestCallback($varName)
{
switch ($varName) {
case 'taskid':
return 'testTaskId';
case 'format':
return RendererBridge::FORMAT_CSV;
default:
return oxNew(Request::class)->getRequestEscapedParameter($varName);
}
}
/**
* @return array
*/
public function executePassDataProvider(): array
{
return [
'no debug' => [false],
'debug' => [true],
];
}
}

View File

@ -0,0 +1,262 @@
<?php
/**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* https://www.d3data.de
*
* @copyright (C) D3 Data Development (Inh. Thomas Dartsch)
* @author D3 Data Development - Daniel Seifert <info@shopmodule.com>
* @link https://www.oxidmodule.com
*/
declare(strict_types=1);
namespace D3\DataWizard\tests\unit\Application\Controller\Admin;
use D3\DataWizard\Application\Controller\Admin\d3ActionWizard;
use D3\DataWizard\Application\Controller\Admin\d3ExportWizard;
use D3\DataWizard\Application\Model\Configuration;
use D3\DataWizard\Application\Model\Exceptions\DataWizardException;
use D3\DataWizard\Application\Model\Exceptions\DebugException;
use D3\DataWizard\tests\tools\d3TestAction;
use D3\ModCfg\Tests\unit\d3ModCfgUnitTestCase;
use Doctrine\DBAL\DBALException;
use OxidEsales\Eshop\Core\Config;
use OxidEsales\Eshop\Core\Exception\DatabaseErrorException;
use OxidEsales\Eshop\Core\Registry;
use OxidEsales\Eshop\Core\Request;
use OxidEsales\Eshop\Core\UtilsView;
use PHPUnit\Framework\MockObject\MockObject;
use Psr\Log\LoggerInterface;
use ReflectionException;
abstract class d3AdminControllerTest extends d3ModCfgUnitTestCase
{
/** @var d3ActionWizard|d3ExportWizard */
protected $_oController;
protected $testClassName;
public function tearDown() : void
{
parent::tearDown();
unset($this->_oController);
}
/**
* @covers \D3\DataWizard\Application\Controller\Admin\d3ActionWizard::__construct
* @covers \D3\DataWizard\Application\Controller\Admin\d3ExportWizard::__construct
* @test
* @throws ReflectionException
*/
public function testConstructor()
{
$this->setValue($this->_oController, 'configuration', null);
$this->callMethod(
$this->_oController,
'__construct'
);
$this->assertInstanceOf(
Configuration::class,
$this->getValue(
$this->_oController,
'configuration'
)
);
}
/**
* @covers \D3\DataWizard\Application\Controller\Admin\d3ActionWizard::runTask()
* @covers \D3\DataWizard\Application\Controller\Admin\d3ExportWizard::runTask()
* @test
* @throws ReflectionException
*/
public function runTaskPass()
{
/** @var d3ActionWizard|d3ExportWizard|MockObject $controllerMock */
$controllerMock = $this->getMockBuilder($this->testClassName)
->onlyMethods(['execute'])
->getMock();
$controllerMock->expects($this->once())->method('execute')->willReturn(true);
$this->_oController = $controllerMock;
$this->callMethod(
$this->_oController,
'runTask'
);
}
/**
* @covers \D3\DataWizard\Application\Controller\Admin\d3ActionWizard::runTask()
* @covers \D3\DataWizard\Application\Controller\Admin\d3ExportWizard::runTask()
* @test
* @param $exceptionClass
* @throws ReflectionException
* @dataProvider runTaskFailedDataProvider
*/
public function runTaskFailed($exceptionClass)
{
/** @var DataWizardException|DBALException|DatabaseErrorException|MockObject $exceptionMock */
$exceptionMock = $this->getMockBuilder($exceptionClass)
->disableOriginalConstructor()
->getMock();
$this->setValue($exceptionMock, 'message', 'exc_msg');
/** @var d3ActionWizard|d3ExportWizard|MockObject $controllerMock */
$controllerMock = $this->getMockBuilder($this->testClassName)
->onlyMethods(['execute'])
->getMock();
$controllerMock->expects($this->once())->method('execute')->willThrowException($exceptionMock);
/** @var LoggerInterface|MockObject $loggerMock */
$loggerMock = $this->getMockBuilder(get_class(Registry::getLogger()))
->onlyMethods(['error'])
->disableOriginalConstructor()
->getMock();
$loggerMock->expects($this->atLeastOnce())->method('error')->with('exc_msg')->willReturn(true);
Registry::set('logger', $loggerMock);
/** @var UtilsView|MockObject $utilsViewMock */
$utilsViewMock = $this->getMockBuilder(get_class(Registry::getUtilsView()))
->onlyMethods(['addErrorToDisplay'])
->getMock();
$utilsViewMock->expects($this->atLeastOnce())->method('addErrorToDisplay')->with($exceptionMock)->willReturn(true);
Registry::set(UtilsView::class, $utilsViewMock);
$this->_oController = $controllerMock;
$this->callMethod(
$this->_oController,
'runTask'
);
}
/**
* @return \string[][]
*/
public function runTaskFailedDataProvider(): array
{
return [
[DataWizardException::class],
[DBALException::class],
[DatabaseErrorException::class],
];
}
/**
* @covers \D3\DataWizard\Application\Controller\Admin\d3ActionWizard::execute()
* @covers \D3\DataWizard\Application\Controller\Admin\d3ExportWizard::execute()
* @test
* @throws ReflectionException
* @dataProvider executePassDataProvider
*/
public function executePass($blDebug)
{
/** @var Request|MockObject $requestMock */
$requestMock = $this->getMockBuilder(get_class(Registry::getRequest()))
->onlyMethods(['getRequestEscapedParameter'])
->getMock();
$requestMock->expects($this->atLeastOnce())->method('getRequestEscapedParameter')->with('taskid')->willReturn('testTaskId');
Registry::set(Request::class, $requestMock);
/** @var d3TestAction|MockObject $actionMock */
$actionMock = $this->getMockBuilder(d3TestAction::class)
->onlyMethods([
'getQuery',
'run'
])
->getMock();
$actionMock->expects($this->atLeastOnce())->method('getQuery')->willReturn(['SELECT 1', ['1']]);
$actionMock->expects($this->exactly((int) !$blDebug))->method('run')->willReturn(true);
/** @var Configuration|MockObject $configurationMock */
$configurationMock = $this->getMockBuilder(Configuration::class)
->onlyMethods(['getActionById'])
->disableOriginalConstructor()
->getMock();
$configurationMock->expects($this->atLeastOnce())->method('getActionById')->with('testTaskId')->willReturn($actionMock);
$this->setValue($this->_oController, 'configuration', $configurationMock);
/** @var Config|MockObject $configMock */
$configMock = $this->getMockBuilder(Config::class)
->onlyMethods(['getConfigParam'])
->getMock();
$configMock->expects($this->atLeastOnce())->method('getConfigParam')->willReturn($blDebug);
Registry::set(Config::class, $configMock);
if ($blDebug) {
$this->expectException(DebugException::class);
}
$this->callMethod(
$this->_oController,
'execute'
);
}
/**
* @return array
*/
public function executePassDataProvider(): array
{
return [
'no debug' => [false],
'debug' => [true],
];
}
/**
* @covers \D3\DataWizard\Application\Controller\Admin\d3ActionWizard::getUserMessages()
* @covers \D3\DataWizard\Application\Controller\Admin\d3ExportWizard::getUserMessages()
* @test
* @throws ReflectionException
*/
public function canGetUserMessages()
{
$this->assertNull(
$this->callMethod(
$this->_oController,
'getUserMessages'
)
);
}
/**
* @covers \D3\DataWizard\Application\Controller\Admin\d3ActionWizard::getHelpURL()
* @covers \D3\DataWizard\Application\Controller\Admin\d3ExportWizard::getHelpURL()
* @test
* @throws ReflectionException
*/
public function canGetHelpUrl()
{
$this->assertNull(
$this->callMethod(
$this->_oController,
'getHelpURL'
)
);
}
/**
* @covers \D3\DataWizard\Application\Controller\Admin\d3ExportWizard::d3GetConfig
* @covers \D3\DataWizard\Application\Controller\Admin\d3ActionWizard::d3GetConfig
* @test
* @throws ReflectionException
*/
public function canGetConfig()
{
$this->assertInstanceOf(
Config::class,
$this->callMethod(
$this->_oController,
'd3GetConfig'
)
);
}
}

View File

@ -0,0 +1,195 @@
<?php
/**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* https://www.d3data.de
*
* @copyright (C) D3 Data Development (Inh. Thomas Dartsch)
* @author D3 Data Development - Daniel Seifert <info@shopmodule.com>
* @link https://www.oxidmodule.com
*/
declare(strict_types=1);
namespace D3\DataWizard\tests\unit\Application\Controller\Admin;
use D3\DataWizard\Application\Controller\Admin\d3ExportWizard;
use D3\DataWizard\Application\Model\Configuration;
use D3\DataWizard\Application\Model\Exceptions\DebugException;
use D3\DataWizard\Application\Model\ExportRenderer\RendererBridge;
use D3\DataWizard\tests\tools\d3TestAction;
use D3\DataWizard\tests\tools\d3TestExport;
use OxidEsales\Eshop\Core\Config;
use OxidEsales\Eshop\Core\Registry;
use OxidEsales\Eshop\Core\Request;
use PHPUnit\Framework\MockObject\MockObject;
use ReflectionException;
class d3ExportWizardTest extends d3AdminControllerTest
{
/** @var d3ExportWizard */
protected $_oController;
protected $testClassName = d3ExportWizard::class;
public function setUp() : void
{
parent::setUp();
$this->_oController = oxNew($this->testClassName);
}
/**
* @covers \D3\DataWizard\Application\Controller\Admin\d3ExportWizard::getGroups()
* @test
* @throws ReflectionException
*/
public function canGetGroups()
{
$expected = ['expected' => 'array'];
/** @var Configuration|MockObject $configurationMock */
$configurationMock = $this->getMockBuilder(Configuration::class)
->onlyMethods(['getExportGroups'])
->getMock();
$configurationMock->expects($this->atLeastOnce())->method('getExportGroups')->willReturn($expected);
$this->setValue($this->_oController, 'configuration', $configurationMock);
$this->assertSame(
$expected,
$this->callMethod(
$this->_oController,
'getGroups'
)
);
}
/**
* @covers \D3\DataWizard\Application\Controller\Admin\d3ExportWizard::getGroupTasks()
* @test
* @throws ReflectionException
* @dataProvider canGetGroupTasksDataProvider
*/
public function canGetGroupTasks($argument)
{
$expected = ['expected' => 'array'];
/** @var Configuration|MockObject $configurationMock */
$configurationMock = $this->getMockBuilder(Configuration::class)
->onlyMethods(['getExportsByGroup'])
->getMock();
$configurationMock->expects($this->atLeastOnce())->method('getExportsByGroup')->with($argument)->willReturn($expected);
$this->setValue($this->_oController, 'configuration', $configurationMock);
$this->assertSame(
$expected,
$this->callMethod(
$this->_oController,
'getGroupTasks',
[$argument]
)
);
}
/**
* @return array
*/
public function canGetGroupTasksDataProvider(): array
{
return [
['test1'],
['test2']
];
}
/**
* @covers \D3\DataWizard\Application\Controller\Admin\d3ExportWizard::execute()
* @test
* @throws ReflectionException
* @dataProvider executePassDataProvider
*/
public function executePass($blDebug)
{
/** @var Request|MockObject $requestMock */
$requestMock = $this->getMockBuilder(get_class(Registry::getRequest()))
->onlyMethods(['getRequestEscapedParameter'])
->getMock();
$requestMock->expects($this->any())->method('getRequestEscapedParameter')->willReturnCallback([$this, 'executePassRequestCallback']);
//OnConsecutiveCalls('testTaskId', 'CSV');
Registry::set(Request::class, $requestMock);
/** @var Config|MockObject $configMock */
$configMock = $this->getMockBuilder(Config::class)
->onlyMethods(['getConfigParam'])
->getMock();
$configMock->expects($this->atLeastOnce())->method('getConfigParam')->willReturnCallback(
function ($argName) use ($blDebug) {
switch ($argName) {
case 'd3datawizard_debug':
return $blDebug;
default:
return Registry::getConfig()->getConfigParam($argName);
}
}
);
/** @var d3ExportWizard|MockObject $controllerMock */
$controllerMock = $this->getMockBuilder(d3ExportWizard::class)
->onlyMethods(['d3GetConfig'])
->getMock();
$controllerMock->method('d3GetConfig')->willReturn($configMock);
$this->_oController = $controllerMock;
/** @var d3TestAction|MockObject $exportMock */
$exportMock = $this->getMockBuilder(d3TestExport::class)
->onlyMethods([
'getQuery',
'run'
])
->getMock();
$exportMock->expects($this->atLeastOnce())->method('getQuery')->willReturn(['SELECT 1', ['1']]);
$exportMock->expects($this->exactly((int) !$blDebug))->method('run')->willReturn('');
/** @var Configuration|MockObject $configurationMock */
$configurationMock = $this->getMockBuilder(Configuration::class)
->onlyMethods(['getExportById'])
->disableOriginalConstructor()
->getMock();
$configurationMock->expects($this->atLeastOnce())->method('getExportById')->with('testTaskId')->willReturn($exportMock);
$this->setValue($this->_oController, 'configuration', $configurationMock);
if ($blDebug) {
$this->expectException(DebugException::class);
}
$this->callMethod(
$this->_oController,
'execute'
);
}
public function executePassRequestCallback($varName)
{
switch ($varName) {
case 'taskid':
return 'testTaskId';
case 'format':
return RendererBridge::FORMAT_CSV;
default:
return oxNew(Request::class)->getRequestEscapedParameter($varName);
}
}
/**
* @return array
*/
public function executePassDataProvider(): array
{
return [
'no debug' => [false],
'debug' => [true],
];
}
}

View File

@ -0,0 +1,316 @@
<?php
/**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* https://www.d3data.de
*
* @copyright (C) D3 Data Development (Inh. Thomas Dartsch)
* @author D3 Data Development - Daniel Seifert <info@shopmodule.com>
* @link https://www.oxidmodule.com
*/
declare(strict_types=1);
namespace D3\DataWizard\tests\unit\Application\Model;
use D3\DataWizard\Application\Model\Exceptions\TaskException;
use D3\DataWizard\tests\tools\d3TestAction;
use D3\ModCfg\Tests\unit\d3ModCfgUnitTestCase;
use FormManager\Inputs\Hidden;
use FormManager\Inputs\Number;
use FormManager\Inputs\Radio;
use OxidEsales\Eshop\Core\Database\Adapter\Doctrine\Database;
use OxidEsales\Eshop\Core\Exception\StandardException;
use PHPUnit\Framework\MockObject\MockObject;
use ReflectionException;
class ActionBaseTest extends d3ModCfgUnitTestCase
{
/** @var d3TestAction */
protected $_oModel;
public function setUp() : void
{
parent::setUp();
$this->_oModel = oxNew(d3TestAction::class);
}
public function tearDown() : void
{
parent::tearDown();
unset($this->_oModel);
}
/**
* @covers \D3\DataWizard\Application\Model\ActionBase::getDescription
* @test
* @throws ReflectionException
*/
public function canGetDescription()
{
$this->assertIsString(
$this->callMethod(
$this->_oModel,
'getDescription'
)
);
}
/**
* @covers \D3\DataWizard\Application\Model\ActionBase::getButtonText
* @test
* @throws ReflectionException
*/
public function canGetButtonText()
{
$this->assertIsString(
$this->callMethod(
$this->_oModel,
'getButtonText'
)
);
}
/**
* @covers \D3\DataWizard\Application\Model\ActionBase::hasFormElements
* @test
* @throws ReflectionException
* @dataProvider canGetHasFormElementsDataProvider
*/
public function canGetHasFormElements($formElements, $expected)
{
$this->setValue($this->_oModel, 'formElements', $formElements);
$this->assertSame(
$expected,
$this->callMethod(
$this->_oModel,
'hasFormElements'
)
);
}
public function canGetHasFormElementsDataProvider(): array
{
return [
'hasFormElements' => [['abc', 'def'], true],
'hasNoFormElements' => [[], false],
];
}
/**
* @covers \D3\DataWizard\Application\Model\ActionBase::getFormElements
* @test
* @throws ReflectionException
* @dataProvider canGetHasFormElementsDataProvider
*/
public function canGetFormElements($formElements)
{
$this->setValue($this->_oModel, 'formElements', $formElements);
$this->assertSame(
$formElements,
$this->callMethod(
$this->_oModel,
'getFormElements'
)
);
}
/**
* @covers \D3\DataWizard\Application\Model\ActionBase::registerFormElement
* @test
* @throws ReflectionException
* @dataProvider canRegisterFormElementDataProvider
*/
public function canRegisterFormElement($inputClass)
{
$oldCount = count($this->getValue($this->_oModel, 'formElements'));
/** @var Radio|MockObject $inputMock */
$inputMock = $this->getMockBuilder($inputClass)
->onlyMethods([
'setTemplate',
'setAttribute'
])
->getMock();
$inputMock->expects($this->atLeastOnce())->method('setTemplate');
$inputMock->expects($this->atLeastOnce())->method('setAttribute');
$this->callMethod(
$this->_oModel,
'registerFormElement',
[$inputMock]
);
$newCount = count($this->getValue($this->_oModel, 'formElements'));
$this->assertGreaterThan($oldCount, $newCount);
}
/**
* @return \string[][]
*/
public function canRegisterFormElementDataProvider(): array
{
return [
'Radio' => [Radio::class],
'Checkbox' => [Radio::class],
'Hidden' => [Hidden::class]
];
}
/**
* @covers \D3\DataWizard\Application\Model\ActionBase::run
* @test
* @throws ReflectionException
*/
public function canRunWithoutFormElements()
{
$modelMock = $this->getMockBuilder(d3TestAction::class)
->onlyMethods([
'hasFormElements',
'executeAction',
'getQuery'
])
->getMock();
$modelMock->expects($this->atLeastOnce())->method('hasFormElements')->willReturn(false);
$modelMock->expects($this->atLeastOnce())->method('executeAction')->willReturn(1);
$modelMock->expects($this->atLeastOnce())->method('getQuery')->willReturn([]);
$this->_oModel = $modelMock;
$this->callMethod(
$this->_oModel,
'run'
);
}
/**
* @covers \D3\DataWizard\Application\Model\ActionBase::run
* @test
* @throws ReflectionException
* @dataProvider canRunWithFormElementsDataProvider
*/
public function canRunWithFormElements($elements, $blThrowException)
{
$expectedException = oxNew(StandardException::class);
$modelMock = $this->getMockBuilder(d3TestAction::class)
->onlyMethods([
'hasFormElements',
'executeAction',
'getQuery',
'getFormElements'
])
->getMock();
$modelMock->expects($this->atLeastOnce())->method('hasFormElements')->willReturn(true);
$modelMock->expects($this->exactly((int) !$blThrowException))->method('executeAction')->willReturn(1);
$modelMock->expects($this->exactly((int) !$blThrowException))->method('getQuery')->willReturn([]);
$modelMock->expects($this->atLeastOnce())->method('getFormElements')->willReturn($elements);
$this->_oModel = $modelMock;
if ($blThrowException) {
$this->expectException(get_class($expectedException));
}
$this->callMethod(
$this->_oModel,
'run'
);
}
/**
* @return array[]
*/
public function canRunWithFormElementsDataProvider(): array
{
/** @var Radio|MockObject $validMock */
$validMock = $this->getMockBuilder(Radio::class)
->onlyMethods(['isValid'])
->getMock();
$validMock->expects($this->atLeastOnce())->method('isValid')->willReturn(true);
$invalidField = new Number(null, [
'required' => true,
'min' => 1,
'max' => 10,
'step' => 5,
]);
$invalidField
->setValue(20)
->setErrorMessages(['errorMsgs']);
return [
'validElements' => [[$validMock, $validMock], false],
'invalidElements' => [[$validMock, $invalidField], true]
];
}
/**
* @covers \D3\DataWizard\Application\Model\ActionBase::executeAction
* @test
* @throws ReflectionException
* @dataProvider canExecuteActionDataProvider
*/
public function canExecuteAction($query, $throwsException)
{
/** @var Database|MockObject $dbMock */
$dbMock = $this->getMockBuilder(Database::class)
->onlyMethods(['execute'])
->getMock();
$dbMock->expects($this->exactly((int) !$throwsException))->method('execute')->willReturn(true);
/** @var d3TestAction|MockObject $modelMock */
$modelMock = $this->getMockBuilder(d3TestAction::class)
->onlyMethods(['d3GetDb'])
->getMock();
$modelMock->expects($this->exactly((int) !$throwsException))->method('d3GetDb')->willReturn($dbMock);
$this->_oModel = $modelMock;
try {
$this->callMethod(
$this->_oModel,
'executeAction',
[[$query, ['parameters']]]
);
} catch (TaskException $e) {
if ($throwsException) {
$this->assertStringContainsString('ACTIONSELECT', $e->getMessage());
} else {
$this->assertStringContainsString('ACTIONRESULT', $e->getMessage());
}
}
}
/**
* @return array[]
*/
public function canExecuteActionDataProvider(): array
{
return [
'Select throws exception' => ['SELECT 1', true],
'Update dont throws exception' => ['UPDATE 1', false],
];
}
/**
* @covers \D3\DataWizard\Application\Model\ActionBase::d3GetDb
* @test
* @throws ReflectionException
*/
public function canGetDb()
{
$this->assertInstanceOf(
Database::class,
$this->callMethod(
$this->_oModel,
'd3GetDb'
)
);
}
}

View File

@ -0,0 +1,455 @@
<?php
/**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* https://www.d3data.de
*
* @copyright (C) D3 Data Development (Inh. Thomas Dartsch)
* @author D3 Data Development - Daniel Seifert <info@shopmodule.com>
* @link https://www.oxidmodule.com
*/
declare(strict_types=1);
namespace D3\DataWizard\tests\unit\Application\Model;
use D3\DataWizard\Application\Model\Configuration;
use D3\DataWizard\Application\Model\Exceptions\DataWizardException;
use D3\DataWizard\tests\tools\d3TestAction;
use D3\DataWizard\tests\tools\d3TestExport;
use D3\ModCfg\Tests\unit\d3ModCfgUnitTestCase;
use PHPUnit\Framework\MockObject\MockObject;
use ReflectionException;
class ConfigurationTest extends d3ModCfgUnitTestCase
{
/** @var Configuration */
protected $_oModel;
public function setUp() : void
{
parent::setUp();
$this->_oModel = oxNew(Configuration::class);
}
public function tearDown() : void
{
parent::tearDown();
unset($this->_oModel);
}
/**
* @covers \D3\DataWizard\Application\Model\Configuration::__construct
* @test
* @throws ReflectionException
*/
public function canConstruct()
{
/** @var Configuration|MockObject $modelMock */
$modelMock = $this->getMockBuilder(Configuration::class)
->disableOriginalConstructor()
->onlyMethods(['configure'])
->getMock();
$modelMock->expects($this->once())->method('configure');
$this->_oModel = $modelMock;
$this->callMethod(
$this->_oModel,
'__construct'
);
}
/**
* @covers \D3\DataWizard\Application\Model\Configuration::configure()
* @test
* @throws ReflectionException
*/
public function canConfigure()
{
$this->assertEmpty(
$this->callMethod(
$this->_oModel,
'configure'
)
);
}
/**
* @covers \D3\DataWizard\Application\Model\Configuration::registerAction
* @test
* @throws ReflectionException
*/
public function canRegisterAction()
{
$action = oxNew(d3TestAction::class);
$oldCount = count($this->getValue(
$this->_oModel,
'actions'
));
$this->callMethod(
$this->_oModel,
'registerAction',
['testGroup', $action]
);
$actions = $this->getValue(
$this->_oModel,
'actions'
);
$newCount = count($actions);
$flattedActions = $this->array_flatten($actions);
$this->assertGreaterThan($oldCount, $newCount);
$this->assertContains($action, $flattedActions);
}
/**
* @covers \D3\DataWizard\Application\Model\Configuration::registerExport
* @test
* @throws ReflectionException
*/
public function canRegisterExport()
{
$export = oxNew(d3TestExport::class);
$oldCount = count($this->getValue(
$this->_oModel,
'exports'
));
$this->callMethod(
$this->_oModel,
'registerExport',
['testGroup', $export]
);
$exports = $this->getValue(
$this->_oModel,
'exports'
);
$newCount = count($exports);
$flattedExports = $this->array_flatten($exports);
$this->assertGreaterThan($oldCount, $newCount);
$this->assertContains($export, $flattedExports);
}
/**
* @param $array
* @return array|false
*/
public function array_flatten($array) {
if (!is_array($array)) {
return false;
}
$result = array();
foreach ($array as $key => $value) {
if (is_array($value)) {
$result = array_merge($result, $this->array_flatten($value));
}
else {
$result[$key] = $value;
}
}
return $result;
}
/**
* @covers \D3\DataWizard\Application\Model\Configuration::getGroupedActions()
* @test
* @throws ReflectionException
*/
public function canGetGroupedActions()
{
$actionList = ['abc', 'def'];
$this->setValue(
$this->_oModel,
'actions',
$actionList
);
$this->assertSame(
$actionList,
$this->callMethod(
$this->_oModel,
'getGroupedActions'
)
);
}
/**
* @covers \D3\DataWizard\Application\Model\Configuration::getGroupedExports()
* @test
* @throws ReflectionException
*/
public function canGetGroupedExports()
{
$exportList = ['abc', 'def'];
$this->setValue(
$this->_oModel,
'exports',
$exportList
);
$this->assertSame(
$exportList,
$this->callMethod(
$this->_oModel,
'getGroupedExports'
)
);
}
/**
* @covers \D3\DataWizard\Application\Model\Configuration::getActionGroups()
* @test
* @throws ReflectionException
*/
public function canGetActionGroups()
{
$actionList = ['abc' => '123', 'def' => '456'];
$this->setValue(
$this->_oModel,
'actions',
$actionList
);
$this->assertSame(
['abc', 'def'],
$this->callMethod(
$this->_oModel,
'getActionGroups'
)
);
}
/**
* @covers \D3\DataWizard\Application\Model\Configuration::getExportGroups()
* @test
* @throws ReflectionException
*/
public function canGetExportGroups()
{
$exportList = ['abc' => '123', 'def' => '456'];
$this->setValue(
$this->_oModel,
'exports',
$exportList
);
$this->assertSame(
['abc', 'def'],
$this->callMethod(
$this->_oModel,
'getExportGroups'
)
);
}
/**
* @covers \D3\DataWizard\Application\Model\Configuration::getActionsByGroup()
* @test
* @throws ReflectionException
*/
public function canGetActionsByGroup()
{
$actionList = ['abc' => '123', 'def' => '456'];
$this->setValue(
$this->_oModel,
'actions',
$actionList
);
$this->assertSame(
'456',
$this->callMethod(
$this->_oModel,
'getActionsByGroup',
['def']
)
);
}
/**
* @covers \D3\DataWizard\Application\Model\Configuration::getExportsByGroup()
* @test
* @throws ReflectionException
*/
public function canGetExportsByGroup()
{
$exportList = ['abc' => '123', 'def' => '456'];
$this->setValue(
$this->_oModel,
'exports',
$exportList
);
$this->assertSame(
'456',
$this->callMethod(
$this->_oModel,
'getExportsByGroup',
['def']
)
);
}
/**
* @covers \D3\DataWizard\Application\Model\Configuration::getAllActions()
* @test
* @throws ReflectionException
*/
public function canGetAllActions()
{
/** @var Configuration|MockObject $modelMock */
$modelMock = $this->getMockBuilder(Configuration::class)
->onlyMethods([
'getActionGroups',
'getActionsByGroup'
])
->getMock();
$modelMock->expects($this->once())->method('getActionGroups')->willReturn(['123', '456']);
$modelMock->expects($this->exactly(2))->method('getActionsByGroup')->willReturnOnConsecutiveCalls(
['123', '456'],
['789', '012']
);
$this->_oModel = $modelMock;
$this->assertSame(
['123','456', '789', '012'],
$this->callMethod(
$this->_oModel,
'getAllActions'
)
);
}
/**
* @covers \D3\DataWizard\Application\Model\Configuration::getAllExports()
* @test
* @throws ReflectionException
*/
public function canGetAllExports()
{
/** @var Configuration|MockObject $modelMock */
$modelMock = $this->getMockBuilder(Configuration::class)
->onlyMethods([
'getExportGroups',
'getExportsByGroup'
])
->getMock();
$modelMock->expects($this->once())->method('getExportGroups')->willReturn(['123', '456']);
$modelMock->expects($this->exactly(2))->method('getExportsByGroup')->willReturnOnConsecutiveCalls(
['123', '456'],
['789', '012']
);
$this->_oModel = $modelMock;
$this->assertSame(
['123', '456', '789', '012'],
$this->callMethod(
$this->_oModel,
'getAllExports'
)
);
}
/**
* @covers \D3\DataWizard\Application\Model\Configuration::getActionById()
* @test
* @throws ReflectionException
* @dataProvider canGetActionByIdDataProvider
*/
public function canGetActionById($id, $throwException)
{
$expected = oxNew(d3TestAction::class);
/** @var Configuration|MockObject $modelMock */
$modelMock = $this->getMockBuilder(Configuration::class)
->onlyMethods(['getAllActions'])
->getMock();
$modelMock->expects($this->once())->method('getAllActions')->willReturn(['123' => oxNew(d3TestAction::class), '456' => $expected]);
$this->_oModel = $modelMock;
if ($throwException) {
$this->expectException(DataWizardException::class);
}
$return = $this->callMethod(
$this->_oModel,
'getActionById',
[$id]
);
if (!$throwException) {
$this->assertSame(
$expected,
$return
);
}
}
/**
* @covers \D3\DataWizard\Application\Model\Configuration::getExportById()
* @test
* @throws ReflectionException
* @dataProvider canGetActionByIdDataProvider
*/
public function canGetExportById($id, $throwException)
{
$expected = oxNew(d3TestExport::class);
/** @var Configuration|MockObject $modelMock */
$modelMock = $this->getMockBuilder(Configuration::class)
->onlyMethods(['getAllExports'])
->getMock();
$modelMock->expects($this->once())->method('getAllExports')->willReturn(['123' => oxNew(d3TestExport::class), '456' => $expected]);
$this->_oModel = $modelMock;
if ($throwException) {
$this->expectException(DataWizardException::class);
}
$return = $this->callMethod(
$this->_oModel,
'getExportById',
[$id]
);
if (!$throwException) {
$this->assertSame(
$expected,
$return
);
}
}
/**
* @return array[]
*/
public function canGetActionByIdDataProvider(): array
{
return [
'unset id' => ['987', true],
'set id' => ['456', false],
];
}
}

View File

@ -0,0 +1,78 @@
<?php
/**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* https://www.d3data.de
*
* @copyright (C) D3 Data Development (Inh. Thomas Dartsch)
* @author D3 Data Development - Daniel Seifert <info@shopmodule.com>
* @link https://www.oxidmodule.com
*/
declare(strict_types=1);
namespace D3\DataWizard\tests\unit\Application\Model\Exceptions;
use D3\DataWizard\Application\Model\Exceptions\DebugException;
use D3\ModCfg\Tests\unit\d3ModCfgUnitTestCase;
use Exception;
use PHPUnit\Framework\MockObject\MockObject;
use ReflectionException;
class DebugExceptionTest extends d3ModCfgUnitTestCase
{
/** @var DebugException */
protected $_oModel;
/**
* @covers \D3\DataWizard\Application\Model\Exceptions\DebugException::__construct
* @test
* @throws ReflectionException
*/
public function canConstruct()
{
$code = '500';
$exception = oxNew( Exception::class);
/** @var DebugException|MockObject $modelMock */
$modelMock = $this->getMockBuilder(DebugException::class)
->disableOriginalConstructor()
->getMock();
$this->_oModel = $modelMock;
$this->callMethod(
$this->_oModel,
'__construct',
['testMessage', $code, $exception]
);
$this->assertStringContainsString(
'DEBUG',
$this->callMethod(
$this->_oModel,
'getMessage'
)
);
$this->assertEquals(
$code,
$this->callMethod(
$this->_oModel,
'getCode'
)
);
$this->assertSame(
$exception,
$this->callMethod(
$this->_oModel,
'getPrevious'
)
);
}
}

View File

@ -0,0 +1,78 @@
<?php
/**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* https://www.d3data.de
*
* @copyright (C) D3 Data Development (Inh. Thomas Dartsch)
* @author D3 Data Development - Daniel Seifert <info@shopmodule.com>
* @link https://www.oxidmodule.com
*/
declare(strict_types=1);
namespace D3\DataWizard\tests\unit\Application\Model\Exceptions;
use D3\DataWizard\Application\Model\Exceptions\ExportFileException;
use D3\ModCfg\Tests\unit\d3ModCfgUnitTestCase;
use Exception;
use PHPUnit\Framework\MockObject\MockObject;
use ReflectionException;
class ExportFileExceptionTest extends d3ModCfgUnitTestCase
{
/** @var ExportFileException */
protected $_oModel;
/**
* @covers \D3\DataWizard\Application\Model\Exceptions\ExportFileException::__construct
* @test
* @throws ReflectionException
*/
public function canConstruct()
{
$code = '500';
$exception = oxNew( Exception::class);
/** @var ExportFileException|MockObject $modelMock */
$modelMock = $this->getMockBuilder(ExportFileException::class)
->disableOriginalConstructor()
->getMock();
$this->_oModel = $modelMock;
$this->callMethod(
$this->_oModel,
'__construct',
['testMessage', $code, $exception]
);
$this->assertStringContainsString(
'EXPORTFILEERROR',
$this->callMethod(
$this->_oModel,
'getMessage'
)
);
$this->assertEquals(
$code,
$this->callMethod(
$this->_oModel,
'getCode'
)
);
$this->assertSame(
$exception,
$this->callMethod(
$this->_oModel,
'getPrevious'
)
);
}
}

View File

@ -0,0 +1,97 @@
<?php
/**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* https://www.d3data.de
*
* @copyright (C) D3 Data Development (Inh. Thomas Dartsch)
* @author D3 Data Development - Daniel Seifert <info@shopmodule.com>
* @link https://www.oxidmodule.com
*/
declare(strict_types=1);
namespace D3\DataWizard\tests\unit\Application\Model\Exceptions;
use D3\DataWizard\Application\Model\Exceptions\InputUnvalidException;
use D3\DataWizard\Application\Model\ExportBase;
use D3\DataWizard\tests\tools\d3TestExport;
use D3\ModCfg\Tests\unit\d3ModCfgUnitTestCase;
use Exception;
use FormManager\Inputs\Number;
use PHPUnit\Framework\MockObject\MockObject;
use ReflectionException;
class InputUnvalidExceptionTest extends d3ModCfgUnitTestCase
{
/** @var InputUnvalidException */
protected $_oModel;
/**
* @covers \D3\DataWizard\Application\Model\Exceptions\InputUnvalidException::__construct
* @test
* @throws ReflectionException
*/
public function canConstruct()
{
$code = '500';
$exception = oxNew( Exception::class);
$invalidField = new Number(null, [
'required' => true,
'min' => 1,
'max' => 10,
'step' => 5,
]);
$invalidField
->setValue(20)
->setErrorMessages(['errorMsgs']);
/** @var ExportBase|MockObject $taskMock */
$taskMock = $this->getMockBuilder(d3TestExport::class)
->onlyMethods(['getTitle'])
->getMock();
$taskMock->expects($this->atLeastOnce())->method('getTitle')->willReturn('testTitle');
/** @var InputUnvalidException|MockObject $modelMock */
$modelMock = $this->getMockBuilder(InputUnvalidException::class)
->disableOriginalConstructor()
->getMock();
$this->_oModel = $modelMock;
$this->callMethod(
$this->_oModel,
'__construct',
[$taskMock, $invalidField, $code, $exception]
);
$this->assertRegExp(
'/^testTitle\s-\s*->\s.*\sless\s/m',
$this->callMethod(
$this->_oModel,
'getMessage'
)
);
$this->assertEquals(
$code,
$this->callMethod(
$this->_oModel,
'getCode'
)
);
$this->assertSame(
$exception,
$this->callMethod(
$this->_oModel,
'getPrevious'
)
);
}
}

View File

@ -0,0 +1,78 @@
<?php
/**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* https://www.d3data.de
*
* @copyright (C) D3 Data Development (Inh. Thomas Dartsch)
* @author D3 Data Development - Daniel Seifert <info@shopmodule.com>
* @link https://www.oxidmodule.com
*/
declare(strict_types=1);
namespace D3\DataWizard\tests\unit\Application\Model\Exceptions;
use D3\DataWizard\Application\Model\Exceptions\NoSuitableRendererException;
use D3\ModCfg\Tests\unit\d3ModCfgUnitTestCase;
use Exception;
use PHPUnit\Framework\MockObject\MockObject;
use ReflectionException;
class NoSuitableRendererExceptionTest extends d3ModCfgUnitTestCase
{
/** @var NoSuitableRendererException */
protected $_oModel;
/**
* @covers \D3\DataWizard\Application\Model\Exceptions\NoSuitableRendererException::__construct
* @test
* @throws ReflectionException
*/
public function canConstruct()
{
$code = '500';
$exception = oxNew( Exception::class);
/** @var NoSuitableRendererException|MockObject $modelMock */
$modelMock = $this->getMockBuilder(NoSuitableRendererException::class)
->disableOriginalConstructor()
->getMock();
$this->_oModel = $modelMock;
$this->callMethod(
$this->_oModel,
'__construct',
['testMessage', $code, $exception]
);
$this->assertStringContainsString(
'NOSUITABLERENDERER',
$this->callMethod(
$this->_oModel,
'getMessage'
)
);
$this->assertEquals(
$code,
$this->callMethod(
$this->_oModel,
'getCode'
)
);
$this->assertSame(
$exception,
$this->callMethod(
$this->_oModel,
'getPrevious'
)
);
}
}

View File

@ -0,0 +1,86 @@
<?php
/**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* https://www.d3data.de
*
* @copyright (C) D3 Data Development (Inh. Thomas Dartsch)
* @author D3 Data Development - Daniel Seifert <info@shopmodule.com>
* @link https://www.oxidmodule.com
*/
declare(strict_types=1);
namespace D3\DataWizard\tests\unit\Application\Model\Exceptions;
use D3\DataWizard\Application\Model\Exceptions\TaskException;
use D3\DataWizard\Application\Model\ExportBase;
use D3\DataWizard\tests\tools\d3TestExport;
use D3\ModCfg\Tests\unit\d3ModCfgUnitTestCase;
use Exception;
use PHPUnit\Framework\MockObject\MockObject;
use ReflectionException;
class TaskExceptionTest extends d3ModCfgUnitTestCase
{
/** @var TaskException */
protected $_oModel;
/**
* @covers \D3\DataWizard\Application\Model\Exceptions\TaskException::__construct
* @test
* @throws ReflectionException
*/
public function canConstruct()
{
$code = '500';
$exception = oxNew( Exception::class);
/** @var ExportBase|MockObject $taskMock */
$taskMock = $this->getMockBuilder(d3TestExport::class)
->onlyMethods(['getTitle'])
->getMock();
$taskMock->expects($this->atLeastOnce())->method('getTitle')->willReturn('testTitle');
/** @var TaskException|MockObject $modelMock */
$modelMock = $this->getMockBuilder(TaskException::class)
->disableOriginalConstructor()
->getMock();
$this->_oModel = $modelMock;
$this->callMethod(
$this->_oModel,
'__construct',
[$taskMock, 'testMessage', $code, $exception]
);
$this->assertSame(
'testTitle - testMessage',
$this->callMethod(
$this->_oModel,
'getMessage'
)
);
$this->assertEquals(
$code,
$this->callMethod(
$this->_oModel,
'getCode'
)
);
$this->assertSame(
$exception,
$this->callMethod(
$this->_oModel,
'getPrevious'
)
);
}
}

View File

@ -0,0 +1,607 @@
<?php
/**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* https://www.d3data.de
*
* @copyright (C) D3 Data Development (Inh. Thomas Dartsch)
* @author D3 Data Development - Daniel Seifert <info@shopmodule.com>
* @link https://www.oxidmodule.com
*/
declare(strict_types=1);
namespace D3\DataWizard\tests\unit\Application\Model;
use D3\DataWizard\Application\Model\Exceptions\ExportFileException;
use D3\DataWizard\Application\Model\Exceptions\TaskException;
use D3\DataWizard\Application\Model\ExportRenderer\Csv;
use D3\DataWizard\Application\Model\ExportRenderer\RendererBridge;
use D3\DataWizard\Application\Model\ExportRenderer\RendererInterface;
use D3\DataWizard\tests\tools\d3TestExport;
use D3\ModCfg\Application\Model\d3filesystem;
use D3\ModCfg\Tests\unit\d3ModCfgUnitTestCase;
use FormManager\Inputs\Hidden;
use FormManager\Inputs\Number;
use FormManager\Inputs\Radio;
use OxidEsales\Eshop\Core\Database\Adapter\Doctrine\Database;
use OxidEsales\Eshop\Core\Exception\StandardException;
use PHPUnit\Framework\MockObject\MockObject;
use ReflectionException;
class ExportBaseTest extends d3ModCfgUnitTestCase
{
/** @var d3TestExport */
protected $_oModel;
public function setUp() : void
{
parent::setUp();
$this->_oModel = oxNew(d3TestExport::class);
}
public function tearDown() : void
{
parent::tearDown();
unset($this->_oModel);
}
/**
* @covers \D3\DataWizard\Application\Model\ExportBase::getDescription
* @test
* @throws ReflectionException
*/
public function canGetDescription()
{
$this->assertIsString(
$this->callMethod(
$this->_oModel,
'getDescription'
)
);
}
/**
* @covers \D3\DataWizard\Application\Model\ExportBase::getButtonText
* @test
* @throws ReflectionException
*/
public function canGetButtonText()
{
$this->assertIsString(
$this->callMethod(
$this->_oModel,
'getButtonText'
)
);
}
/**
* @covers \D3\DataWizard\Application\Model\ExportBase::hasFormElements
* @test
* @throws ReflectionException
* @dataProvider canGetHasFormElementsDataProvider
*/
public function canGetHasFormElements($formElements, $expected)
{
$this->setValue($this->_oModel, 'formElements', $formElements);
$this->assertSame(
$expected,
$this->callMethod(
$this->_oModel,
'hasFormElements'
)
);
}
public function canGetHasFormElementsDataProvider(): array
{
return [
'hasFormElements' => [['abc', 'def'], true],
'hasNoFormElements' => [[], false],
];
}
/**
* @covers \D3\DataWizard\Application\Model\ExportBase::getFormElements
* @test
* @throws ReflectionException
* @dataProvider canGetHasFormElementsDataProvider
*/
public function canGetFormElements($formElements)
{
$this->setValue($this->_oModel, 'formElements', $formElements);
$this->assertSame(
$formElements,
$this->callMethod(
$this->_oModel,
'getFormElements'
)
);
}
/**
* @covers \D3\DataWizard\Application\Model\ExportBase::registerFormElement
* @test
* @throws ReflectionException
* @dataProvider canRegisterFormElementDataProvider
*/
public function canRegisterFormElement($inputClass)
{
$oldCount = count($this->getValue($this->_oModel, 'formElements'));
/** @var Radio|MockObject $inputMock */
$inputMock = $this->getMockBuilder($inputClass)
->onlyMethods([
'setTemplate',
'setAttribute'
])
->getMock();
$inputMock->expects($this->atLeastOnce())->method('setTemplate');
$inputMock->expects($this->atLeastOnce())->method('setAttribute');
$this->callMethod(
$this->_oModel,
'registerFormElement',
[$inputMock]
);
$newCount = count($this->getValue($this->_oModel, 'formElements'));
$this->assertGreaterThan($oldCount, $newCount);
}
/**
* @return \string[][]
*/
public function canRegisterFormElementDataProvider(): array
{
return [
'Radio' => [Radio::class],
'Checkbox' => [Radio::class],
'Hidden' => [Hidden::class]
];
}
/**
* @covers \D3\DataWizard\Application\Model\ExportBase::run
* @test
* @throws ReflectionException
*/
public function canRunWithoutFormElements()
{
$format = 'myFormat';
$path = 'myPath';
/** @var d3TestExport|MockObject $modelMock */
$modelMock = $this->getMockBuilder(d3TestExport::class)
->onlyMethods([
'hasFormElements',
'executeExport'
])
->getMock();
$modelMock->expects($this->atLeastOnce())->method('hasFormElements')->willReturn(false);
$modelMock->expects($this->atLeastOnce())->method('executeExport')->with($format, $path)->willReturn('some content');
$this->_oModel = $modelMock;
$this->callMethod(
$this->_oModel,
'run',
[$format, $path]
);
}
/**
* @covers \D3\DataWizard\Application\Model\ExportBase::run
* @test
* @throws ReflectionException
* @dataProvider canRunWithFormElementsDataProvider
*/
public function canRunWithFormElements($elements, $blThrowException)
{
$format = 'myFormat';
$path = 'myPath';
$expectedException = oxNew(StandardException::class);
$modelMock = $this->getMockBuilder(d3TestExport::class)
->onlyMethods([
'hasFormElements',
'executeExport',
'getFormElements'
])
->getMock();
$modelMock->expects($this->atLeastOnce())->method('hasFormElements')->willReturn(true);
$modelMock->expects($this->exactly((int) !$blThrowException))->method('executeExport')->with($format, $path)->willReturn('some content');
$modelMock->expects($this->atLeastOnce())->method('getFormElements')->willReturn($elements);
$this->_oModel = $modelMock;
if ($blThrowException) {
$this->expectException(get_class($expectedException));
}
$this->callMethod(
$this->_oModel,
'run',
[$format, $path]
);
}
/**
* @return array[]
*/
public function canRunWithFormElementsDataProvider(): array
{
/** @var Radio|MockObject $validMock */
$validMock = $this->getMockBuilder(Radio::class)
->onlyMethods(['isValid'])
->getMock();
$validMock->expects($this->atLeastOnce())->method('isValid')->willReturn(true);
$invalidField = new Number(null, [
'required' => true,
'min' => 1,
'max' => 10,
'step' => 5,
]);
$invalidField
->setValue(20)
->setErrorMessages(['errorMsgs']);
return [
'validElements' => [[$validMock, $validMock], false],
'invalidElements' => [[$validMock, $invalidField], true]
];
}
/**
* @covers \D3\DataWizard\Application\Model\ExportBase::executeExport
* @test
* @throws ReflectionException
* @dataProvider canExecuteExportDataProvider
*/
public function canExecuteExport($path, $throwsException)
{
/** @var d3filesystem|MockObject $fsMock */
$fsMock = $this->getMockBuilder(d3filesystem::class)
->onlyMethods([
'startDirectDownload',
'filterFilename',
'trailingslashit',
'createFile'
])
->getMock();
$fsMock->expects($this->exactly((int) !isset($path)))->method('startDirectDownload')->willReturn(true);
$fsMock->method('filterFilename')->willReturnArgument(0);
$fsMock->expects($this->exactly((int) isset($path)))->method('trailingslashit')->willReturnArgument(0);
$fsMock->expects($this->exactly((int) isset($path)))->method('createFile')->willReturn((bool) !$throwsException);
/** @var d3TestExport|MockObject $modelMock */
$modelMock = $this->getMockBuilder(d3TestExport::class)
->onlyMethods([
'getQuery',
'getExportData',
'renderContent',
'getFileSystem',
'getExportFileName'
])
->getMock();
$modelMock->expects($this->atLeastOnce())->method('getQuery')->willReturn(['SELECT 1', ['arg1', 'arg2']]);
$modelMock->expects($this->atLeastOnce())->method('getExportData')->willReturn([[1, 2], ['field1', 'field2']]);
$modelMock->expects($this->atLeastOnce())->method('renderContent')->willReturn('some content');
$modelMock->expects($this->atLeastOnce())->method('getFileSystem')->willReturn($fsMock);
$modelMock->expects($this->atLeastOnce())->method('getExportFileName')->willReturn('exportFileName');
$this->_oModel = $modelMock;
if ($path && $throwsException) {
$this->expectException(ExportFileException::class);
}
$this->callMethod(
$this->_oModel,
'executeExport',
['CSV', $path]
);
}
/**
* @return array[]
*/
public function canExecuteExportDataProvider(): array
{
return [
'unable to create path for saving file' => ['myPath', true],
'can create path for saving file' => ['myPath', false],
'no path for download' => [null, false],
];
}
/**
* @covers \D3\DataWizard\Application\Model\ExportBase::d3GetDb
* @test
* @throws ReflectionException
*/
public function canGetDb()
{
$this->assertInstanceOf(
Database::class,
$this->callMethod(
$this->_oModel,
'd3GetDb'
)
);
}
/**
* @covers \D3\DataWizard\Application\Model\ExportBase::getFileSystem
* @test
* @throws ReflectionException
*/
public function canGetFileSystem()
{
$this->assertInstanceOf(
d3filesystem::class,
$this->callMethod(
$this->_oModel,
'getFileSystem'
)
);
}
/**
* @covers \D3\DataWizard\Application\Model\ExportBase::getRenderer
* @test
* @throws ReflectionException
*/
public function canGetRenderer()
{
/** @var RendererInterface|MockObject $rendererMock */
$rendererMock = $this->getMockBuilder(Csv::class)
->getMock();
/** @var RendererBridge|MockObject $rendererBridgeMock */
$rendererBridgeMock = $this->getMockBuilder(RendererBridge::class)
->onlyMethods(['getRenderer'])
->getMock();
$rendererBridgeMock->expects($this->atLeastOnce())->method('getRenderer')->willReturn($rendererMock);
/** @var d3TestExport|MockObject $modelMock */
$modelMock = $this->getMockBuilder(d3TestExport::class)
->onlyMethods([
'getRendererBridge'
])
->getMock();
$modelMock->expects($this->atLeastOnce())->method('getRendererBridge')->willReturn($rendererBridgeMock);
$this->_oModel = $modelMock;
$this->assertSame(
$rendererMock,
$this->callMethod(
$this->_oModel,
'getRenderer',
[RendererBridge::FORMAT_CSV]
)
);
}
/**
* @covers \D3\DataWizard\Application\Model\ExportBase::getRendererBridge
* @test
* @throws ReflectionException
*/
public function canGetRendererBridge()
{
$this->assertInstanceOf(
RendererBridge::class,
$this->callMethod(
$this->_oModel,
'getRendererBridge'
)
);
}
/**
* @covers \D3\DataWizard\Application\Model\ExportBase::getFileExtension
* @test
* @throws ReflectionException
*/
public function canGetFileExtension()
{
$format = RendererBridge::FORMAT_CSV;
$expected = 'myFileExtension';
/** @var RendererInterface|MockObject $rendererMock */
$rendererMock = $this->getMockBuilder(Csv::class)
->onlyMethods(['getFileExtension'])
->getMock();
$rendererMock->expects($this->atLeastOnce())->method('getFileExtension')->willReturn($expected);
/** @var d3TestExport|MockObject $modelMock */
$modelMock = $this->getMockBuilder(d3TestExport::class)
->onlyMethods([
'getRenderer'
])
->getMock();
$modelMock->expects($this->atLeastOnce())->method('getRenderer')->with($format)->willReturn($rendererMock);
$this->_oModel = $modelMock;
$this->assertSame(
$expected,
$this->callMethod(
$this->_oModel,
'getFileExtension',
[$format]
)
);
}
/**
* @covers \D3\DataWizard\Application\Model\ExportBase::renderContent
* @test
* @throws ReflectionException
*/
public function canRenderContent()
{
$rows = ['row1', 'row2'];
$fieldnames = ['fieldname1', 'fieldname2'];
$format = RendererBridge::FORMAT_CSV;
$expected = 'myContent';
/** @var RendererInterface|MockObject $rendererMock */
$rendererMock = $this->getMockBuilder(Csv::class)
->onlyMethods(['getContent'])
->getMock();
$rendererMock->expects($this->atLeastOnce())->method('getContent')->with($rows, $fieldnames)->willReturn($expected);
/** @var d3TestExport|MockObject $modelMock */
$modelMock = $this->getMockBuilder(d3TestExport::class)
->onlyMethods([
'getRenderer'
])
->getMock();
$modelMock->expects($this->atLeastOnce())->method('getRenderer')->with($format)->willReturn($rendererMock);
$this->_oModel = $modelMock;
$this->assertSame(
$expected,
$this->callMethod(
$this->_oModel,
'renderContent',
[$rows, $fieldnames, $format]
)
);
}
/**
* @covers \D3\DataWizard\Application\Model\ExportBase::getExportFilenameBase
* @test
* @throws ReflectionException
*/
public function canGetExportFilenameBase()
{
/** @var d3TestExport|MockObject $modelMock */
$modelMock = $this->getMockBuilder(d3TestExport::class)
->onlyMethods([
'getTitle'
])
->getMock();
$modelMock->expects($this->atLeastOnce())->method('getTitle')->willReturn('someTitle');
$this->_oModel = $modelMock;
$this->callMethod(
$this->_oModel,
'getExportFilenameBase'
);
}
/**
* @covers \D3\DataWizard\Application\Model\ExportBase::getExportFileName
* @test
* @throws ReflectionException
*/
public function canGetExportFileName()
{
$format = RendererBridge::FORMAT_CSV;
/** @var d3TestExport|MockObject $modelMock */
$modelMock = $this->getMockBuilder(d3TestExport::class)
->onlyMethods([
'getExportFilenameBase',
'getFileExtension'
])
->getMock();
$modelMock->expects($this->atLeastOnce())->method('getExportFilenameBase')->willReturn('base');
$modelMock->expects($this->atLeastOnce())->method('getFileExtension')->with($format)->willReturn('extension');
$this->_oModel = $modelMock;
$this->assertRegExp(
'/^base_(\d{4})-(\d{2})-(\d{2})_(\d{2})-(\d{2})-(\d{2})\.extension$/m',
$this->callMethod(
$this->_oModel,
'getExportFileName',
[$format]
)
);
}
/**
* @covers \D3\DataWizard\Application\Model\ExportBase::getExportData
* @test
* @throws ReflectionException
* @dataProvider canGetExportDataDataProvider
*/
public function canGetExportData($query, $throwsException, $dbResult)
{
/** @var Database|MockObject $dbMock */
$dbMock = $this->getMockBuilder(Database::class)
->onlyMethods(['getAll'])
->getMock();
$dbMock->expects($this->exactly((int) !$throwsException))->method('getAll')->willReturn($dbResult);
/** @var d3TestExport|MockObject $modelMock */
$modelMock = $this->getMockBuilder(d3TestExport::class)
->onlyMethods([
'd3GetDb'
])
->getMock();
$modelMock->expects($this->exactly((int) !$throwsException))->method('d3GetDb')->willReturn($dbMock);
$this->_oModel = $modelMock;
try {
$result = $this->callMethod(
$this->_oModel,
'getExportData',
[[$query], ['param1', 'param2']]
);
$this->assertSame(
[
[
[
'field1' => 'content1',
'field2' => 'content2'
]
],
[
'field1',
'field2'
]
],
$result
);
} catch (TaskException $e) {
if ($throwsException) {
$this->assertStringContainsString('NOEXPORTSELECT', $e->getMessage());
} elseif (!count($dbResult)) {
$this->assertStringContainsString('kein Inhalt', $e->getMessage());
}
}
}
/**
* @return array[]
*/
public function canGetExportDataDataProvider(): array
{
return [
'not SELECT throws exception' => [' UPDATE 1', true, []],
'empty SELECT' => [' SELECT 1', false, []],
'fulfilled SELECT' => [' SELECT 1', false, [['field1' => 'content1', 'field2' => 'content2']]],
];
}
}

View File

@ -0,0 +1,177 @@
<?php
/**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* https://www.d3data.de
*
* @copyright (C) D3 Data Development (Inh. Thomas Dartsch)
* @author D3 Data Development - Daniel Seifert <info@shopmodule.com>
* @link https://www.oxidmodule.com
*/
declare(strict_types=1);
namespace D3\DataWizard\tests\unit\Application\Model\ExportRenderer;
use D3\DataWizard\Application\Model\Exceptions\RenderException;
use D3\DataWizard\Application\Model\ExportRenderer\Csv;
use League\Csv\Exception;
use League\Csv\Writer;
use OxidEsales\Eshop\Core\Config;
use OxidEsales\Eshop\Core\Registry;
use PHPUnit\Framework\MockObject\MockObject;
use ReflectionException;
class CsvTest extends ExportRendererTest
{
/** @var Csv */
protected $_oModel;
public function setUp() : void
{
parent::setUp();
$this->_oModel = oxNew(Csv::class);
}
/**
* @covers \D3\DataWizard\Application\Model\ExportRenderer\Csv::getContent
* @test
* @throws ReflectionException
* @dataProvider canGetContentDataProvider
*/
public function canGetContent($blThrowException)
{
$expected = 'expectedReturn';
$fieldList = ['field1', 'field2'];
$valueList = ['value1', 'value2'];
/** @var Writer|MockObject $csvMock */
$csvMockBuilder = $this->getMockBuilder( Writer::class);
$csvMockBuilder->disableOriginalConstructor();
$onlyMethods = ['__toString', 'insertOne', 'insertAll'];
$csvMockBuilder->onlyMethods($onlyMethods);
$csvMock = $csvMockBuilder->getMock();
$csvMock->method('insertOne')->willReturn(1);
$csvMock->method('insertAll')->willReturn(1);
if ($blThrowException) {
$csvMock->expects($this->atLeastOnce())->method('__toString')->willThrowException(oxNew(Exception::class));
$this->expectException(RenderException::class);
} else {
$csvMock->expects($this->atLeastOnce())->method('__toString')->willReturn($expected);
}
/** @var Csv|MockObject $modelMock */
$modelMock = $this->getMockBuilder(Csv::class)
->onlyMethods(['getCsv'])
->getMock();
$modelMock->expects($this->atLeastOnce())->method('getCsv')->willReturn($csvMock);
$this->_oModel = $modelMock;
$this->assertSame(
$expected,
$this->callMethod(
$this->_oModel,
'getContent',
[$valueList, $fieldList]
)
);
}
/**
* @return array
*/
public function canGetContentDataProvider(): array
{
return [
'exception' => [true],
'no exception' => [false]
];
}
/**
* @covers \D3\DataWizard\Application\Model\ExportRenderer\Csv::getCsv
* @test
* @throws ReflectionException
*/
public function canGetCsv()
{
$this->assertInstanceOf(
Writer::class,
$this->callMethod(
$this->_oModel,
'getCsv'
)
);
}
/**
* @covers \D3\DataWizard\Application\Model\ExportRenderer\Csv::getCsv
* @test
* @throws ReflectionException
*/
public function canGetCsvNoSettings()
{
/** @var Config|MockObject $configMock */
$configMock = $this->getMockBuilder(Config::class)
->onlyMethods(['getConfigParam'])
->getMock();
$configMock->expects($this->atLeastOnce())->method('getConfigParam')->willReturnCallback(
function ($argName) {
switch ($argName) {
case 'sGiCsvFieldEncloser':
case 'sCSVSign':
return false;
default:
return Registry::getConfig()->getConfigParam($argName);
}
}
);
$modelMock = $this->getMockBuilder(Csv::class)
->onlyMethods(['d3GetConfig'])
->getMock();
$modelMock->method('d3GetConfig')->willReturn($configMock);
$this->_oModel = $modelMock;
$csv = $this->callMethod(
$this->_oModel,
'getCsv'
);
$this->assertInstanceOf(
Writer::class,
$csv
);
$this->assertSame(
'"',
$csv->getEnclosure()
);
$this->assertSame(
';',
$csv->getDelimiter()
);
}
/**
* @covers \D3\DataWizard\Application\Model\ExportRenderer\Csv::d3GetConfig
* @test
* @throws ReflectionException
*/
public function canGetConfig()
{
$this->assertInstanceOf(
Config::class,
$this->callMethod(
$this->_oModel,
'd3GetConfig'
)
);
}
}

View File

@ -0,0 +1,66 @@
<?php
/**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* https://www.d3data.de
*
* @copyright (C) D3 Data Development (Inh. Thomas Dartsch)
* @author D3 Data Development - Daniel Seifert <info@shopmodule.com>
* @link https://www.oxidmodule.com
*/
namespace D3\DataWizard\tests\unit\Application\Model\ExportRenderer;
use D3\DataWizard\Application\Model\ExportRenderer\RendererInterface;
use D3\ModCfg\Tests\unit\d3ModCfgUnitTestCase;
use ReflectionException;
abstract class ExportRendererTest extends d3ModCfgUnitTestCase
{
/** @var RendererInterface */
protected $_oModel;
public function tearDown() : void
{
parent::tearDown();
unset($this->_oModel);
}
/**
* @covers \D3\DataWizard\Application\Model\ExportRenderer\Csv::getFileExtension
* @covers \D3\DataWizard\Application\Model\ExportRenderer\Json::getFileExtension
* @covers \D3\DataWizard\Application\Model\ExportRenderer\Pretty::getFileExtension
* @test
* @throws ReflectionException
*/
public function canGetFileExtension()
{
$this->assertRegExp(
"/^[a-z0-9._-]*$/i",
$this->callMethod(
$this->_oModel,
'getFileExtension'
)
);
}
/**
* @covers \D3\DataWizard\Application\Model\ExportRenderer\Csv::getTitleTranslationId
* @covers \D3\DataWizard\Application\Model\ExportRenderer\Json::getTitleTranslationId
* @covers \D3\DataWizard\Application\Model\ExportRenderer\Pretty::getTitleTranslationId
* @test
* @throws ReflectionException
*/
public function canGetTitleTranslationId()
{
$this->assertIsString(
$this->callMethod(
$this->_oModel,
'getTitleTranslationId'
)
);
}
}

View File

@ -0,0 +1,67 @@
<?php
/**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* https://www.d3data.de
*
* @copyright (C) D3 Data Development (Inh. Thomas Dartsch)
* @author D3 Data Development - Daniel Seifert <info@shopmodule.com>
* @link https://www.oxidmodule.com
*/
declare(strict_types=1);
namespace D3\DataWizard\tests\unit\Application\Model\ExportRenderer;
use D3\DataWizard\Application\Model\Exceptions\RenderException;
use D3\DataWizard\Application\Model\ExportRenderer\Json;
use ReflectionException;
class JsonTest extends ExportRendererTest
{
/** @var Json */
protected $_oModel;
public function setUp() : void
{
parent::setUp();
$this->_oModel = oxNew(Json::class);
}
/**
* @covers \D3\DataWizard\Application\Model\ExportRenderer\Json::getContent
* @test
* @throws ReflectionException
* @dataProvider canGetContentDataProvider
*/
public function canGetContent($valueList, $expectException)
{
$fieldList = ['field1', 'field2'];
if ($expectException) {
$this->expectException(RenderException::class);
}
$this->assertJson(
$this->callMethod(
$this->_oModel,
'getContent',
[$valueList, $fieldList]
)
);
}
/**
* @return \string[][]
*/
public function canGetContentDataProvider(): array
{
return [
'valid' => [['value1', 'value2'], false],
'invalid' => [["text" => "\xB1\x31"], true] // malformed UTF8 chars
];
}
}

View File

@ -0,0 +1,86 @@
<?php
/**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* https://www.d3data.de
*
* @copyright (C) D3 Data Development (Inh. Thomas Dartsch)
* @author D3 Data Development - Daniel Seifert <info@shopmodule.com>
* @link https://www.oxidmodule.com
*/
declare(strict_types=1);
namespace D3\DataWizard\tests\unit\Application\Model\ExportRenderer;
use D3\DataWizard\Application\Model\ExportRenderer\Pretty;
use MathieuViossat\Util\ArrayToTextTable;
use PHPUnit\Framework\MockObject\MockObject;
use ReflectionException;
class PrettyTest extends ExportRendererTest
{
/** @var Pretty */
protected $_oModel;
public function setUp() : void
{
parent::setUp();
$this->_oModel = oxNew(Pretty::class);
}
/**
* @covers \D3\DataWizard\Application\Model\ExportRenderer\Pretty::getContent
* @test
* @throws ReflectionException
*/
public function canGetContent()
{
$expected = 'expectedReturn';
$fieldList = ['field1', 'field2'];
$valueList = ['value1', 'value2'];
/** @var ArrayToTextTable|MockObject $csvMock */
$arrayToTextTableMock = $this->getMockBuilder(ArrayToTextTable::class)
->disableOriginalConstructor()
->onlyMethods(['getTable'])
->getMock();
$arrayToTextTableMock->expects($this->atLeastOnce())->method('getTable')->willReturn($expected);
/** @var Pretty|MockObject $modelMock */
$modelMock = $this->getMockBuilder(Pretty::class)
->onlyMethods(['getArrayToTextTableInstance'])
->getMock();
$modelMock->expects($this->atLeastOnce())->method('getArrayToTextTableInstance')->willReturn($arrayToTextTableMock);
$this->_oModel = $modelMock;
$this->assertSame(
$expected,
$this->callMethod(
$this->_oModel,
'getContent',
[$valueList, $fieldList]
)
);
}
/**
* @covers \D3\DataWizard\Application\Model\ExportRenderer\Pretty::getArrayToTextTableInstance
* @test
* @throws ReflectionException
*/
public function canGetArrayToTextTableInstance()
{
$this->assertInstanceOf(
ArrayToTextTable::class,
$this->callMethod(
$this->_oModel,
'getArrayToTextTableInstance',
[['field1', 'field2']]
)
);
}
}

View File

@ -0,0 +1,152 @@
<?php
/**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* https://www.d3data.de
*
* @copyright (C) D3 Data Development (Inh. Thomas Dartsch)
* @author D3 Data Development - Daniel Seifert <info@shopmodule.com>
* @link https://www.oxidmodule.com
*/
declare(strict_types=1);
namespace D3\DataWizard\tests\unit\Application\Model\ExportRenderer;
use D3\DataWizard\Application\Model\Exceptions\NoSuitableRendererException;
use D3\DataWizard\Application\Model\ExportRenderer\Csv;
use D3\DataWizard\Application\Model\ExportRenderer\Json;
use D3\DataWizard\Application\Model\ExportRenderer\Pretty;
use D3\DataWizard\Application\Model\ExportRenderer\RendererBridge;
use D3\DataWizard\Application\Model\ExportRenderer\RendererInterface;
use D3\ModCfg\Tests\unit\d3ModCfgUnitTestCase;
use PHPUnit\Framework\MockObject\MockObject;
use ReflectionException;
class RendererBridgeTest extends d3ModCfgUnitTestCase
{
/** @var RendererBridge */
protected $_oModel;
public function setUp() : void
{
parent::setUp();
$this->_oModel = oxNew(RendererBridge::class);
}
public function tearDown(): void
{
parent::tearDown();
unset($this->_oModel);
}
/**
* @covers \D3\DataWizard\Application\Model\ExportRenderer\RendererBridge::getRendererList
* @test
* @throws ReflectionException
*/
public function canGetRendererList()
{
$list = $this->callMethod(
$this->_oModel,
'getRendererList'
);
$this->assertIsArray($list);
$this->assertTrue((bool) count($list));
}
/**
* @covers \D3\DataWizard\Application\Model\ExportRenderer\RendererBridge::getTranslatedRendererIdList
* @test
* @throws ReflectionException
*/
public function canGetTranslatedRendererIdList()
{
$utlist = $this->callMethod(
$this->_oModel,
'getRendererList'
);
$list = $this->callMethod(
$this->_oModel,
'getTranslatedRendererIdList'
);
$this->assertIsArray($list);
$this->assertTrue((bool) count($list));
$this->assertSame(count($utlist), count($list));
}
/**
* @covers \D3\DataWizard\Application\Model\ExportRenderer\RendererBridge::translateRendererId
* @test
* @throws ReflectionException
*/
public function canTranslateRendererId()
{
$expected = "expectedTranslation";
/** @var RendererInterface|MockObject $renderMock */
$renderMock = $this->getMockBuilder(Pretty::class)
->onlyMethods(['getTitleTranslationId'])
->getMock();
$renderMock->expects($this->atLeastOnce())->method('getTitleTranslationId')->willReturn($expected);
$this->callMethod(
$this->_oModel,
'translateRendererId',
[$renderMock]
);
}
/**
* @covers \D3\DataWizard\Application\Model\ExportRenderer\RendererBridge::getRenderer
* @test
* @param $format
* @param $blThrowException
* @throws ReflectionException
* @dataProvider canGetRendererDataProvider
*/
public function canGetRenderer($format, $blThrowException)
{
/** @var RendererBridge|MockObject $modelMock */
$modelMock = $this->getMockBuilder(RendererBridge::class)
->onlyMethods(['getRendererList'])
->getMock();
$modelMock->expects($this->atLeastOnce())->method('getRendererList')->willReturn(
[
'CSV' => $this->getMockBuilder(Csv::class)->getMock(),
'Pretty' => $this->getMockBuilder(Pretty::class)->getMock(),
'JSON' => $this->getMockBuilder(Json::class)->getMock()
]
);
$this->_oModel = $modelMock;
if ($blThrowException) {
$this->expectException(NoSuitableRendererException::class);
}
$this->callMethod(
$this->_oModel,
'getRenderer',
[$format]
);
}
/**
* @return array
*/
public function canGetRendererDataProvider(): array
{
return [
'existing renderer'=> [RendererBridge::FORMAT_JSON, false],
'unknown renderer'=> ['unknownRenderer', true]
];
}
}