Skip to content
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

fix: feature flag for xml editor #2418

Merged
merged 13 commits into from
Dec 6, 2023
2 changes: 1 addition & 1 deletion actions/class.XmlEditor.php
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,6 @@ public function edit(): void
*/
private function getXmlEditorService(): XmlEditorInterface
{
return $this->getServiceLocator()->get(XmlEditorInterface::SERVICE_ID);
return $this->getServiceLocator()->getContainer()->get(XmlEditorInterface::class);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,6 @@
*
*/

declare(strict_types=1);

use oat\taoQtiTest\models\xmlEditor\XmlEditor;

return new XmlEditor([
XmlEditor::OPTION_XML_EDITOR_LOCK => true
]);
return [XmlEditor::OPTION_XML_EDITOR_LOCK => true];
58 changes: 58 additions & 0 deletions migrations/Version202311291155452260_taoQtiTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<?php

/**
* 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; under version 2
* of the License (non-upgradable).
*
* 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.
*
* Copyright (c) 2023 (original work) Open Assessment Technologies SA;
*/

declare(strict_types=1);

namespace oat\taoQtiTest\migrations;

use common_ext_Extension as Extension;
use common_ext_ExtensionsManager as ExtensionsManager;
use Doctrine\DBAL\Schema\Schema;
use oat\tao\scripts\tools\migrations\AbstractMigration;

final class Version202311291155452260_taoQtiTest extends AbstractMigration
{
public function getDescription(): string
{
return 'Configure default `xmlEditor` value for the new config format.';
}

public function up(Schema $schema): void
{
$oldXmlConfigKey = 'XmlEditor';
$newXmlConfigKey = 'xmlEditor';
$extension = $this->getExtension();
$extension->unsetConfig($oldXmlConfigKey);
$extension->setConfig($newXmlConfigKey, ['is_locked' => true]);
}

public function down(Schema $schema): void
{
$this->throwIrreversibleMigrationException();
}

private function getExtension(): Extension
{
return $this->getServiceLocator()
->getContainer()
->get(ExtensionsManager::SERVICE_ID)
->getExtensionById('taoQtiTest');
}
}
19 changes: 17 additions & 2 deletions model/Container/TestQtiServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,18 @@

namespace oat\taoQtiTest\model\Container;

use common_ext_ExtensionsManager;
use oat\generis\model\data\Ontology;
use oat\generis\model\DependencyInjection\ContainerServiceProviderInterface;
use oat\oatbox\event\EventManager;
use oat\oatbox\log\LoggerService;
use oat\taoQtiItem\model\qti\Service;
use oat\tao\model\featureFlag\FeatureFlagChecker;
use oat\taoQtiTest\model\Domain\Model\ItemResponseRepositoryInterface;
use oat\taoQtiTest\model\Domain\Model\QtiTestRepositoryInterface;
use oat\taoQtiTest\model\Domain\Model\ToolsStateRepositoryInterface;
use oat\taoQtiTest\model\Infrastructure\QtiItemResponseRepository;
use oat\taoQtiTest\model\Infrastructure\QtiToolsStateRepository;
use oat\taoQtiTest\model\Infrastructure\QtiTestRepository;
use oat\taoQtiTest\model\Infrastructure\QtiToolsStateRepository;
use oat\taoQtiTest\model\Service\ExitTestService;
use oat\taoQtiTest\model\Service\ListItemsService;
use oat\taoQtiTest\model\Service\MoveService;
Expand All @@ -44,7 +45,10 @@
use oat\taoQtiTest\model\Service\TimeoutService;
use oat\taoQtiTest\models\runner\QtiRunnerService;
use oat\taoQtiTest\models\TestModelService;
use oat\taoQtiTest\models\xmlEditor\XmlEditor;
use oat\taoQtiTest\models\xmlEditor\XmlEditorInterface;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
use taoQtiTest_models_classes_QtiTestService;

use function Symfony\Component\DependencyInjection\Loader\Configurator\service;

Expand Down Expand Up @@ -156,5 +160,16 @@ public function __invoke(ContainerConfigurator $configurator): void
service(TestModelService::SERVICE_ID),
]
);

$services
->set(XmlEditorInterface::class, XmlEditor::class)
->public()
->args(
[
service(common_ext_ExtensionsManager::SERVICE_ID),
service(taoQtiTest_models_classes_QtiTestService::class),
service(FeatureFlagChecker::class),
]
);
}
}
48 changes: 30 additions & 18 deletions models/classes/xmlEditor/XmlEditor.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,21 +22,43 @@

namespace oat\taoQtiTest\models\xmlEditor;

use oat\oatbox\service\ConfigurableService;
use common_ext_ExtensionsManager;
use core_kernel_classes_Resource;
use oat\tao\model\featureFlag\FeatureFlagChecker;
use qtism\data\storage\xml\XmlDocument;
use taoQtiTest_models_classes_QtiTestService;
use core_kernel_classes_Resource;

