Merge pull request #29 from DanielSiepmann/feature/configure-allowed-document-types

Feature/configure allowed document types
This commit is contained in:
Daniel Siepmann 2016-12-15 14:35:24 +01:00 committed by GitHub
commit 1eaac95a4c
24 changed files with 531 additions and 357 deletions

View file

@ -41,7 +41,7 @@ services:
install: make install install: make install
script: make Tests script: make functionalTests
after_script: after_script:
- make uploadCodeCoverage - make uploadCodeCoverage

View file

@ -21,6 +21,7 @@ namespace Leonmrni\SearchCore\Command;
*/ */
use Leonmrni\SearchCore\Domain\Index\IndexerFactory; use Leonmrni\SearchCore\Domain\Index\IndexerFactory;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Mvc\Controller\CommandController; use TYPO3\CMS\Extbase\Mvc\Controller\CommandController;
/** /**
@ -33,6 +34,12 @@ class IndexCommandController extends CommandController
*/ */
protected $indexerFactory; protected $indexerFactory;
/**
* @var \Leonmrni\SearchCore\Configuration\ConfigurationContainerInterface
* @inject
*/
protected $configuration;
/** /**
* @param IndexerFactory $factory * @param IndexerFactory $factory
*/ */
@ -50,6 +57,11 @@ class IndexCommandController extends CommandController
{ {
// TODO: Allow to index multiple tables at once? // TODO: Allow to index multiple tables at once?
// TODO: Also allow to index everything? // TODO: Also allow to index everything?
if (! in_array($table, GeneralUtility::trimExplode(',', $this->configuration->get('index', 'allowedTables')))) {
$this->outputLine('Table is not allowed for indexing.');
$this->quit(1);
}
$this->indexerFactory->getIndexer($table)->indexAllDocuments(); $this->indexerFactory->getIndexer($table)->indexAllDocuments();
$this->outputLine('Table was indexed.');
} }
} }

View file

