356 lines
11 KiB
PHP
356 lines
11 KiB
PHP
<?php
|
|
|
|
namespace oat\taoQtiTest\test\unit\models\classes;
|
|
|
|
use common_exception_InconsistentData;
|
|
use core_kernel_classes_Property as KernelProperty;
|
|
use core_kernel_classes_Resource as KernelResource;
|
|
use DOMDocument;
|
|
use oat\generis\model\data\Ontology;
|
|
use oat\generis\model\fileReference\FileReferenceSerializer;
|
|
use oat\generis\test\MockObject;
|
|
use oat\generis\test\TestCase;
|
|
use oat\oatbox\filesystem\Directory;
|
|
use oat\oatbox\filesystem\File;
|
|
use oat\tao\model\service\ApplicationService;
|
|
use oat\taoQtiTest\models\test\AssessmentTestXmlFactory;
|
|
use oat\taoQtiTest\models\test\Template\DefaultConfigurationRegistry;
|
|
use qtism\common\utils\Format;
|
|
use taoQtiTest_models_classes_QtiTestService as QtiTestService;
|
|
use Zend\ServiceManager\ServiceLocatorInterface;
|
|
|
|
class QtiTestServiceTest extends TestCase
|
|
{
|
|
private const TEST_TEMPLATE = <<<'XML'
|
|
<?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="{testId}" title="{testTitle}" toolName="tao" toolVersion="{taoVersion}" 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"/>
|
|
</testPart>
|
|
</assessmentTest>
|
|
XML;
|
|
|
|
private const PLATFORM_VERSION = 'v1-test';
|
|
|
|
/** @var Directory|MockObject */
|
|
private $defaultDirectoryMock;
|
|
|
|
/** @var FileReferenceSerializer|MockObject */
|
|
private $fileReferenceSerializerMock;
|
|
|
|
/** @var KernelProperty|MockObject */
|
|
private $testContentPropertyMock;
|
|
|
|
/** @var AssessmentTestXmlFactory */
|
|
private $xmlFactory;
|
|
|
|
/** @var DefaultConfigurationRegistry */
|
|
private $xmlTemplateOptionsRegistry;
|
|
|
|
/** @var QtiTestService */
|
|
private $sut;
|
|
|
|
/**
|
|
* @before
|
|
*/
|
|
public function init(): void
|
|
{
|
|
$this->defaultDirectoryMock = $this->createMock(Directory::class);
|
|
$this->fileReferenceSerializerMock = $this->createMock(FileReferenceSerializer::class);
|
|
$this->testContentPropertyMock = $this->createMock(KernelProperty::class);
|
|
$this->xmlTemplateOptionsRegistry = $this->createPartialMock(DefaultConfigurationRegistry::class, ['getMap']);
|
|
$this->xmlFactory = new AssessmentTestXmlFactory(
|
|
[
|
|
AssessmentTestXmlFactory::OPTION_CONFIGURATION_REGISTRY => $this->xmlTemplateOptionsRegistry
|
|
]
|
|
);
|
|
|
|
$this->xmlTemplateOptionsRegistry
|
|
->method('getMap')
|
|
->willReturn(
|
|
[
|
|
DefaultConfigurationRegistry::ID => [
|
|
'partIdPrefix' => 'testPart',
|
|
'sectionIdPrefix' => 'assessmentSection',
|
|
'sectionTitlePrefix' => 'Section',
|
|
'categories' => [],
|
|
'navigationMode' => 0,
|
|
'submissionMode' => 0,
|
|
'maxAttempts' => 0,
|
|
],
|
|
]
|
|
);
|
|
|
|
$serviceLocator = $this->creteServiceLocatorMock();
|
|
|
|
$this->xmlFactory->setServiceLocator($serviceLocator);
|
|
$this->xmlTemplateOptionsRegistry->setServiceLocator($serviceLocator);
|
|
|
|
$this->sut = $this->createPartialMock(
|
|
QtiTestService::class,
|
|
['getDefaultDir', 'getQtiTestTemplateFileAsString', 'getServiceManager']
|
|
);
|
|
|
|
$this->sut
|
|
->method('getDefaultDir')
|
|
->willReturn($this->defaultDirectoryMock);
|
|
|
|
$this->sut
|
|
->method('getServiceManager')
|
|
->willReturn($serviceLocator);
|
|
|
|
$this->sut->setServiceLocator($serviceLocator);
|
|
$this->sut->setModel(
|
|
$this->createModelMock()
|
|
);
|
|
}
|
|
|
|
public function testCreateContent(): void
|
|
{
|
|
$test = $this->createTestMock('https://example.com', '0label-with_sømę-exötïč_charæctêrß');
|
|
|
|
/** @noinspection PhpUnhandledExceptionInspection */
|
|
static::assertSame(
|
|
$this->createDirectoryMock(
|
|
$test,
|
|
$this->createNewFileMock($test)
|
|
),
|
|
$this->sut->createContent($test)
|
|
);
|
|
}
|
|
|
|
public function testOverwriteContent(): void
|
|
{
|
|
$test = $this->createTestMock('https://example.com', 'label');
|
|
|
|
/** @noinspection PhpUnhandledExceptionInspection */
|
|
static::assertSame(
|
|
$this->createDirectoryMock(
|
|
$test,
|
|
$this->createNewFileMock($test),
|
|
true,
|
|
false
|
|
),
|
|
$this->sut->createContent($test, true, false)
|
|
);
|
|
}
|
|
|
|
public function testExceptionOnExistingContent(): void
|
|
{
|
|
$test = $this->createTestMock('https://example.com', 'label');
|
|
|
|
$this->expectExceptionObject(
|
|
new common_exception_InconsistentData("Data directory for test {$test->getUri()} already exists.")
|
|
);
|
|
|
|
$this->createDirectoryMock(
|
|
$test,
|
|
null,
|
|
true
|
|
);
|
|
|
|
/** @noinspection PhpUnhandledExceptionInspection */
|
|
$this->sut->createContent($test);
|
|
}
|
|
|
|
public function testExistingContentFile(): void
|
|
{
|
|
$test = $this->createTestMock('https://example.com', 'label');
|
|
|
|
/** @noinspection PhpUnhandledExceptionInspection */
|
|
static::assertSame(
|
|
$this->createDirectoryMock(
|
|
$test,
|
|
$this->createExistingFileMock($test),
|
|
true,
|
|
false
|
|
),
|
|
$this->sut->createContent($test, false, false)
|
|
);
|
|
}
|
|
|
|
private function createTemplateDocument(): DOMDocument
|
|
{
|
|
$document = new DOMDocument('1.0', 'UTF-8');
|
|
|
|
$document->loadXML(self::TEST_TEMPLATE);
|
|
|
|
return $document;
|
|
}
|
|
|
|
private function createTestDom(KernelResource $test): DOMDocument
|
|
{
|
|
$document = $this->createTemplateDocument();
|
|
|
|
$this
|
|
->updateDocumentTitle($document, $test)
|
|
->documentElement->setAttribute(
|
|
'identifier',
|
|
str_replace('_', '-', Format::sanitizeIdentifier($test->getLabel()))
|
|
);
|
|
$document->documentElement->setAttribute('toolVersion', self::PLATFORM_VERSION);
|
|
|
|
return $document;
|
|
}
|
|
|
|
private function updateDocumentTitle(DOMDocument $document, KernelResource $test): DOMDocument
|
|
{
|
|
$document->documentElement->setAttribute('title', $test->getLabel());
|
|
|
|
return $document;
|
|
}
|
|
|
|
private function createNewFileMock(KernelResource $test): File
|
|
{
|
|
$fileMock = $this->createMock(File::class);
|
|
|
|
$fileMock
|
|
->expects(static::once())
|
|
->method('write')
|
|
->with(
|
|
$this->createTestDom($test)->saveXML()
|
|
)
|
|
->willReturn(true);
|
|
|
|
return $fileMock;
|
|
}
|
|
|
|
private function createExistingFileMock(KernelResource $test): File
|
|
{
|
|
$documentTemplate = $this->createTemplateDocument();
|
|
|
|
$fileMock = $this->createMock(File::class);
|
|
|
|
$fileMock
|
|
->expects(static::once())
|
|
->method('exists')
|
|
->willReturn(true);
|
|
|
|
$fileMock
|
|
->expects(static::once())
|
|
->method('read')
|
|
->willReturn($documentTemplate->saveXML());
|
|
|
|
$fileMock
|
|
->expects(static::once())
|
|
->method('update')
|
|
->with(
|
|
$this->updateDocumentTitle($documentTemplate, $test)->saveXML()
|
|
)
|
|
->willReturn(true);
|
|
|
|
return $fileMock;
|
|
}
|
|
|
|
private function createTestMock(string $uri, string $label): KernelResource
|
|
{
|
|
$testMock = $this->createMock(KernelResource::class);
|
|
|
|
$testMock
|
|
->method('getUri')
|
|
->willReturn($uri);
|
|
|
|
$testMock
|
|
->method('getLabel')
|
|
->willReturn($label);
|
|
|
|
return $testMock;
|
|
}
|
|
|
|
/**
|
|
* @param KernelResource|MockObject $test
|
|
* @param File|MockObject|null $file
|
|
* @param bool $exists
|
|
* @param bool $preventOverride
|
|
*
|
|
* @return Directory
|
|
*/
|
|
private function createDirectoryMock(
|
|
KernelResource $test,
|
|
File $file = null,
|
|
bool $exists = false,
|
|
$preventOverride = true
|
|
): Directory {
|
|
$mainInvocationRule = !$exists || !$preventOverride ? static::once() : static::never();
|
|
|
|
$directoryMock = $this->createMock(Directory::class);
|
|
|
|
$directoryMock
|
|
->expects(static::once())
|
|
->method('exists')
|
|
->willReturn($exists);
|
|
|
|
$directoryMock
|
|
->expects(clone $mainInvocationRule)
|
|
->method('getFile')
|
|
->with('tao-qtitest-testdefinition.xml')
|
|
->willReturn($file);
|
|
|
|
$this->defaultDirectoryMock
|
|
->expects(static::once())
|
|
->method('getDirectory')
|
|
->with(md5($test->getUri()))
|
|
->willReturn($directoryMock);
|
|
|
|
$serializedDirectoryData = 'serialized_directory_data';
|
|
|
|
$this->fileReferenceSerializerMock
|
|
->expects(clone $mainInvocationRule)
|
|
->method('serialize')
|
|
->with($directoryMock)
|
|
->willReturn($serializedDirectoryData);
|
|
|
|
$test
|
|
->expects(clone $mainInvocationRule)
|
|
->method('editPropertyValues')
|
|
->with($this->testContentPropertyMock, $serializedDirectoryData);
|
|
|
|
return $directoryMock;
|
|
}
|
|
|
|
private function creteServiceLocatorMock(): ServiceLocatorInterface
|
|
{
|
|
$serviceLocatorMock = $this->createMock(ServiceLocatorInterface::class);
|
|
|
|
$serviceLocatorMock
|
|
->method('get')
|
|
->willReturnMap(
|
|
[
|
|
[ApplicationService::SERVICE_ID, $this->createApplicationServiceMock()],
|
|
[FileReferenceSerializer::SERVICE_ID, $this->fileReferenceSerializerMock],
|
|
[AssessmentTestXmlFactory::class, $this->xmlFactory],
|
|
[DefaultConfigurationRegistry::class, $this->xmlTemplateOptionsRegistry],
|
|
]
|
|
);
|
|
|
|
return $serviceLocatorMock;
|
|
}
|
|
|
|
private function createModelMock(): Ontology
|
|
{
|
|
$modelMock = $this->createMock(Ontology::class);
|
|
|
|
$modelMock
|
|
->method('getProperty')
|
|
->willReturnMap(
|
|
[
|
|
['http://www.tao.lu/Ontologies/TAOTest.rdf#TestContent', $this->testContentPropertyMock],
|
|
]
|
|
);
|
|
|
|
return $modelMock;
|
|
}
|
|
|
|
private function createApplicationServiceMock(): ApplicationService
|
|
{
|
|
$applicationServiceMock = $this->createMock(ApplicationService::class);
|
|
|
|
$applicationServiceMock
|
|
->method('getPlatformVersion')
|
|
->willReturn(self::PLATFORM_VERSION);
|
|
|
|
return $applicationServiceMock;
|
|
}
|
|
}
|