mirror of
https://github.com/Combodo/iTop.git
synced 2026-08-30 09:58:17 +02:00
N°5655 - Introduce auto-routing mechanism for backoffice pages (Part 1)
This commit is contained in:
@@ -352,6 +352,7 @@ return array(
|
||||
'Combodo\\iTop\\Controller\\Base\\Layout\\ObjectController' => $baseDir . '/sources/Controller/Base/Layout/ObjectController.php',
|
||||
'Combodo\\iTop\\Controller\\OAuth\\OAuthLandingController' => $baseDir . '/sources/Controller/OAuth/OAuthLandingController.php',
|
||||
'Combodo\\iTop\\Controller\\PreferencesController' => $baseDir . '/sources/Controller/PreferencesController.php',
|
||||
'Combodo\\iTop\\Controller\\iController' => $baseDir . '/sources/Controller/iController.php',
|
||||
'Combodo\\iTop\\Core\\Authentication\\Client\\OAuth\\IOAuthClientProvider' => $baseDir . '/sources/Core/Authentication/Client/OAuth/IOAuthClientProvider.php',
|
||||
'Combodo\\iTop\\Core\\Authentication\\Client\\OAuth\\OAuthClientProviderAbstract' => $baseDir . '/sources/Core/Authentication/Client/OAuth/OAuthClientProviderAbstract.php',
|
||||
'Combodo\\iTop\\Core\\Authentication\\Client\\OAuth\\OAuthClientProviderAzure' => $baseDir . '/sources/Core/Authentication/Client/OAuth/OAuthClientProviderAzure.php',
|
||||
@@ -415,6 +416,7 @@ return array(
|
||||
'Combodo\\iTop\\Renderer\\FieldRenderer' => $baseDir . '/sources/Renderer/FieldRenderer.php',
|
||||
'Combodo\\iTop\\Renderer\\FormRenderer' => $baseDir . '/sources/Renderer/FormRenderer.php',
|
||||
'Combodo\\iTop\\Renderer\\RenderingOutput' => $baseDir . '/sources/Renderer/RenderingOutput.php',
|
||||
'Combodo\\iTop\\Router\\Router' => $baseDir . '/sources/Router/Router.php',
|
||||
'Combodo\\iTop\\Service\\EventData' => $baseDir . '/sources/Application/Service/EventData.php',
|
||||
'Combodo\\iTop\\Service\\EventHelper' => $baseDir . '/sources/Application/Service/EventHelper.php',
|
||||
'Combodo\\iTop\\Service\\EventService' => $baseDir . '/sources/Application/Service/EventService.php',
|
||||
|
||||
@@ -717,6 +717,7 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
|
||||
'Combodo\\iTop\\Controller\\Base\\Layout\\ObjectController' => __DIR__ . '/../..' . '/sources/Controller/Base/Layout/ObjectController.php',
|
||||
'Combodo\\iTop\\Controller\\OAuth\\OAuthLandingController' => __DIR__ . '/../..' . '/sources/Controller/OAuth/OAuthLandingController.php',
|
||||
'Combodo\\iTop\\Controller\\PreferencesController' => __DIR__ . '/../..' . '/sources/Controller/PreferencesController.php',
|
||||
'Combodo\\iTop\\Controller\\iController' => __DIR__ . '/../..' . '/sources/Controller/iController.php',
|
||||
'Combodo\\iTop\\Core\\Authentication\\Client\\OAuth\\IOAuthClientProvider' => __DIR__ . '/../..' . '/sources/Core/Authentication/Client/OAuth/IOAuthClientProvider.php',
|
||||
'Combodo\\iTop\\Core\\Authentication\\Client\\OAuth\\OAuthClientProviderAbstract' => __DIR__ . '/../..' . '/sources/Core/Authentication/Client/OAuth/OAuthClientProviderAbstract.php',
|
||||
'Combodo\\iTop\\Core\\Authentication\\Client\\OAuth\\OAuthClientProviderAzure' => __DIR__ . '/../..' . '/sources/Core/Authentication/Client/OAuth/OAuthClientProviderAzure.php',
|
||||
@@ -780,6 +781,7 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
|
||||
'Combodo\\iTop\\Renderer\\FieldRenderer' => __DIR__ . '/../..' . '/sources/Renderer/FieldRenderer.php',
|
||||
'Combodo\\iTop\\Renderer\\FormRenderer' => __DIR__ . '/../..' . '/sources/Renderer/FormRenderer.php',
|
||||
'Combodo\\iTop\\Renderer\\RenderingOutput' => __DIR__ . '/../..' . '/sources/Renderer/RenderingOutput.php',
|
||||
'Combodo\\iTop\\Router\\Router' => __DIR__ . '/../..' . '/sources/Router/Router.php',
|
||||
'Combodo\\iTop\\Service\\EventData' => __DIR__ . '/../..' . '/sources/Application/Service/EventData.php',
|
||||
'Combodo\\iTop\\Service\\EventHelper' => __DIR__ . '/../..' . '/sources/Application/Service/EventHelper.php',
|
||||
'Combodo\\iTop\\Service\\EventService' => __DIR__ . '/../..' . '/sources/Application/Service/EventService.php',
|
||||
|
||||
2794
pages/UI.php
2794
pages/UI.php
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -10,20 +10,16 @@ namespace Combodo\iTop\Controller;
|
||||
* Class AbstractController
|
||||
*
|
||||
* Abstract controller to centralize common features of business controllers which are still to be defined.
|
||||
* Note that this can be extended by "TwigBase" controllers or standalone controllers.
|
||||
*
|
||||
* @author Guillaume Lajarige <guillaume.lajarige@combodo.com>
|
||||
* @package Combodo\iTop\Controller
|
||||
* @since 3.1.0
|
||||
*/
|
||||
class AbstractController
|
||||
abstract class AbstractController implements iController
|
||||
{
|
||||
/**
|
||||
* It works if your JavaScript library sets an X-Requested-With HTTP header.
|
||||
* It is known to work with common JavaScript frameworks: {@link https://wikipedia.org/wiki/List_of_Ajax_frameworks#JavaScript}
|
||||
*
|
||||
* @see \Symfony\Component\HttpFoundation\Request::isXmlHttpRequest() Inspired by
|
||||
*
|
||||
* @return bool True if the current request is an XmlHttpRequest (eg. an AJAX request)
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function IsHandlingXmlHttpRequest(): bool
|
||||
{
|
||||
|
||||
@@ -11,6 +11,7 @@ use ApplicationException;
|
||||
use cmdbAbstractObject;
|
||||
use CMDBObjectSet;
|
||||
use Combodo\iTop\Application\UI\Base\Layout\PageContent\PageContentFactory;
|
||||
use Combodo\iTop\Controller\AbstractController;
|
||||
use Dict;
|
||||
use iTopWebPage;
|
||||
use MetaModel;
|
||||
@@ -27,12 +28,9 @@ use WebPage;
|
||||
* @since 3.1.0
|
||||
* @package Combodo\iTop\Controller\Base\Layout
|
||||
*/
|
||||
class ObjectController extends \Combodo\iTop\Controller\AbstractController
|
||||
class ObjectController extends AbstractController
|
||||
{
|
||||
public function View()
|
||||
{
|
||||
|
||||
}
|
||||
public const ROUTE_NAMESPACE = 'object';
|
||||
|
||||
/**
|
||||
* @return \iTopWebPage|\AjaxPage Object edit form in its webpage
|
||||
@@ -41,15 +39,12 @@ class ObjectController extends \Combodo\iTop\Controller\AbstractController
|
||||
* @throws \CoreException
|
||||
* @throws \SecurityException
|
||||
*/
|
||||
public function Modify()
|
||||
public function OperationModify()
|
||||
{
|
||||
$bPrintable = utils::ReadParam('printable', '0') === '1';
|
||||
$sClass = utils::ReadParam('class', '', false, 'class');
|
||||
$sId = utils::ReadParam('id', '');
|
||||
|
||||
$sClass = 'Person';
|
||||
$sId = 6;
|
||||
|
||||
// Check parameters
|
||||
if (utils::IsNullOrEmptyString($sClass) || utils::IsNullOrEmptyString($sId))
|
||||
{
|
||||
|
||||
30
sources/Controller/iController.php
Normal file
30
sources/Controller/iController.php
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2022 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\Controller;
|
||||
|
||||
/**
|
||||
* @author Guillaume Lajarige <guillaume.lajarige@combodo.com>
|
||||
* @since 3.1.0
|
||||
* @package Combodo\iTop\Controller
|
||||
*/
|
||||
interface iController
|
||||
{
|
||||
/**
|
||||
* @var string|null Meant for overlaoding. Route namespace, what will prefix the "route" parameter to define in which namespoce the operation is to be executed. If left to `null`, the controller will be ignored.
|
||||
*/
|
||||
public const ROUTE_NAMESPACE = null;
|
||||
|
||||
/**
|
||||
* It works if your JavaScript library sets an X-Requested-With HTTP header.
|
||||
* It is known to work with common JavaScript frameworks: {@link https://wikipedia.org/wiki/List_of_Ajax_frameworks#JavaScript}
|
||||
*
|
||||
* @see \Symfony\Component\HttpFoundation\Request::isXmlHttpRequest() Inspired by
|
||||
*
|
||||
* @return bool True if the current request is an XmlHttpRequest (eg. an AJAX request)
|
||||
*/
|
||||
public function IsHandlingXmlHttpRequest(): bool;
|
||||
}
|
||||
183
sources/Router/Router.php
Normal file
183
sources/Router/Router.php
Normal file
@@ -0,0 +1,183 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2022 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\Router;
|
||||
|
||||
use utils;
|
||||
|
||||
/**
|
||||
* Class Router
|
||||
*
|
||||
* Service to find the corresponding controller / method for a given "route" parameter
|
||||
*
|
||||
* @author Guillaume Lajarige <guillaume.lajarige@combodo.com>
|
||||
* @package Combodo\iTop\Router
|
||||
* @since 3.1.0
|
||||
* @internal
|
||||
*/
|
||||
class Router
|
||||
{
|
||||
/** @var \Combodo\iTop\Router\Router|null Singleton instance */
|
||||
protected static ?Router $oSingleton = null;
|
||||
|
||||
/**
|
||||
* @return $this The singleton instance of the router
|
||||
*/
|
||||
public static function GetInstance()
|
||||
{
|
||||
if (null === static::$oSingleton) {
|
||||
static::$oSingleton = new static();
|
||||
}
|
||||
|
||||
return static::$oSingleton;
|
||||
}
|
||||
|
||||
/**********************/
|
||||
/* Non-static methods */
|
||||
/**********************/
|
||||
|
||||
/**
|
||||
* Singleton pattern, can't use the constructor. Use {@see \Combodo\iTop\Router\Router::GetInstance()} instead.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function __construct()
|
||||
{
|
||||
// Don't do anything, we don't want to be initialized
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sRoute
|
||||
*
|
||||
* @return bool True if there is a matching handler for $sRoute
|
||||
*/
|
||||
public function CanDispatchRoute(string $sRoute): bool
|
||||
{
|
||||
return $this->GetDispatchSpecsForRoute($sRoute) !== null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatch the current request to the matching handler for $sRoute
|
||||
*
|
||||
* @param string $sRoute
|
||||
*
|
||||
* @return mixed Response from the route's handler, can be anything.
|
||||
* Even though it can be anything, in most cases, response will either be:
|
||||
* - A \WebPage for usual backoffice operations
|
||||
* - null for TwigBase backoffice operations
|
||||
*/
|
||||
public function DispatchRoute(string $sRoute)
|
||||
{
|
||||
$aMethodSpecs = $this->GetDispatchSpecsForRoute($sRoute);
|
||||
$mResponse = call_user_func_array([new $aMethodSpecs[0](), $aMethodSpecs[1]], []);
|
||||
|
||||
return $mResponse;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sRoute
|
||||
*
|
||||
* @return array{sControllerFQCN, sOperationMethodName}|null The FQCN controller and operation method matching $sRoute, null if no matching handler
|
||||
*/
|
||||
public function GetDispatchSpecsForRoute(string $sRoute)
|
||||
{
|
||||
$aRouteParts = $this->GetRouteParts($sRoute);
|
||||
if (is_null($aRouteParts)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$sRouteNamespace = $aRouteParts['namespace'];
|
||||
$sRouteOperation = $aRouteParts['operation'];
|
||||
$sControllerFQCN = $this->FindControllerFromRouteNamespace($sRouteNamespace);
|
||||
if (utils::IsNullOrEmptyString($sControllerFQCN)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$sOperationMethodName = $this->MakeOperationMethodNameFromOperation($sRouteOperation);
|
||||
$aMethodSpecs = [$sControllerFQCN, $sOperationMethodName];
|
||||
if (false === is_callable($aMethodSpecs)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $aMethodSpecs;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sRoute
|
||||
*
|
||||
* @return array{namespace: string, operation: string}|null Route parts (namespace and operation) if route can be parsed, null otherwise
|
||||
*/
|
||||
public function GetRouteParts(string $sRoute)
|
||||
{
|
||||
if (utils::IsNullOrEmptyString($sRoute)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$sRouteNamespace = $this->GetRouteNamespace($sRoute);
|
||||
$sRouteOperation = $this->GetRouteOperation($sRoute);
|
||||
if (utils::IsNullOrEmptyString($sRouteNamespace) || utils::IsNullOrEmptyString($sRouteOperation)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return ['namespace' => $sRouteNamespace, 'operation' => $sRouteOperation];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sRoute
|
||||
*
|
||||
* @return string|null Namespace of the route (eg. "object" for "object.modify") if route can be parsed null otherwise
|
||||
*/
|
||||
public function GetRouteNamespace(string $sRoute): ?string
|
||||
{
|
||||
$mSeparatorPos = strripos($sRoute, '.', -1);
|
||||
if (false === $mSeparatorPos) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return substr($sRoute, 0, $mSeparatorPos);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sRoute
|
||||
*
|
||||
* @return string|null Operation of the route (eg. "modify" for "object.modify") if route can be parsed null otherwise
|
||||
*/
|
||||
public function GetRouteOperation(string $sRoute): ?string
|
||||
{
|
||||
$mSeparatorPos = strripos($sRoute, '.', -1);
|
||||
if (false === $mSeparatorPos) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return substr($sRoute, $mSeparatorPos + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sRouteNamespace {@see static::$sRouteNamespace}
|
||||
*
|
||||
* @return string|null The FQCN of the controller matching the $sRouteNamespace, null if none matching.
|
||||
*/
|
||||
protected function FindControllerFromRouteNamespace(string $sRouteNamespace): ?string
|
||||
{
|
||||
foreach (utils::GetClassesForInterface('Combodo\iTop\Controller\iController', '', ['[\\\\/]lib[\\\\/]', '[\\\\/]node_modules[\\\\/]', '[\\\\/]test[\\\\/]']) as $sControllerFQCN) {
|
||||
if ($sControllerFQCN::ROUTE_NAMESPACE === $sRouteNamespace) {
|
||||
return $sControllerFQCN;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sOperation
|
||||
*
|
||||
* @return string The method name for the $sOperation regarding the convention
|
||||
*/
|
||||
protected function MakeOperationMethodNameFromOperation(string $sOperation): string
|
||||
{
|
||||
return 'Operation'.utils::ToCamelCase($sOperation);
|
||||
}
|
||||
}
|
||||
205
test/sources/Router/RouterTest.php
Normal file
205
test/sources/Router/RouterTest.php
Normal file
@@ -0,0 +1,205 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2022 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
use Combodo\iTop\Router\Router;
|
||||
use Combodo\iTop\Test\UnitTest\ItopTestCase;
|
||||
|
||||
/**
|
||||
* Class RouterTest
|
||||
*
|
||||
* @author Guillaume Lajarige <guillaume.lajarige@combodo.com>
|
||||
* @since 3.1.0
|
||||
* @covers \Combodo\iTop\Router\Router
|
||||
*/
|
||||
class RouterTest extends ItopTestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider CanDispatchRouteProvider
|
||||
* @covers \Combodo\iTop\Router\Router::CanDispatchRoute
|
||||
*
|
||||
* @param string $sRoute
|
||||
* @param $bExpectedResult
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testCanDispatchRoute(string $sRoute, $bExpectedResult): void
|
||||
{
|
||||
$oRouter = Router::GetInstance();
|
||||
$bTestedResult = $oRouter->CanDispatchRoute($sRoute);
|
||||
|
||||
$sRouteNamespace = $oRouter->GetRouteNamespace($sRoute);
|
||||
$sRouteOperation = $oRouter->GetRouteOperation($sRoute);
|
||||
$aRouteParts = $oRouter->GetRouteParts($sRoute);
|
||||
$sControllerFQCN = $this->InvokeNonPublicMethod(get_class($oRouter), 'FindControllerFromRouteNamespace', $oRouter, ['object']);
|
||||
$sMethodName = $this->InvokeNonPublicMethod(get_class($oRouter), 'MakeOperationMethodNameFromOperation', $oRouter, ['modify']);
|
||||
$aDispatchSpecs = $oRouter->GetDispatchSpecsForRoute($sRoute);
|
||||
|
||||
$this->debug($sRoute);
|
||||
$this->debug($sRouteNamespace);
|
||||
$this->debug($sRouteOperation);
|
||||
$this->debug($aRouteParts);
|
||||
$this->debug($sControllerFQCN);
|
||||
$this->debug($sMethodName);
|
||||
$this->debug(is_callable([$sControllerFQCN, $sMethodName]) ? 'true' : 'false');
|
||||
$this->debug($aDispatchSpecs);
|
||||
$this->debug($bTestedResult);
|
||||
$this->assertEquals($bExpectedResult, $bTestedResult, "Dispatch capability for '$sRoute' was not the expected one. Got ".var_export($bTestedResult, true).", expected ".var_export($bExpectedResult, true));
|
||||
}
|
||||
|
||||
public function CanDispatchRouteProvider(): array
|
||||
{
|
||||
return [
|
||||
'Existing handler' => [
|
||||
'object.modify',
|
||||
true,
|
||||
],
|
||||
'Existing controller but unknown operation' => [
|
||||
'object.modify_me_please',
|
||||
false,
|
||||
],
|
||||
'Unknown controller' => [
|
||||
'foo.bar',
|
||||
false,
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider GetRouteNamespaceProvider
|
||||
* @covers \Combodo\iTop\Router\Router::GetRouteNamespace
|
||||
*
|
||||
* @param string $sRoute
|
||||
* @param string|null $sExpectedNamespace
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testGetRouteNamespace(string $sRoute, ?string $sExpectedNamespace): void
|
||||
{
|
||||
$oRouter = Router::GetInstance();
|
||||
$sTestedNamespace = $oRouter->GetRouteNamespace($sRoute);
|
||||
|
||||
$this->assertEquals($sExpectedNamespace, $sTestedNamespace, "Namespace found for '$sRoute' was not the expected one. Got '$sTestedNamespace', expected '$sExpectedNamespace'.");
|
||||
}
|
||||
|
||||
public function GetRouteNamespaceProvider(): array
|
||||
{
|
||||
return [
|
||||
'Operation without namespace' => [
|
||||
'some_operation',
|
||||
null,
|
||||
],
|
||||
'Operation with namespace' => [
|
||||
'some_namespace.some_operation',
|
||||
'some_namespace',
|
||||
],
|
||||
'Operation with multi-levels namespace' => [
|
||||
'some.deep.namespace.some_operation',
|
||||
'some.deep.namespace',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider GetRouteOperationProvider
|
||||
* @covers \Combodo\iTop\Router\Router::GetRouteOperation
|
||||
*
|
||||
* @param string $sRoute
|
||||
* @param string|null $sExpectedOperation
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testGetRouteOperation(string $sRoute, ?string $sExpectedOperation): void
|
||||
{
|
||||
$oRouter = Router::GetInstance();
|
||||
$sTestedOperation = $oRouter->GetRouteOperation($sRoute);
|
||||
|
||||
$this->assertEquals($sExpectedOperation, $sTestedOperation, "Operation found for '$sRoute' was not the expected one. Got '$sTestedOperation', expected '$sExpectedOperation'.");
|
||||
}
|
||||
|
||||
public function GetRouteOperationProvider(): array
|
||||
{
|
||||
return [
|
||||
'Operation without namespace' => [
|
||||
'some_operation',
|
||||
null,
|
||||
],
|
||||
'Operation with namespace' => [
|
||||
'some_namespace.some_operation',
|
||||
'some_operation',
|
||||
],
|
||||
'Operation with multi-levels namespace' => [
|
||||
'some.deep.namespace.some_operation',
|
||||
'some_operation',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider FindControllerFromRouteNamespaceProvider
|
||||
* @covers \Combodo\iTop\Router\Router::FindControllerFromRouteNamespace
|
||||
*
|
||||
* @param string $sRouteNamespace
|
||||
* @param string $sExpectedControllerFQCN
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testFindControllerFromRouteNamespace(string $sRoute, ?string $sExpectedControllerFQCN): void
|
||||
{
|
||||
$oRouter = Router::GetInstance();
|
||||
$sRouteNamespace = $oRouter->GetRouteNamespace($sRoute);
|
||||
|
||||
$sTestedControllerFQCN = $this->InvokeNonPublicMethod(get_class($oRouter), 'FindControllerFromRouteNamespace', $oRouter, [$sRouteNamespace]);
|
||||
|
||||
$this->assertEquals($sExpectedControllerFQCN, $sTestedControllerFQCN, "Controller found for '$sRouteNamespace' was not the expected one. Got '$sTestedControllerFQCN', expected '$sExpectedControllerFQCN'.");
|
||||
}
|
||||
|
||||
public function FindControllerFromRouteNamespaceProvider(): array
|
||||
{
|
||||
return [
|
||||
'Object controller' => [
|
||||
'object.modify',
|
||||
'Combodo\iTop\Controller\Base\Layout\ObjectController',
|
||||
],
|
||||
'Unknown controller' => [
|
||||
'something_that_should_not_exist_in_the_default_package.foo',
|
||||
null,
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider GetOperationMethodNameFromRouteOperationProvider
|
||||
* @covers \Combodo\iTop\Router\Router::MakeOperationMethodNameFromOperation
|
||||
*
|
||||
* @param string $sRoute
|
||||
* @param string $sExpectedMethodName
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testGetOperationMethodNameFromRouteOperation(string $sRoute, string $sExpectedMethodName): void
|
||||
{
|
||||
$oRouter = Router::GetInstance();
|
||||
$aRouteParts = $oRouter->GetRouteParts($sRoute);
|
||||
|
||||
$sTestedMethodName = $this->InvokeNonPublicMethod(get_class($oRouter), 'MakeOperationMethodNameFromOperation', $oRouter, [$aRouteParts[1]]);
|
||||
|
||||
$this->assertEquals($sExpectedMethodName, $sTestedMethodName, "Operation method name '$aRouteParts[1]' was not matching the expected one. Got '$sTestedMethodName', expected '$sExpectedMethodName'.");
|
||||
}
|
||||
|
||||
public function GetOperationMethodNameFromRouteOperationProvider(): array
|
||||
{
|
||||
return [
|
||||
'Simple operation' => [
|
||||
'object.modify',
|
||||
'OperationModify',
|
||||
],
|
||||
'Operation with an underscore' => [
|
||||
'object.apply_modify',
|
||||
'OperationApplyModify',
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user