diff --git a/.travis.yml b/.travis.yml
index 3530a8c..5f7df5f 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -13,6 +13,14 @@ addons:
language: php
matrix:
include:
+ - php: 7.2
+ env:
+ - MAGENTO_VERSION=2.2
+ - TEST_SUITE=unit
+ - php: 7.3
+ env:
+ - MAGENTO_VERSION=2.3-develop
+ - TEST_SUITE=unit
- php: 7.2
env:
- MAGENTO_VERSION=2.2
diff --git a/.travis/before_script.sh b/.travis/before_script.sh
index 154ddc6..d8d55d4 100755
--- a/.travis/before_script.sh
+++ b/.travis/before_script.sh
@@ -25,8 +25,13 @@ cd magento2
composer config minimum-stability dev
composer config repositories.travis_to_test git https://github.com/$TRAVIS_REPO_SLUG.git
#TODO make it work with tags as well:
+
composer require ${COMPOSER_PACKAGE_NAME}:dev-${TRAVIS_BRANCH}\#{$TRAVIS_COMMIT}
+# Install dev dependencies of module
+php ../.travis/merge-dev.php vendor/$COMPOSER_PACKAGE_NAME/composer.json composer.json
+composer update
+
# prepare for test suite
case $TEST_SUITE in
integration)
diff --git a/.travis/merge-dev.php b/.travis/merge-dev.php
new file mode 100644
index 0000000..8f411c3
--- /dev/null
+++ b/.travis/merge-dev.php
@@ -0,0 +1,23 @@
+ $value) {
+ $pathPrefix = dirname($fromFile) . DIRECTORY_SEPARATOR;
+ $fromJson['autoload-dev']['psr-4'][$key] = $pathPrefix . $value;
+}
+
+$toJson['require-dev'] = array_replace_recursive($toJson['require-dev'] ?? [], $fromJson['require-dev']);
+$toJson['autoload-dev'] = array_merge_recursive($toJson['autoload-dev'] ?? [], $fromJson['autoload-dev']);
+
+file_put_contents($toFile, json_encode($toJson, JSON_PRETTY_PRINT));
\ No newline at end of file
diff --git a/composer.json b/composer.json
index 656f1ed..390bd6c 100755
--- a/composer.json
+++ b/composer.json
@@ -26,10 +26,15 @@
"src/registration.php"
],
"psr-4": {
- "IntegerNet\\AsyncVarnish\\Test\\": "tests/",
"IntegerNet\\AsyncVarnish\\": "src/"
}
},
+ "autoload-dev": {
+ "psr-4": {
+ "IntegerNet\\AsyncVarnish\\Test\\": "tests/",
+ "IntegerNet\\AsyncVarnish\\": "tests/src/"
+ }
+ },
"repositories": [
{
"type": "composer",
@@ -37,6 +42,6 @@
}
],
"require-dev": {
- "magento/magento-coding-standard": "@dev"
+ "react/http": "0.8.5"
}
}
diff --git a/src/Api/TagRepositoryInterface.php b/src/Api/TagRepositoryInterface.php
new file mode 100644
index 0000000..0e9048c
--- /dev/null
+++ b/src/Api/TagRepositoryInterface.php
@@ -0,0 +1,37 @@
+tagRepository->getAll();
$maxHeaderLength = $this->getMaxHeaderLengthFromConfig();
diff --git a/src/Model/ResourceModel/Tag.php b/src/Model/ResourceModel/Tag.php
index f3120eb..1daab7b 100644
--- a/src/Model/ResourceModel/Tag.php
+++ b/src/Model/ResourceModel/Tag.php
@@ -22,11 +22,10 @@ public function getMaxTagId(int $limit):array
$connection = $this->getConnection();
$subSetSelect = $connection->select()->from(
- self::TABLE_NAME,
+ $this->getTable(self::TABLE_NAME),
['entity_id','tag']
)->order(
- 'entity_id',
- 'ASC'
+ 'entity_id ASC'
)->limit(
$limit
);
@@ -44,7 +43,7 @@ public function getUniqueTagsByMaxId(int $maxId):array
$connection = $this->getConnection();
$select = $connection->select()->from(
- ['main_table' => self::TABLE_NAME],
+ ['main_table' => $this->getTable(self::TABLE_NAME)],
['tag']
)->group(
'tag'
diff --git a/src/Model/TagRepository.php b/src/Model/TagRepository.php
index b556291..c1229d6 100644
--- a/src/Model/TagRepository.php
+++ b/src/Model/TagRepository.php
@@ -3,11 +3,12 @@
namespace IntegerNet\AsyncVarnish\Model;
+use IntegerNet\AsyncVarnish\Api\TagRepositoryInterface;
use Magento\Framework\App\ResourceConnection;
use IntegerNet\AsyncVarnish\Model\ResourceModel\Tag as TagResource;
use Magento\Framework\App\Config\ScopeConfigInterface;
-class TagRepository
+class TagRepository implements TagRepositoryInterface
{
/**
* DB Storage table name
@@ -19,6 +20,9 @@ class TagRepository
*/
const FETCH_TAG_LIMIT_CONFIG_PATH = 'system/full_page_cache/async_varnish/varnish_fetch_tag_limit';
+ /**
+ * @var int|null
+ */
private $lastUsedId;
/**
@@ -52,9 +56,9 @@ public function __construct(
$this->scopeConfig = $scopeConfig;
}
- private function getTagFetchLimit()
+ private function getTagFetchLimit(): int
{
- return $this->scopeConfig->getValue(self::FETCH_TAG_LIMIT_CONFIG_PATH);
+ return (int) $this->scopeConfig->getValue(self::FETCH_TAG_LIMIT_CONFIG_PATH);
}
/**
@@ -64,7 +68,7 @@ private function getTagFetchLimit()
* @return int
* @throws \Exception
*/
- public function insertMultiple($tags = [])
+ public function insertMultiple($tags = []): int
{
if (empty($tags)) {
return 0;
@@ -92,7 +96,7 @@ function ($tag) {
* @return int
* @throws \Exception
*/
- public function deleteUpToId($maxId = 0)
+ public function deleteUpToId(int $maxId = 0): int
{
try {
$tableName = $this->resource->getTableName(self::TABLE_NAME);
@@ -103,10 +107,9 @@ public function deleteUpToId($maxId = 0)
}
/**
- * @return array
* @throws \Zend_Db_Statement_Exception
*/
- public function getAll()
+ public function getAll(): array
{
$tags = [];
@@ -120,24 +123,21 @@ public function getAll()
return $tags;
}
- $maxId = $maxIdResult['max_id'];
+ $maxId = (int)$maxIdResult['max_id'];
- $uniqueTagsResult = $tagResource->getUniqueTagsByMaxId((int)$maxId);
+ $uniqueTagsResult = $tagResource->getUniqueTagsByMaxId($maxId);
if (!empty($uniqueTagsResult)) {
$this->lastUsedId = $maxId;
foreach ($uniqueTagsResult as $tag) {
- $tags[] = ($tag['tag']);
+ $tags[] = $tag['tag'];
}
}
return $tags;
}
- /**
- * @return int
- */
- public function getLastUsedId()
+ public function getLastUsedId(): int
{
return $this->lastUsedId ?: 0;
}
diff --git a/src/etc/di.xml b/src/etc/di.xml
index 6e6a05b..5673de7 100644
--- a/src/etc/di.xml
+++ b/src/etc/di.xml
@@ -12,4 +12,6 @@
+
\ No newline at end of file
diff --git a/tests/Integration/AbstractTagRepositoryTest.php b/tests/Integration/AbstractTagRepositoryTest.php
new file mode 100644
index 0000000..1a13dc9
--- /dev/null
+++ b/tests/Integration/AbstractTagRepositoryTest.php
@@ -0,0 +1,78 @@
+tagRepository = $this->getTestSubject();
+ }
+
+ abstract protected function getTestSubject(): TagRepositoryInterface;
+
+ public function testInsertAndRetrieve()
+ {
+ $affected = $this->tagRepository->insertMultiple(['x', 'y', 'z']);
+ $this->assertEquals(3, $affected, 'insertMultiple() should return number of inserted rows');
+ $this->assertEqualsCanonicalizing(['x', 'y', 'z'], $this->tagRepository->getAll());
+ }
+
+ public function testNoDuplicatesAreRetrieved()
+ {
+ $affected = $this->tagRepository->insertMultiple(['x', 'y', 'x']);
+ $this->assertEquals(3, $affected, 'insertMultiple() should return number of inserted rows');
+ $this->assertEqualsCanonicalizing(['x', 'y'], $this->tagRepository->getAll());
+ }
+
+ public function testNoDuplicatesAreRetrievedAfterSubsequentCalls()
+ {
+ $affected = $this->tagRepository->insertMultiple(['x', 'y']);
+ $this->assertEquals(2, $affected, 'insertMultiple() should return number of inserted rows');
+ $affected = $this->tagRepository->insertMultiple(['y', 'z']);
+ $this->assertEquals(2, $affected, 'insertMultiple() should return number of inserted rows');
+ $this->assertEqualsCanonicalizing(['x', 'y', 'z'], $this->tagRepository->getAll());
+ }
+
+ public function testLastUsedIdIncreases()
+ {
+ $this->tagRepository->insertMultiple(['x']);
+ $this->tagRepository->getAll();
+ $lastUsedId = $this->tagRepository->getLastUsedId();
+ $this->tagRepository->insertMultiple(['y']);
+ $this->tagRepository->getAll();
+ //TODO maybe throw exception if getAll has not been called before:
+ $this->assertEquals($lastUsedId + 1, $this->tagRepository->getLastUsedId());
+ }
+
+ public function testDeleteUpToId()
+ {
+ $this->tagRepository->insertMultiple(['x', 'y', 'z']);
+ $this->tagRepository->getAll();
+ $lastUsedId = $this->tagRepository->getLastUsedId();
+ $this->tagRepository->insertMultiple(['a', 'b', 'c']);
+ $affected = $this->tagRepository->deleteUpToId($lastUsedId);
+ $this->assertEquals(3, $affected, 'deleteUpToId() should return number of deleted rows');
+ $this->assertEqualsCanonicalizing(['a', 'b', 'c'], $this->tagRepository->getAll());
+ }
+
+ /**
+ * Backport from PHPUnit 8
+ *
+ * @param array $expected
+ * @param array $actual
+ */
+ public static function assertEqualsCanonicalizing(array $expected, array $actual, string $message = '')
+ {
+ self::assertEquals($expected, $actual, $message, 0.0, 10, true);
+ }
+}
diff --git a/tests/Integration/ModuleTest.php b/tests/Integration/ModuleTest.php
new file mode 100644
index 0000000..865824e
--- /dev/null
+++ b/tests/Integration/ModuleTest.php
@@ -0,0 +1,44 @@
+objectManager->create(ModuleList::class);
+ return $moduleList;
+ }
+ protected function setUp()
+ {
+ $this->objectManager = ObjectManager::getInstance();
+ }
+ public function testTheModuleIsRegistered()
+ {
+ $registrar = new ComponentRegistrar();
+ $paths = $registrar->getPaths(ComponentRegistrar::MODULE);
+ $this->assertArrayHasKey(self::MODULE_NAME, $paths, 'Module should be registered');
+ }
+ public function testTheModuleIsKnownAndEnabled()
+ {
+ $moduleList = $this->getTestModuleList();
+ $this->assertTrue($moduleList->has(self::MODULE_NAME), 'Module should be enabled');
+ }
+
+}
\ No newline at end of file
diff --git a/tests/Integration/PurgeCacheTest.php b/tests/Integration/PurgeCacheTest.php
new file mode 100644
index 0000000..5caa888
--- /dev/null
+++ b/tests/Integration/PurgeCacheTest.php
@@ -0,0 +1,135 @@
+startMockServer();
+ $this->createRequestLog();
+
+ $this->configureVarnishHost();
+ $this->purgeCache = Bootstrap::getObjectManager()->get(PurgeCache::class);
+ }
+
+ private function configureVarnishHost()
+ {
+ /** @var ObjectManager $objectManager */
+ $objectManager = Bootstrap::getObjectManager();
+ $deploymentConfig = new DeploymentConfig(
+ $objectManager->get(DeploymentConfig\Reader::class),
+ ['http_cache_hosts' => [['host' => '127.0.0.1', 'port' => self::MOCK_SERVER_PORT]]]
+ );
+ $objectManager->addSharedInstance(
+ $deploymentConfig,
+ DeploymentConfig::class
+ );
+ }
+
+ protected function tearDown()
+ {
+ $this->stopMockServer();
+ }
+
+ public function testWebserver()
+ {
+ $this->assertEquals("OK\n", \file_get_contents('http://127.0.0.1:' . self::MOCK_SERVER_PORT . '/'));
+ }
+
+ public function testPurgeRequestIsSentToVarnish()
+ {
+ $tagsPattern = 'XXX|YYY|ZZZZ';
+ $result = $this->purgeCache->sendPurgeRequest($tagsPattern);
+ $this->assertTrue($result);
+ $this->assertEquals(
+ [
+ [
+ 'method' => 'PURGE',
+ 'headers' => ['Host' => ['127.0.0.1'], 'X-Magento-Tags-Pattern' => [$tagsPattern]],
+ ],
+ ],
+ $this->getRequestsFromLog()
+ );
+ }
+
+ private function startMockServer(): void
+ {
+ $objectManager = Bootstrap::getObjectManager();
+ /** @var PhpExecutableFinder $phpExecutableFinder */
+ $phpExecutableFinder = $objectManager->get(PhpExecutableFinder::class);
+ $mockServerCmd = $phpExecutableFinder->find() . ' ' . self::MOCK_SERVER_DIR . '/server.php';
+ //the following needs Symfony Process >= 4.2.0
+// $this->mockServerProcess = Process::fromShellCommandline($mockServerCmd);
+ //so we use the old way to instantiate Process from string:
+ $this->mockServerProcess = new Process($mockServerCmd);
+ $this->mockServerProcess->start();
+ //the following needs Symfony Process >= 4.2.0
+// $this->mockServerProcess->waitUntil(
+// function($output) {
+// return $output === 'Started';
+// }
+// );
+ // so we wait a second or two instead:
+ sleep(2);
+ }
+
+ private function stopMockServer(): void
+ {
+ // issue: this only kills the parent shell script, not the PHP process (Symfony Process 4.1)
+// $this->mockServerProcess->stop();
+ // so we implemented a kill switch in the server:
+ $ch = \curl_init('http://127.0.0.1:8082/?kill=1');
+ \curl_exec($ch);
+ }
+
+ private function createRequestLog(): void
+ {
+ \file_put_contents(self::REQUEST_LOG_FILE, '');
+ \chmod(self::REQUEST_LOG_FILE, 0666);
+ }
+
+ private function getRequestsFromLog(): array
+ {
+ $requests = \array_map(
+ function (string $line): array {
+ return \json_decode($line, true);
+ },
+ \file(self::REQUEST_LOG_FILE)
+ );
+ return $requests;
+ }
+}
diff --git a/tests/Integration/TagRepositoryTest.php b/tests/Integration/TagRepositoryTest.php
new file mode 100644
index 0000000..662baa0
--- /dev/null
+++ b/tests/Integration/TagRepositoryTest.php
@@ -0,0 +1,21 @@
+get(TagRepository::class);
+ }
+}
diff --git a/tests/Integration/VarnishMock/.gitignore b/tests/Integration/VarnishMock/.gitignore
new file mode 100644
index 0000000..89267c3
--- /dev/null
+++ b/tests/Integration/VarnishMock/.gitignore
@@ -0,0 +1 @@
+/.requests.log
\ No newline at end of file
diff --git a/tests/Integration/VarnishMock/server.php b/tests/Integration/VarnishMock/server.php
new file mode 100644
index 0000000..17a1dc9
--- /dev/null
+++ b/tests/Integration/VarnishMock/server.php
@@ -0,0 +1,38 @@
+getQueryParams()['kill'] ?? false) {
+ exit;
+ }
+ $requestJson = \json_encode(
+ [
+ 'method' => $request->getMethod(),
+ 'headers' => $request->getHeaders()
+ ]
+ );
+ \file_put_contents(__DIR__ . '/.requests.log', $requestJson . "\n", FILE_APPEND);
+
+ return new \React\Http\Response(
+ 200,
+ array(
+ 'Content-Type' => 'text/plain'
+ ),
+ "OK\n"
+ );
+});
+
+$socket = new \React\Socket\Server(8082, $loop);
+$server->listen($socket);
+
+echo "Started";
+
+$loop->run();
diff --git a/tests/Unit/FakeTagRepositoryTest.php b/tests/Unit/FakeTagRepositoryTest.php
new file mode 100644
index 0000000..be3743a
--- /dev/null
+++ b/tests/Unit/FakeTagRepositoryTest.php
@@ -0,0 +1,17 @@
+
+
+
+ ../../../vendor/integer-net/magento2-async-varnish/tests/Unit
+
+
+
+
+
+
+
+ ../../src/app/code/*
+
+ ../../src/app/code/*/*/Test
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/src/FakeTagRepository.php b/tests/src/FakeTagRepository.php
new file mode 100644
index 0000000..229283e
--- /dev/null
+++ b/tests/src/FakeTagRepository.php
@@ -0,0 +1,57 @@
+tags = array_merge($this->tags, $tags);
+ return count($tags);
+ }
+
+ public function deleteUpToId(int $maxId = 0): int
+ {
+ $deleted = 0;
+ foreach ($this->tags as $key => $tag) {
+ if ($key <= $maxId) {
+ unset($this->tags[$key]);
+ ++$deleted;
+ }
+ }
+ return $deleted;
+ }
+
+ public function getAll(): array
+ {
+ return array_unique($this->tags);
+ }
+
+ public function getLastUsedId(): int
+ {
+ return array_key_last($this->tags);
+ }
+
+}
+
+/*
+ * PHP 7.2 Polyfill
+ */
+if (!\function_exists('array_key_last')) {
+ function array_key_last(array $array)
+ {
+ if (empty($array)) {
+ return null;
+ }
+
+ return key(array_slice($array, -1, 1, true));
+ }
+}
\ No newline at end of file
pFad - Phonifier reborn
Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies:
Alternative Proxy
pFad Proxy
pFad v3 Proxy
pFad v4 Proxy