@ -59,7 +59,7 @@ class ConfigurationContainer implements ConfigurationContainerInterface
{ {
if (!isset($this->settings[$section]) || !isset($this->settings[$section][$key])) { if (!isset($this->settings[$section]) || !isset($this->settings[$section][$key])) {
throw new InvalidArgumentException( throw new InvalidArgumentException(
'The given configuration option does not exit.', 'The given configuration option does not exist.',
InvalidArgumentException::OPTION_DOES_NOT_EXIST InvalidArgumentException::OPTION_DOES_NOT_EXIST
); );
} }

View file

@ -20,7 +20,9 @@ namespace Leonmrni\SearchCore\Domain\Service;
* 02110-1301, USA. * 02110-1301, USA.
*/ */
use Leonmrni\SearchCore\Configuration\ConfigurationContainerInterface;
use TYPO3\CMS\Core\SingletonInterface as Singleton; use TYPO3\CMS\Core\SingletonInterface as Singleton;
use TYPO3\CMS\Core\Utility\GeneralUtility;
/** /**
* Handles all data related things like updates, deletes and inserts. * Handles all data related things like updates, deletes and inserts.
@ -30,10 +32,14 @@ use TYPO3\CMS\Core\SingletonInterface as Singleton;
* *
* TODO: Probably a candidate for deletion. Currently this class makes use of * TODO: Probably a candidate for deletion. Currently this class makes use of
* extbase DI. We have to resolve this somehow. * extbase DI. We have to resolve this somehow.
*
* I think we keep it for easier testing and DI.
*/ */
class DataHandler implements Singleton class DataHandler implements Singleton
{ {
/** /**
* TODO: Only inject on first use?!
*
* @var \Leonmrni\SearchCore\Connection\ConnectionInterface * @var \Leonmrni\SearchCore\Connection\ConnectionInterface
* @inject * @inject
*/ */
@ -45,6 +51,11 @@ class DataHandler implements Singleton
*/ */
protected $indexerFactory; protected $indexerFactory;
/**
* @var ConfigurationContainerInterface
*/
protected $configuration;
/** /**
* @var \TYPO3\CMS\Core\Log\Logger * @var \TYPO3\CMS\Core\Log\Logger
*/ */
@ -60,6 +71,24 @@ class DataHandler implements Singleton
$this->logger = $logManager->getLogger(__CLASS__); $this->logger = $logManager->getLogger(__CLASS__);
} }
/**
* @param ConfigurationContainerInterface $configuration
*/
public function __construct(ConfigurationContainerInterface $configuration)
{
$this->configuration = $configuration;
}
/**
* Get all tables that are allowed for indexing.
*
* @return array<String>
*/
public function getAllowedTablesForIndexing()
{
return GeneralUtility::trimExplode(',', $this->configuration->get('index', 'allowedTables'));
}
/** /**
* @param string $table * @param string $table
* @param array $record * @param array $record

View file

@ -48,9 +48,6 @@ class DataHandler implements Singleton
* Dependency injection as TYPO3 doesn't provide it on it's own. * Dependency injection as TYPO3 doesn't provide it on it's own.
* Still you can submit your own dataHandler. * Still you can submit your own dataHandler.
* *
* TODO: Inject datahandler only on use?! Using getter / setter or something else?
* Otherwise a connection to elastic and whole bootstrapping will be triggered.
*
* @param OwnDataHandler $dataHandler * @param OwnDataHandler $dataHandler
* @param Logger $logger * @param Logger $logger
*/ */
@ -109,7 +106,7 @@ class DataHandler implements Singleton
if ($status === 'new') { if ($status === 'new') {
$fieldArray['uid'] = $dataHandler->substNEWwithIDs[$uid]; $fieldArray['uid'] = $dataHandler->substNEWwithIDs[$uid];
$this->dataHandler->add($table, $fieldArray); $this->dataHandler->add($table, $fieldArray);
return false; return true;
} }
if ($status === 'update') { if ($status === 'update') {
@ -117,28 +114,14 @@ class DataHandler implements Singleton
if ($record !== null) { if ($record !== null) {
$this->dataHandler->update($table, $record); $this->dataHandler->update($table, $record);
} }
return false; return true;
} }
$this->logger->debug( $this->logger->debug(
'Database update not processed, cause status is unhandled.', 'Database update not processed, cause status is unhandled.',
[$status, $table, $uid, $fieldArray] [$status, $table, $uid, $fieldArray]
); );
return true; return false;
}
/**
* Returns array containing tables that should be processed by this hook.
*
* TODO: Fetch from config
*
* @return string[]
*/
protected function getTablesToProcess()
{
return [
'tt_content',
];
} }
/** /**
@ -147,7 +130,7 @@ class DataHandler implements Singleton
*/ */
protected function shouldProcessTable($table) protected function shouldProcessTable($table)
{ {
return in_array($table, $this->getTablesToProcess()); return in_array($table, $this->dataHandler->getAllowedTablesForIndexing());
} }
/** /**

View file

@ -7,6 +7,12 @@ plugin {
} }
index { index {
# Pages are not supported yet, see
# https://github.com/DanielSiepmann/search_core/issues/24 but
# should also be added, together with additionalWhereClause
# based on doktypes
allowedTables = tt_content
tt_content { tt_content {
additionalWhereClause = tt_content.CType NOT IN ('gridelements_pi1', 'list', 'div', 'menu') additionalWhereClause = tt_content.CType NOT IN ('gridelements_pi1', 'list', 'div', 'menu')
} }

View file

@ -14,11 +14,6 @@ install: clean
COMPOSER_PROCESS_TIMEOUT=1000 composer require -vv --dev --prefer-source typo3/cms="$(TYPO3_VERSION)" COMPOSER_PROCESS_TIMEOUT=1000 composer require -vv --dev --prefer-source typo3/cms="$(TYPO3_VERSION)"
git checkout composer.json git checkout composer.json
unitTests:
TYPO3_PATH_WEB=$(TYPO3_WEB_DIR) \
.Build/bin/phpunit --colors --debug -v \
-c Tests/Unit/UnitTests.xml
functionalTests: functionalTests:
typo3DatabaseName=$(typo3DatabaseName) \ typo3DatabaseName=$(typo3DatabaseName) \
typo3DatabaseUsername=$(typo3DatabaseUsername) \ typo3DatabaseUsername=$(typo3DatabaseUsername) \
@ -28,9 +23,6 @@ functionalTests:
.Build/bin/phpunit --colors --debug -v \ .Build/bin/phpunit --colors --debug -v \
-c Tests/Functional/FunctionalTests.xml -c Tests/Functional/FunctionalTests.xml
.PHONY: Tests
Tests: unitTests functionalTests
uploadCodeCoverage: uploadCodeCoverageToScrutinizer uploadCodeCoverageToCodacy uploadCodeCoverage: uploadCodeCoverageToScrutinizer uploadCodeCoverageToCodacy
uploadCodeCoverageToScrutinizer: uploadCodeCoverageToScrutinizer:

View file

@ -29,18 +29,6 @@ abstract class AbstractFunctionalTestCase extends CoreTestCase
{ {
protected $testExtensionsToLoad = ['typo3conf/ext/search_core']; protected $testExtensionsToLoad = ['typo3conf/ext/search_core'];
/**
* Define whether to setup default typoscript on page 1.
*
* Set to false if you need to add further ts and use getDefaultPageTs to get the default one.
*
* This is necessary as setUpFrontendRootPage will allways add a new record
* and only the first one is used.
*
* @var bool
*/
protected $loadDefaultTs = true;
public function setUp() public function setUp()
{ {
parent::setUp(); parent::setUp();
@ -48,15 +36,33 @@ abstract class AbstractFunctionalTestCase extends CoreTestCase
$this->setUpBackendUserFromFixture(1); $this->setUpBackendUserFromFixture(1);
\TYPO3\CMS\Core\Core\Bootstrap::getInstance()->initializeLanguageObject(); \TYPO3\CMS\Core\Core\Bootstrap::getInstance()->initializeLanguageObject();
// Provide necessary configuration for extension foreach ($this->getDataSets() as $dataSet) {
$this->importDataSet('Tests/Functional/Fixtures/BasicSetup.xml'); $this->importDataSet($dataSet);
if ($this->loadDefaultTs) {
$this->setUpFrontendRootPage(1, $this->getDefaultPageTs());
} }
$this->setUpFrontendRootPage(1, $this->getTypoScriptFilesForFrontendRootPage());
} }
protected function getDefaultPageTs() /**
* Overwrite to import different files.
*
* Defines which DataSet Files should be imported.
*
* @return array<String>
*/
protected function getDataSets()
{
return ['Tests/Functional/Fixtures/BasicSetup.xml'];
}
/**
* Overwrite to import different files.
*
* Defines which TypoScript Files should be imported.
*
* @return array<String>
*/
protected function getTypoScriptFilesForFrontendRootPage()
{ {
return ['EXT:search_core/Tests/Functional/Fixtures/BasicSetup.ts']; return ['EXT:search_core/Tests/Functional/Fixtures/BasicSetup.ts'];
} }

