Skip to content

Add tests for Tag Repository and a mock webserver for Varnish integration tests #3

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
Open
8 changes: 8 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
5 changes: 5 additions & 0 deletions .travis/before_script.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
23 changes: 23 additions & 0 deletions .travis/merge-dev.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php
/*
* Merge autoload-dev and require-dev from one composer.json into another one
*
* This is used to install the module within a Magento 2 installation, but with its dev dependencies
*/
declare(strict_types=1);

$fromFile = $argv[1];
$toFile = $argv[2];

$fromJson = json_decode(file_get_contents($fromFile), true);
$toJson = json_decode(file_get_contents($toFile), true);

foreach ($fromJson['autoload-dev']['psr-4'] ?? [] as $key => $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));
9 changes: 7 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,22 @@
"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",
"url": "https://repo.magento.com/"
}
],
"require-dev": {
"magento/magento-coding-standard": "@dev"
"react/http": "0.8.5"
}
}
37 changes: 37 additions & 0 deletions src/Api/TagRepositoryInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php
declare(strict_types=1);

namespace IntegerNet\AsyncVarnish\Api;

interface TagRepositoryInterface
{
/**
* Insert multiple Tags
*
* @param string[] $tags
* @return int
* @throws \Exception
*/
public function insertMultiple(array $tags = []): int;

/**
* Delete multiple Tags by max entity_id
*
* @param int $maxId
* @return int
* @throws \Exception
*/
public function deleteUpToId(int $maxId = 0): int;

/**
* @throws \Zend_Db_Statement_Exception
*/
public function getAll(): array;

/**
* Return last ID (after getAll() call)
*
* @return int
*/
public function getLastUsedId(): int;
}
6 changes: 3 additions & 3 deletions src/Model/PurgeAsyncCache.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@

namespace IntegerNet\AsyncVarnish\Model;

use Magento\CacheInvalidate\Model\PurgeCache as PurgeCache;
use IntegerNet\AsyncVarnish\Model\TagRepository as TagRepository;
use Magento\CacheInvalidate\Model\PurgeCache;
use IntegerNet\AsyncVarnish\Model\TagRepository;
use Magento\Framework\App\Config\ScopeConfigInterface;

class PurgeAsyncCache
Expand Down Expand Up @@ -46,7 +46,7 @@ private function getMaxHeaderLengthFromConfig()
* @throws \Zend_Db_Statement_Exception
* @throws \Exception
*/
public function run():int
public function run(): int
{
$tags = $this->tagRepository->getAll();
$maxHeaderLength = $this->getMaxHeaderLengthFromConfig();
Expand Down
7 changes: 3 additions & 4 deletions src/Model/ResourceModel/Tag.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
);
Expand All @@ -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'
Expand Down
28 changes: 14 additions & 14 deletions src/Model/TagRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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;

/**
Expand Down Expand Up @@ -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);
}

/**
Expand All @@ -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;
Expand Down Expand Up @@ -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);
Expand All @@ -103,10 +107,9 @@ public function deleteUpToId($maxId = 0)
}

/**
* @return array
* @throws \Zend_Db_Statement_Exception
*/
public function getAll()
public function getAll(): array
{

$tags = [];
Expand All @@ -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;
}
Expand Down
2 changes: 2 additions & 0 deletions src/etc/di.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,6 @@
</argument>
</arguments>
</type>
<preference for="IntegerNet\AsyncVarnish\Api\TagRepositoryInterface"
type="IntegerNet\AsyncVarnish\Model\TagRepository" />
</config>
78 changes: 78 additions & 0 deletions tests/Integration/AbstractTagRepositoryTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
<?php
declare(strict_types=1);

namespace IntegerNet\AsyncVarnish\Test\Integration;

use IntegerNet\AsyncVarnish\Api\TagRepositoryInterface;
use PHPUnit\Framework\TestCase;

abstract class AbstractTagRepositoryTest extends TestCase
{
/**
* @var TagRepositoryInterface
*/
protected $tagRepository;

protected function setUp()
{
$this->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);
}
}
44 changes: 44 additions & 0 deletions tests/Integration/ModuleTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?php
declare(strict_types=1);

namespace IntegerNet\AsyncVarnish\Test\Integration;

use Magento\Framework\Component\ComponentRegistrar;
use Magento\Framework\Module\ModuleList;
use Magento\TestFramework\ObjectManager;
use PHPUnit\Framework\TestCase;

class ModuleTest extends TestCase
{

/**
* @var ObjectManager
*/
private $objectManager;
const MODULE_NAME = 'IntegerNet_AsyncVarnish';
/**
* @return ModuleList
*/
private function getTestModuleList()
{
/** @var ModuleList $moduleList */
$moduleList = $this->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');
}

}
Loading