class XmlEditor extends ConfigurableService implements XmlEditorInterface
class XmlEditor implements XmlEditorInterface
{
private const XML_EDITOR_ENABLED = 'XML_EDITOR_ENABLED';
private const FEATURE_FLAG_XML_EDITOR_ENABLED = 'FEATURE_FLAG_XML_EDITOR_ENABLED';
private const CONFIG = 'xmlEditor';

/** @var taoQtiTest_models_classes_QtiTestService */
private taoQtiTest_models_classes_QtiTestService $qtiTestService;

/** @var FeatureFlagChecker */
private FeatureFlagChecker $featureFlagChecker;

private array $options = [];

public function __construct(
common_ext_ExtensionsManager $extensionsManager,
taoQtiTest_models_classes_QtiTestService $qtiTestService,
FeatureFlagChecker $featureFlagChecker
) {
$this->options = $extensionsManager
->getExtensionById('taoQtiTest')
->getConfig(self::CONFIG);
$this->qtiTestService = $qtiTestService;
$this->featureFlagChecker = $featureFlagChecker;
}

/**
* {@inheritdoc}
*/
public function getTestXml(core_kernel_classes_Resource $test): string
{
return $this->getTestService()->getDoc($test)->saveToString();
return $this->qtiTestService->getDoc($test)->saveToString();
}

/**
Expand All @@ -48,28 +70,18 @@ public function saveStringTest(core_kernel_classes_Resource $test, string $testS
$doc->loadFromString($testString, true);
$converter = new \taoQtiTest_models_classes_QtiTestConverter($doc);

return $this->getTestService()->saveJsonTest($test, $converter->toJson());
return $this->qtiTestService->saveJsonTest($test, $converter->toJson());
}

/**
* {@inheritdoc}
*/
public function isLocked(): bool
{
if ($this->getFeatureFlagChecker()->isEnabled(self::XML_EDITOR_ENABLED)) {
if ($this->featureFlagChecker->isEnabled(self::FEATURE_FLAG_XML_EDITOR_ENABLED)) {
return false;
}

return $this->hasOption('is_locked') ? (bool)$this->getOption('is_locked') : true;
}

private function getTestService(): taoQtiTest_models_classes_QtiTestService
{
return $this->getServiceLocator()->get(taoQtiTest_models_classes_QtiTestService::class);
}

private function getFeatureFlagChecker(): FeatureFlagChecker
{
return $this->getServiceManager()->getContainer()->get(FeatureFlagChecker::class);
return isset($this->options['is_locked']) ? (bool)$this->options['is_locked'] : true;
}
}
1 change: 0 additions & 1 deletion models/classes/xmlEditor/XmlEditorInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@

interface XmlEditorInterface
{
public const SERVICE_ID = 'taoQtiTest/XmlEditor';
public const XML_EDITOR_ROLE = 'http://www.tao.lu/Ontologies/generis.rdf#TestXMLEditor';
public const OPTION_XML_EDITOR_LOCK = 'is_locked';

Expand Down
85 changes: 61 additions & 24 deletions test/unit/models/classes/xml/XmlEditorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,13 @@

namespace oat\taoQtiTest\test\unit\models\classes\xml;

use common_ext_Extension;
use common_ext_ExtensionsManager;
use core_kernel_classes_Resource;
use oat\generis\test\TestCase;
use oat\tao\model\featureFlag\FeatureFlagChecker;
use oat\taoQtiTest\models\xmlEditor\XmlEditor;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase as UnitTestCase;
use qtism\data\storage\xml\XmlDocument;
use qtism\data\storage\xml\XmlStorageException;
use SplObjectStorage;
Expand All @@ -33,16 +35,19 @@
use taoQtiTest_models_classes_QtiTestServiceException;
use Zend\ServiceManager\ServiceLocatorInterface;

class XmlEditorTest extends TestCase
class XmlEditorTest extends UnitTestCase
{
/** @var XmlDocument */
private $xmlDoc;

/** @var core_kernel_classes_Resource|MockObject */
private $testResourceMock;

/** @var ServiceLocatorInterface */
private $serviceLocatorMock;
/** @var common_ext_ExtensionsManager|MockObject */
private $extensionsManagerMock;

/** @var common_ext_Extension|MockObject */
private $extensionMock;

/** @var taoQtiTest_models_classes_QtiTestService|MockObject */
private $qtiTestServiceMock;
Expand All @@ -57,26 +62,36 @@ public function setUp(): void
$this->xmlDoc = $doc;

$this->testResourceMock = $this->createMock(core_kernel_classes_Resource::class);

$this->extensionMock = $this->createMock(common_ext_Extension::class);
$this->extensionsManagerMock = $this->createMock(common_ext_ExtensionsManager::class);
$this->extensionsManagerMock
->expects(self::once())
->method('getExtensionById')
->with('taoQtiTest')
->willReturn($this->extensionMock);
$this->qtiTestServiceMock = $this->createMock(taoQtiTest_models_classes_QtiTestService::class);
$this->qtiTestServiceMock
->method('getDoc')
->with($this->testResourceMock)
->willReturn($this->xmlDoc);

$this->featureFlagCheckerMock = $this->createMock(FeatureFlagChecker::class);

$this->serviceLocatorMock = $this->getServiceLocatorMock([
taoQtiTest_models_classes_QtiTestService::class => $this->qtiTestServiceMock,
FeatureFlagChecker::class => $this->featureFlagCheckerMock,
]);
}

public function testGetTestXml()
{
$service = new XmlEditor();
$service->setServiceLocator($this->serviceLocatorMock);
$xmlString = $service->getTestXml($this->testResourceMock);
$this->extensionMock
->expects(self::once())
->method('getConfig')
->with('xmlEditor')
->willReturn([XmlEditor::OPTION_XML_EDITOR_LOCK => true]);

$serviceXmlEditor = new XmlEditor(
$this->extensionsManagerMock,
$this->qtiTestServiceMock,
$this->featureFlagCheckerMock
);

$xmlString = $serviceXmlEditor->getTestXml($this->testResourceMock);
$this->assertEquals($this->xmlDoc->saveToString(), $xmlString);
}

Expand All @@ -87,15 +102,29 @@ public function testGetTestXml()
*/
public function testSaveStringTest()
{
$service = new XmlEditor();
$this->extensionMock
->expects(self::once())
->method('getConfig')
->with('xmlEditor')
->willReturn([XmlEditor::OPTION_XML_EDITOR_LOCK => true]);

$serviceXmlEditor = new XmlEditor(
$this->extensionsManagerMock,
$this->qtiTestServiceMock,
$this->featureFlagCheckerMock
);

// phpcs:disable Generic.Files.LineLength
$xmlMock = <<<'EOL'
<?xml version="1.0" encoding="UTF-8"?>
<assessmentTest xmlns="http://www.imsglobal.org/xsd/imsqti_v2p1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" identifier="UnitTestQtiItem" title="UnitTestQtiItem" toolName="tao" toolVersion="3.4.0-sprint130" xsi:schemaLocation="http://www.imsglobal.org/xsd/imsqti_v2p1 http://www.imsglobal.org/xsd/qti/qtiv2p1/imsqti_v2p1.xsd">
<assessmentTest xmlns="http://www.imsglobal.org/xsd/imsqti_v2p1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
identifier="UnitTestQtiItem" title="UnitTestQtiItem" toolName="tao" toolVersion="3.4.0-sprint130"
xsi:schemaLocation="http://www.imsglobal.org/xsd/imsqti_v2p1 http://www.imsglobal.org/xsd/qti/qtiv2p1/imsqti_v2p1.xsd">
<testPart identifier="testPart-1" navigationMode="linear" submissionMode="individual">
<itemSessionControl maxAttempts="0" showFeedback="false" allowReview="true" showSolution="false" allowComment="false" allowSkipping="true" validateResponses="false"/>
<assessmentSection identifier="assessmentSection-1" required="true" fixed="false" title="Section 1" visible="true" keepTogether="true"/>
<itemSessionControl maxAttempts="0" showFeedback="false" allowReview="true" showSolution="false"
allowComment="false" allowSkipping="true" validateResponses="false"/>
<assessmentSection identifier="assessmentSection-1" required="true" fixed="false" title="Section 1"
visible="true" keepTogether="true"/>
</testPart>
</assessmentTest>
EOL;
Expand Down Expand Up @@ -164,20 +193,28 @@ public function testSaveStringTest()
->method('saveJsonTest')
->with($this->testResourceMock, json_encode($expectArrayTest));

$service->setServiceLocator($this->serviceLocatorMock);
$service->saveStringTest($this->testResourceMock, $xmlMock);
$serviceXmlEditor->saveStringTest($this->testResourceMock, $xmlMock);
}

public function testIsLocked()
{
$service = new XmlEditor([XmlEditor::OPTION_XML_EDITOR_LOCK => false]);
$service->setServiceLocator($this->serviceLocatorMock);
$this->extensionMock
->expects(self::once())
->method('getConfig')
->with('xmlEditor')
->willReturn([XmlEditor::OPTION_XML_EDITOR_LOCK => false]);

$serviceXmlEditor = new XmlEditor(
$this->extensionsManagerMock,
$this->qtiTestServiceMock,
$this->featureFlagCheckerMock
);

$this->featureFlagCheckerMock
->method('isEnabled')
->with('XML_EDITOR_ENABLED')
->with('FEATURE_FLAG_XML_EDITOR_ENABLED')
->willReturn(true);

$this->assertEquals(false, $service->isLocked());
$this->assertEquals(false, $serviceXmlEditor->isLocked());
}
}
Loading