View file

@ -28,11 +28,12 @@ use TYPO3\CMS\Extbase\Object\ObjectManager;
*/ */
class IndexTcaTableTest extends AbstractFunctionalTestCase class IndexTcaTableTest extends AbstractFunctionalTestCase
{ {
public function setUp() protected function getDataSets()
{ {
parent::setUp(); return array_merge(
parent::getDataSets(),
$this->importDataSet('Tests/Functional/Fixtures/Indexing/IndexTcaTable.xml'); ['Tests/Functional/Fixtures/Indexing/IndexTcaTable.xml']
);
} }
/** /**

View file

@ -5,6 +5,10 @@ plugin {
host = localhost host = localhost
port = 9200 port = 9200
} }
index {
allowedTables = tt_content
}
} }
} }
} }

View file

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<dataset> <dataset>
<tt_content> <tt_content>
<uid>6</uid> <uid>1</uid>
<pid>1</pid> <pid>1</pid>
<tstamp>1480686370</tstamp> <tstamp>1480686370</tstamp>
<crdate>1480686370</crdate> <crdate>1480686370</crdate>
@ -9,7 +9,7 @@
<sorting>72</sorting> <sorting>72</sorting>
<CType>textmedia</CType> <CType>textmedia</CType>
<header>test</header> <header>test</header>
<bodytext>this is the content of textmedia content element that should get indexed</bodytext> <bodytext>Record that can be processed by hook</bodytext>
<media>0</media> <media>0</media>
<layout>0</layout> <layout>0</layout>
<deleted>0</deleted> <deleted>0</deleted>

View file

@ -0,0 +1,11 @@
plugin {
tx_searchcore {
settings {
index {
allowedTables = tt_content, fe_user
}
}
}
}
module.tx_searchcore < plugin.tx_searchcore

View file

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<dataset>
<sys_category>
<uid>1</uid>
<pid>1</pid>
<tstamp>1480686370</tstamp>
<crdate>1480686370</crdate>
<deleted>0</deleted>
<starttime>0</starttime>
<endtime>0</endtime>
<sorting>1</sorting>
<title>Some Category that should not be indexed as sys_category is not allowed</title>
<description></description>
<parent>0</parent>
<items>0</items>
</sys_category>
</dataset>

View file

@ -0,0 +1,57 @@
<?php
namespace Leonmrni\SearchCore\Tests\Functional\Hooks\DataHandler;
/*
* Copyright (C) 2016 Daniel Siepmann <coding@daniel-siepmann.de>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
use Leonmrni\SearchCore\Configuration\ConfigurationContainerInterface;
use Leonmrni\SearchCore\Domain\Service\DataHandler as DataHandlerService;
use Leonmrni\SearchCore\Hook\DataHandler as DataHandlerHook;
use Leonmrni\SearchCore\Tests\Functional\AbstractFunctionalTestCase;
use TYPO3\CMS\Core\DataHandling\DataHandler as Typo3DataHandler;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Object\ObjectManager;
abstract class AbstractDataHandlerTest extends AbstractFunctionalTestCase
{
/**
* @var DataHandlerService|\PHPUnit_Framework_MockObject_MockObject|AccessibleObjectInterface
*/
protected $subject;
public function setUp()
{
parent::setUp();
$objectManager = GeneralUtility::makeInstance(ObjectManager::class);
$this->subject = $this->getAccessibleMock(
DataHandlerService::class,
[
'add',
'update',
'delete',
],
[$objectManager->get(ConfigurationContainerInterface::class)]
);
// This way TYPO3 will use our mock instead of a new instance.
$GLOBALS['T3_VAR']['getUserObj']['&' . DataHandlerHook::class] = new DataHandlerHook($this->subject);
}
}

View file

@ -0,0 +1,54 @@
<?php
namespace Leonmrni\SearchCore\Tests\Functional\Hooks\DataHandler;
/*
* Copyright (C) 2016 Daniel Siepmann <coding@daniel-siepmann.de>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
use Leonmrni\SearchCore\Configuration\ConfigurationContainerInterface;
use Leonmrni\SearchCore\Domain\Service\DataHandler as DataHandlerService;
use Leonmrni\SearchCore\Hook\DataHandler as DataHandlerHook;
use TYPO3\CMS\Core\DataHandling\DataHandler as Typo3DataHandler;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Object\ObjectManager;
class IgnoresUnkownOperationTest extends AbstractDataHandlerTest
{
/**
* @var DataHandlerService|\PHPUnit_Framework_MockObject_MockObject|AccessibleObjectInterface
*/
protected $subject;
/**
* @test
*/
public function dataHandlerCommandSomethingIsIgnored()
{
$subject = new DataHandlerHook($this->subject);
$this->assertFalse(
$subject->processDatamap_afterDatabaseOperations(
'something',
'tt_content',
1,
[],
new Typo3DataHandler
),
'Hook processed status "something".'
);
}
}

