N°6436 - Add unit test to ensure that we don't lose an API during merge between branches

This commit is contained in:
Molkobain
2023-08-18 09:55:45 +02:00
parent 1990ccb5d8
commit a8c689c6c0
2 changed files with 357 additions and 0 deletions

View File

@@ -0,0 +1,124 @@
<?php
/*
* @copyright Copyright (C) 2010-2023 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
*/
namespace Combodo\iTop\Test\UnitTest\Application;
use Combodo\iTop\Test\UnitTest\ItopCustomDatamodelTestCase;
use MetaModel;
use utils;
/**
* @covers \iBackofficeLinkedScriptsExtension
*/
class ApplicationExtensionTest extends ItopCustomDatamodelTestCase
{
protected const ENUM_API_CALL_METHOD_ENUMPLUGINS = 'MetaModel::EnumPlugins';
protected const ENUM_API_CALL_METHOD_GETCLASSESFORINTERFACE = 'utils::GetClassesForInterface';
/**
* @inheritDoc
*/
public function GetDatamodelDeltaAbsPath(): string
{
return __DIR__ . '/Delta/application-extension-usages-in-snippets.xml';
}
/**
* This test ensures that APIs are discovered / registered / called.
*
* It was introduced after {@since N°6436} when some APIs registration in \MetaModel::InitClasses() were lost during a merge {@link https://github.com/Combodo/iTop/commit/6432678de9f635990e22a6512e5b30713c22204a#diff-c94890a26989b5a5ce638f82e8cc7d4c7aa24e6fbb9c2ca89850e8fa4e0e9adaL3004} preventing them from being called when requested. This was hard to detect as it needed an extension to use the lost API to witness that it was no longer called.
*
* For each new API, a new test case should be added here to ensure that we don't lose it later.
* To do so:
* - Add the API to the provider
* - Add a class extending / implementing the API in ./Delta/application-extension-usages-in-snippets.xml
*
* @param string $sAPIFQCN
* @param string $sCallMethod
*
* @return void
* @dataProvider ExtensionAPIRegisteredAndCalledProvider
*/
public function testExtensionAPIRegisteredAndCalled(string $sAPIFQCN, string $sCallMethod)
{
if ($sCallMethod === static::ENUM_API_CALL_METHOD_ENUMPLUGINS) {
$iExtendingClassesCount = count(MetaModel::EnumPlugins($sAPIFQCN));
} else {
$iExtendingClassesCount = count(utils::GetClassesForInterface($sAPIFQCN, '', ['[\\\\/]lib[\\\\/]', '[\\\\/]node_modules[\\\\/]', '[\\\\/]test[\\\\/]', '[\\\\/]tests[\\\\/]']));
}
$this->assertGreaterThan(0, $iExtendingClassesCount, "Found no class extending the $sAPIFQCN API");
}
public function ExtensionAPIRegisteredAndCalledProvider(): array
{
// APIs not concerned by this test:
// * \iRestServiceProvider as it is discovered by iterating over declared classes directly
// * \iLoginUIExtension as it is not iterated directly, only its derived interfaces
return [
\iLoginFSMExtension::class => [
\iLoginFSMExtension::class,
static::ENUM_API_CALL_METHOD_ENUMPLUGINS,
],
\iLogoutExtension::class => [
\iLogoutExtension::class,
static::ENUM_API_CALL_METHOD_ENUMPLUGINS,
],
\iLoginUIExtension::class => [
\iLoginUIExtension::class,
static::ENUM_API_CALL_METHOD_ENUMPLUGINS,
],
\iPreferencesExtension::class => [
\iPreferencesExtension::class,
static::ENUM_API_CALL_METHOD_ENUMPLUGINS,
],
\iApplicationUIExtension::class => [
\iApplicationUIExtension::class,
static::ENUM_API_CALL_METHOD_ENUMPLUGINS,
],
\iApplicationObjectExtension::class => [
\iApplicationObjectExtension::class,
static::ENUM_API_CALL_METHOD_ENUMPLUGINS,
],
\iPopupMenuExtension::class => [
\iPopupMenuExtension::class,
static::ENUM_API_CALL_METHOD_ENUMPLUGINS,
],
\iPageUIExtension::class => [
\iPageUIExtension::class,
static::ENUM_API_CALL_METHOD_ENUMPLUGINS,
],
\iPortalUIExtension::class => [
\iPortalUIExtension::class,
static::ENUM_API_CALL_METHOD_ENUMPLUGINS,
],
\iQueryModifier::class => [
\iQueryModifier::class,
static::ENUM_API_CALL_METHOD_ENUMPLUGINS,
],
\iOnClassInitialization::class => [
\iOnClassInitialization::class,
static::ENUM_API_CALL_METHOD_ENUMPLUGINS,
],
\iModuleExtension::class => [
\iModuleExtension::class,
static::ENUM_API_CALL_METHOD_ENUMPLUGINS,
],
\iKPILoggerExtension::class => [
\iKPILoggerExtension::class,
static::ENUM_API_CALL_METHOD_ENUMPLUGINS,
],
\ModuleHandlerApiInterface::class => [
\ModuleHandlerApiInterface::class,
static::ENUM_API_CALL_METHOD_ENUMPLUGINS,
],
\iNewsroomProvider::class => [
\iNewsroomProvider::class,
static::ENUM_API_CALL_METHOD_ENUMPLUGINS,
],
];
}
}