View file

@ -0,0 +1,103 @@
<?php
namespace Leonmrni\SearchCore\Tests\Functional\Hooks\DataHandler;
/*
* Copyright (C) 2016 Daniel Siepmann <coding@daniel-siepmann.de>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
use Leonmrni\SearchCore\Configuration\ConfigurationContainerInterface;
use Leonmrni\SearchCore\Domain\Service\DataHandler as DataHandlerService;
use Leonmrni\SearchCore\Hook\DataHandler as DataHandlerHook;
use TYPO3\CMS\Core\DataHandling\DataHandler as Typo3DataHandler;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Object\ObjectManager;
class NonAllowedTablesTest extends AbstractDataHandlerTest
{
/**
* @var DataHandlerService|\PHPUnit_Framework_MockObject_MockObject|AccessibleObjectInterface
*/
protected $subject;
protected function getDataSets()
{
return array_merge(
parent::getDataSets(),
['Tests/Functional/Fixtures/Hooks/DataHandler/NonAllowedTables.xml']
);
}
/**
* @test
*/
public function deletionWillNotBeTriggeredForSysCategories()
{
$this->subject->expects($this->exactly(0))->method('delete');
$tce = GeneralUtility::makeInstance(Typo3DataHandler::class);
$tce->stripslashes_values = 0;
$tce->start([], [
'sys_category' => [
'1' => [
'delete' => 1,
],
],
]);
$tce->process_cmdmap();
}
/**
* @test
*/
public function updateWillNotBeTriggeredForSysCategory()
{
$this->subject->expects($this->exactly(0))->method('update');
$tce = GeneralUtility::makeInstance(Typo3DataHandler::class);
$tce->stripslashes_values = 0;
$tce->start([
'sys_category' => [
'1' => [
'title' => 'something new',
],
],
], []);
$tce->process_datamap();
}
/**
* @test
*/
public function addWillNotBeTriggeredForSysCategoy()
{
$this->subject->expects($this->exactly(0))->method('add');
$tce = GeneralUtility::makeInstance(Typo3DataHandler::class);
$tce->stripslashes_values = 0;
$tce->start([
'sys_category' => [
'NEW_1' => [
'pid' => 1,
'title' => 'a new record',
],
],
], []);
$tce->process_datamap();
}
}

View file

@ -0,0 +1,32 @@
<?php
namespace Leonmrni\SearchCore\Tests\Functional\Hooks\DataHandler;
/*
* Copyright (C) 2016 Daniel Siepmann <coding@daniel-siepmann.de>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
class NonAllowedTablesWithMultipleTablesConfiguredTest extends NonAllowedTablesTest
{
protected function getTypoScriptFilesForFrontendRootPage()
{
return array_merge(
parent::getTypoScriptFilesForFrontendRootPage(),
['EXT:search_core/ Tests/Functional/Fixtures/Hooks/DataHandler/MultipleAllowedTables.ts']
);
}
}

View file

@ -0,0 +1,122 @@
<?php
namespace Leonmrni\SearchCore\Tests\Functional\Hooks\DataHandler;
/*
* Copyright (C) 2016 Daniel Siepmann <coding@daniel-siepmann.de>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
use Leonmrni\SearchCore\Configuration\ConfigurationContainerInterface;
use Leonmrni\SearchCore\Domain\Service\DataHandler as DataHandlerService;
use Leonmrni\SearchCore\Hook\DataHandler as DataHandlerHook;
use TYPO3\CMS\Core\DataHandling\DataHandler as Typo3DataHandler;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Object\ObjectManager;
class ProcessesAllowedTablesTest extends AbstractDataHandlerTest
{
/**
* @var DataHandlerService|\PHPUnit_Framework_MockObject_MockObject|AccessibleObjectInterface
*/
protected $subject;
protected function getDataSets()
{
return array_merge(
parent::getDataSets(),
['Tests/Functional/Fixtures/Hooks/DataHandler/AllowedTables.xml']
);
}
/**
* @test
*/
public function deletionWillBeTriggeredForTtContent()
{
$this->subject->expects($this->exactly(1))->method('delete')
->with($this->equalTo('tt_content'), $this->equalTo('1'));
$tce = GeneralUtility::makeInstance(Typo3DataHandler::class);
$tce->stripslashes_values = 0;
$tce->start([], [
'tt_content' => [
'1' => [
'delete' => 1,
],
],
]);
$tce->process_cmdmap();
}
/**
* @test
*/
public function updateWillBeTriggeredForTtContent()
{
$this->subject->expects($this->exactly(1))->method('update')
->with(
$this->equalTo('tt_content'),
$this->callback(function ($record) {
return isset($record['uid']) && $record['uid'] === '1'
&& isset($record['pid']) && $record['pid'] === '1'
&& isset($record['colPos']) && $record['colPos'] === '1'
;
})
);
$tce = GeneralUtility::makeInstance(Typo3DataHandler::class);
$tce->stripslashes_values = 0;
$tce->start([
'tt_content' => [
'1' => [
'colPos' => 1,
],
],
], []);
$tce->process_datamap();
}
/**
* @test
*/
public function addWillBeTriggeredForTtContent()
{
$this->subject->expects($this->exactly(1))->method('add')
->with(
$this->equalTo('tt_content'),
$this->callback(function ($record) {
return isset($record['uid']) && $record['uid'] === 2
&& isset($record['pid']) && $record['pid'] === 1
&& isset($record['header']) && $record['header'] === 'a new record'
;
})
);
$tce = GeneralUtility::makeInstance(Typo3DataHandler::class);
$tce->stripslashes_values = 0;
$tce->start([
'tt_content' => [
'NEW_1' => [
'pid' => 1,
'header' => 'a new record',
],
],
], []);
$tce->process_datamap();
}
}