View File

@@ -0,0 +1,233 @@
<?xml version="1.0" encoding="UTF-8"?>
<itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.7">
<snippets>
<!-- These snippets just implements application/applicationextension.inc.php APIs for the ApplicationExtensionTest unit test -->
<snippet id="ExampleFor_iLoginFSMExtension" _delta="define">
<placement>core</placement>
<rank>0</rank>
<content><![CDATA[
class ExampleFor_iLoginFSMExtension extends \AbstractLoginFSMExtension
{
public function ListSupportedLoginModes()
{
// Do nothing, we just need the class to exists for the unit test
}
}
]]></content>
</snippet>
<snippet id="ExampleFor_iLogoutExtension" _delta="define">
<placement>core</placement>
<rank>0</rank>
<content><![CDATA[
class ExampleFor_iLogoutExtension implements \iLogoutExtension
{
public function LogoutAction()
{
// Do nothing, we just need the class to exists for the unit test
}
public function ListSupportedLoginModes()
{
// Do nothing, we just need the class to exists for the unit test
}
}
]]></content>
</snippet>
<snippet id="ExampleFor_iLoginUIExtension" _delta="define">
<placement>core</placement>
<rank>0</rank>
<content><![CDATA[
class ExampleFor_iLoginUIExtension implements \iLoginUIExtension
{
public function GetTwigContext()
{
// Do nothing, we just need the class to exists for the unit test
}
public function ListSupportedLoginModes()
{
// Do nothing, we just need the class to exists for the unit test
}
}
]]></content>
</snippet>
<snippet id="ExampleFor_iPreferencesExtension" _delta="define">
<placement>core</placement>
<rank>0</rank>
<content><![CDATA[
class ExampleFor_iPreferencesExtension extends \AbstractPreferencesExtension
{
// Do nothing, we just need the class to exists for the unit test
}
]]></content>
</snippet>
<snippet id="ExampleFor_iApplicationUIExtension" _delta="define">
<placement>core</placement>
<rank>0</rank>
<content><![CDATA[
class ExampleFor_iApplicationUIExtension extends \AbstractApplicationUIExtension
{
// Do nothing, we just need the class to exists for the unit test
}
]]></content>
</snippet>
<snippet id="ExampleFor_iApplicationObjectExtension" _delta="define">
<placement>core</placement>
<rank>0</rank>
<content><![CDATA[
class ExampleFor_iApplicationObjectExtension extends \AbstractApplicationObjectExtension
{
// Do nothing, we just need the class to exists for the unit test
}
]]></content>
</snippet>
<snippet id="ExampleFor_iPopupMenuExtension" _delta="define">
<placement>core</placement>
<rank>0</rank>
<content><![CDATA[
class ExampleFor_iPopupMenuExtension implements \iPopupMenuExtension
{
public static function EnumItems($iMenuId, $param)
{
// Do nothing, we just need the class to exists for the unit test
}
}
]]></content>
</snippet>
<snippet id="ExampleFor_ApplicationPopupMenuItem" _delta="define">
<placement>core</placement>
<rank>0</rank>
<content><![CDATA[
class ExampleFor_ApplicationPopupMenuItem extends \ApplicationPopupMenuItem
{
public function GetMenuItem()
{
// Do nothing, we just need the class to exists for the unit test
}
}
]]></content>
</snippet>
<snippet id="ExampleFor_iPageUIExtension" _delta="define">
<placement>core</placement>
<rank>0</rank>
<content><![CDATA[
class ExampleFor_iPageUIExtension extends \AbstractPageUIExtension
{
// Do nothing, we just need the class to exists for the unit test
}
]]></content>
</snippet>
<snippet id="ExampleFor_iPortalUIExtension" _delta="define">
<placement>core</placement>
<rank>0</rank>
<content><![CDATA[
class ExampleFor_iPortalUIExtension extends \AbstractPortalUIExtension
{
// Do nothing, we just need the class to exists for the unit test
}
]]></content>
</snippet>
<snippet id="ExampleFor_iQueryModifier" _delta="define">
<placement>core</placement>
<rank>0</rank>
<content><![CDATA[
class ExampleFor_iQueryModifier implements \iQueryModifier
{
public function __construct()
{
// Do nothing, we just need the class to exists for the unit test
}
public function GetFieldExpression(QueryBuilderContext &$oBuild, $sClass, $sAttCode, $sColId, Expression $oFieldSQLExp, SQLQuery &$oSelect)
{
// Do nothing, we just need the class to exists for the unit test
}
}
]]></content>
</snippet>
<snippet id="ExampleFor_iOnClassInitialization" _delta="define">
<placement>core</placement>
<rank>0</rank>
<content><![CDATA[
class ExampleFor_iOnClassInitialization implements \iOnClassInitialization
{
public function OnAfterClassInitialization($sClass)
{
// Do nothing, we just need the class to exists for the unit test
}
}
]]></content>
</snippet>
<snippet id="ExampleFor_iModuleExtension" _delta="define">
<placement>core</placement>
<rank>0</rank>
<content><![CDATA[
class ExampleFor_iModuleExtension implements \iModuleExtension
{
public function __construct()
{
// Do nothing, we just need the class to exists for the unit test
}
}
]]></content>
</snippet>
<snippet id="ExampleFor_iKPILoggerExtension" _delta="define">
<placement>core</placement>
<rank>0</rank>
<content><![CDATA[
class ExampleFor_iKPILoggerExtension implements \iKPILoggerExtension
{
public function InitStats()
{
// Do nothing, we just need the class to exists for the unit test
}
public function LogOperation($oKpiLogData)
{
// Do nothing, we just need the class to exists for the unit test
}
}
]]></content>
</snippet>
<!-- These snippets just implements core/modulehandler.class.inc.php APIs for the ApplicationExtensionTest unit test -->
<snippet id="ExampleFor_ModuleHandlerApiInterface" _delta="define">
<placement>core</placement>
<rank>0</rank>
<content><![CDATA[
class ExampleFor_ModuleHandlerApiInterface extends \ModuleHandlerAPI
{
// Do nothing, we just need the class to exists for the unit test
}
]]></content>
</snippet>
<!-- These snippets just implements application/newsroomprovider.class.inc.php APIs for the ApplicationExtensionTest unit test -->
<snippet id="ExampleFor_iNewsroomProvider" _delta="define">
<placement>core</placement>
<rank>0</rank>
<content><![CDATA[
class ExampleFor_iNewsroomProvider extends \NewsroomProviderBase
{
public function GetLabel()
{
// Do nothing, we just need the class to exists for the unit test
}
public function GetFetchURL()
{
// Do nothing, we just need the class to exists for the unit test
}
public function GetMarkAllAsReadURL()
{
// Do nothing, we just need the class to exists for the unit test
}
public function GetViewAllURL()
{
// Do nothing, we just need the class to exists for the unit test
}
}
]]></content>
</snippet>
</snippets>
</itop_design>