View file

@ -0,0 +1,37 @@
<?php
namespace Leonmrni\SearchCore\Tests\Functional\Hooks\DataHandler;
/*
* Copyright (C) 2016 Daniel Siepmann <coding@daniel-siepmann.de>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
class ProcessesAllowedTablesWithMultipleTablesConfiguredTest extends ProcessesAllowedTablesTest
{
/**
* @var DataHandlerService|\PHPUnit_Framework_MockObject_MockObject|AccessibleObjectInterface
*/
protected $subject;
protected function getTypoScriptFilesForFrontendRootPage()
{
return array_merge(
parent::getTypoScriptFilesForFrontendRootPage(),
['EXT:search_core/ Tests/Functional/Fixtures/Hooks/DataHandler/MultipleAllowedTables.ts']
);
}
}

View file

@ -1,115 +0,0 @@
<?php
namespace Leonmrni\SearchCore\Tests\Functional\Hooks;
/*
* Copyright (C) 2016 Daniel Siepmann <coding@daniel-siepmann.de>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
use Leonmrni\SearchCore\Hook\DataHandler as Hook;
use Leonmrni\SearchCore\Tests\Functional\Connection\Elasticsearch\AbstractFunctionalTestCase;
use TYPO3\CMS\Core\DataHandling\DataHandler as CoreDataHandler;
use TYPO3\CMS\Extbase\Object\ObjectManager;
/**
* TODO: Rewrite as this test doesn't test what it should do.
* We have to split it up in two tests:
* 1. Test whether TYPO3 DataHandler will our hook as expected.
* 2. Test whether our hook will send the documents to connection as expected.
*/
class DataHandlerTest extends AbstractFunctionalTestCase
{
public function setUp()
{
parent::setUp();
$this->importDataSet('Tests/Functional/Fixtures/Hooks/DataHandler.xml');
}
/**
* @test
*/
public function nonAllowedTablesWillNotBeProcessed()
{
$dataHandler = new CoreDataHandler();
$hook = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(Hook::class);
$this->assertFalse($hook->processDatamap_afterDatabaseOperations('new', 'some_strange_table', 'NEW34', [], $dataHandler));
$this->assertFalse($hook->processDatamap_afterDatabaseOperations('update', 'some_strange_table', 6, [], $dataHandler));
$this->assertFalse($hook->processCmdmap_deleteAction('some_strange_table', 6, [], false, $dataHandler));
}
/**
* @test
*/
public function addNewElement()
{
$dataHandler = new CoreDataHandler();
$dataHandler->substNEWwithIDs = ['NEW34' => 6];
$hook = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(Hook::class);
$hook->processDatamap_afterDatabaseOperations('new', 'tt_content', 'NEW34', [], $dataHandler);
$response = $this->client->request('typo3content/_search?q=*:*');
$this->assertTrue($response->isOK());
$this->assertSame($response->getData()['hits']['total'], 1, 'Not exactly 1 document was indexed.');
}
/**
* @test
* TODO: Make sure the indexed document was updated, e.g. by changing some content.
*/
public function updateExistingElement()
{
$dataHandler = new CoreDataHandler();
$hook = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(Hook::class);
$hook->processDatamap_afterDatabaseOperations('update', 'tt_content', 6, [], $dataHandler);
$response = $this->client->request('typo3content/_search?q=*:*');
$this->assertTrue($response->isOK(), 'Elastica did not answer with ok code.');
$this->assertSame($response->getData()['hits']['total'], 1, 'Not exactly 1 document was indexed.');
}
/**
* @test
*/
public function deleteExistingElement()
{
$this->addNewElement();
$dataHandler = new CoreDataHandler();
$hook = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(Hook::class);
$hook->processCmdmap_deleteAction('tt_content', 6, [], false, $dataHandler);
$response = $this->client->request('typo3content/_search?q=*:*');
$this->assertTrue($response->isOK(), 'Elastica did not answer with ok code.');
$this->assertSame($response->getData()['hits']['total'], 0, 'Not exactly 0 document was indexed.');
}
/**
* @test
* @expectedException \Elastica\Exception\ResponseException
*/
public function someUnknownOperationDoesNotBreakSomething()
{
$dataHandler = new CoreDataHandler();
$hook = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(Hook::class);
//TODO: this test is senseless, checking an exception not correct, this operation should not do anything!
$hook->processDatamap_afterDatabaseOperations('something', 'tt_content', 6, [], $dataHandler);
// Should trigger Exception
$this->client->request('typo3content/_search?q=*:*');
}
}

View file

@ -30,22 +30,12 @@ use TYPO3\CMS\Extbase\Object\ObjectManager;
class TcaIndexerTest extends AbstractFunctionalTestCase class TcaIndexerTest extends AbstractFunctionalTestCase
{ {
protected $loadDefaultTs = false;
/** /**
* @test * @test
*/ */
public function respectRootLineBlacklist() public function respectRootLineBlacklist()
{ {
$this->importDataSet('Tests/Functional/Fixtures/Indexing/TcaIndexer/RespectRootLineBlacklist.xml'); $this->importDataSet('Tests/Functional/Fixtures/Indexing/TcaIndexer/RespectRootLineBlacklist.xml');
$this->setUpFrontendRootPage(
1,
array_merge(
$this->getDefaultPageTs(),
['EXT:search_core/Tests/Functional/Fixtures/Indexing/TcaIndexer/RespectRootLineBlacklist.ts']
)
);
$objectManager = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(ObjectManager::class); $objectManager = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(ObjectManager::class);
$tableName = 'tt_content'; $tableName = 'tt_content';
$tableService = $objectManager->get( $tableService = $objectManager->get(
@ -83,4 +73,12 @@ class TcaIndexerTest extends AbstractFunctionalTestCase
$objectManager->get(TcaIndexer::class, $tableService, $connection)->indexAllDocuments(); $objectManager->get(TcaIndexer::class, $tableService, $connection)->indexAllDocuments();
} }
protected function getTypoScriptFilesForFrontendRootPage()
{
return array_merge(
parent::getTypoScriptFilesForFrontendRootPage(),
['EXT:search_core/Tests/Functional/Fixtures/Indexing/TcaIndexer/RespectRootLineBlacklist.ts']
);
}
} }

View file

@ -1,142 +0,0 @@
<?php
namespace Leonmrni\SearchCore\Tests\Unit\Hook;
/*
* Copyright (C) 2016 Daniel Siepmann <daniel.siepmann@typo3.org>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
use TYPO3\CMS\Core\DataHandling\DataHandler as CoreDataHandler;
use TYPO3\CMS\Core\Tests\UnitTestCase;
use Leonmrni\SearchCore\Domain\Service\DataHandler;
use Leonmrni\SearchCore\Hook\DataHandler as Hook;
/**
*
*/
class DataHandlerTest extends UnitTestCase
{
/**
* @var DataHandler|\PHPUnit_Framework_MockObject_MockObject|AccessibleObjectInterface
*/
protected $subject;
/**
* @var Hook|\PHPUnit_Framework_MockObject_MockObject|AccessibleObjectInterface
*/
protected $hook;
/**
* Set up the tests
*/
protected function setUp()
{
$this->subject = $this->getAccessibleMock(DataHandler::class);
$this->hook = $this->getAccessibleMock(
Hook::class,
[
'getTablesToProcess',
'getRecord'
],
[$this->subject]
);
$this->hook->method('getTablesToProcess')
->willReturn(['table']);
$this->hook->method('getRecord')
->willReturn([
'title' => 'some title',
'bodytext' => 'some text',
]);
}
/**
* @test
*/
public function notConfiguredTablesWillNotBeProcessed()
{
$table = 'noneConfiguredTable';
$recordUid = 1;
$this->subject->expects($this->exactly(0))->method('delete');
$this->subject->expects($this->exactly(0))->method('add');
$this->subject->expects($this->exactly(0))->method('update');
$dataHandler = new CoreDataHandler();
$dataHandler->substNEWwithIDs = ['NEW34' => $recordUid];
$this->hook->processCmdmap_deleteAction($table, $recordUid, [], false, $dataHandler);
$this->hook->processDatamap_afterDatabaseOperations('new', $table, 'NEW34', [], $dataHandler);
$this->hook->processDatamap_afterDatabaseOperations('update', $table, $recordUid, [], $dataHandler);
}
/**
* @test
*/
public function configuredTablesWillBeProcessed()
{
$table = 'table';
$recordUid = 1;
$this->subject->expects($this->once())->method('delete');
$this->subject->expects($this->once())->method('add');
$this->subject->expects($this->once())->method('update');
$dataHandler = new CoreDataHandler();
$dataHandler->substNEWwithIDs = ['NEW34' => $recordUid];
$this->hook->processCmdmap_deleteAction($table, $recordUid, [], false, $dataHandler);
$this->hook->processDatamap_afterDatabaseOperations('new', $table, 'NEW34', [], $dataHandler);
$this->hook->processDatamap_afterDatabaseOperations('update', $table, $recordUid, [], $dataHandler);
}
/**
* @test
*/
public function deletionWillBeTriggered()
{
$table = 'table';
$recordUid = 1;
$this->subject->expects($this->once())
->method('delete')
->with(
$this->equalTo($table),
$this->equalTo($recordUid)
);
$this->hook->processCmdmap_deleteAction($table, $recordUid, [], false, new CoreDataHandler());
}
/**
* @test
*/
public function updateWillBeTriggered()
{
$table = 'table';
$recordUid = 1;
$record = [
'title' => 'some title',
'bodytext' => 'some text',
];
$this->subject->expects($this->once())
->method('update')
->with(
$this->equalTo($table),
$this->equalTo($record)
);
$this->hook->processDatamap_afterDatabaseOperations('update', $table, $recordUid, $record, new CoreDataHandler);
}
}

View file

@ -1,33 +0,0 @@
<phpunit
backupGlobals="false"
backupStaticAttributes="false"
bootstrap="../../.Build/vendor/typo3/cms/typo3/sysext/core/Build/UnitTestsBootstrap.php"
colors="true"
convertErrorsToExceptions="false"
convertWarningsToExceptions="false"
forceCoversAnnotation="false"
processIsolation="false"
stopOnError="false"
stopOnFailure="false"
stopOnIncomplete="false"
stopOnSkipped="false"
verbose="false">
<testsuites>
<testsuite name="unit-tests">
<directory>.</directory>
</testsuite>
</testsuites>
<filter>
<whitelist>
<directory suffix=".php">../../Classes</directory>
</whitelist>
</filter>
<logging>
<log type="coverage-html" target="../../.Build/report/unit/html" lowUpperBound="35" highLowerBound="70"/>
<log type="coverage-clover" target="../../.Build/report/unit/clover/coverage"/>
</logging>
</phpunit>

View file

@ -16,10 +16,10 @@ call_user_func(
], ],
't3lib/class.t3lib_tcemain.php' => [ 't3lib/class.t3lib_tcemain.php' => [
'processCmdmapClass' => [ 'processCmdmapClass' => [
$extensionKey => \Leonmrni\SearchCore\Hook\DataHandler::class, $extensionKey => '&' . \Leonmrni\SearchCore\Hook\DataHandler::class,
], ],
'processDatamapClass' => [ 'processDatamapClass' => [
$extensionKey => \Leonmrni\SearchCore\Hook\DataHandler::class, $extensionKey => '&' . \Leonmrni\SearchCore\Hook\DataHandler::class,
], ],
], ],
], ],