diff --git a/actions/class.Tests.php b/actions/class.Tests.php index 7186b760..94023bc3 100755 --- a/actions/class.Tests.php +++ b/actions/class.Tests.php @@ -32,6 +32,8 @@ use oat\tao\model\controller\SignedFormInstance; use oat\tao\model\resources\Service\ClassDeleter; use oat\tao\model\routing\AnnotationReader\security; +use oat\taoTests\models\Form\Modifier\FormModifierProxy; +use oat\taoTests\models\Translation\Form\Modifier\TranslationFormModifierProxy; use tao_helpers_form_FormContainer as FormContainer; use oat\generis\model\resource\Service\ResourceDeleter; use oat\tao\model\resources\Contract\ClassDeleterInterface; @@ -114,6 +116,10 @@ public function editTest() $this->getDependsOnPropertyValidator(), ], ], + FormContainer::FORM_MODIFIERS => [ + FormModifierProxy::class, + TranslationFormModifierProxy::class, + ], ] ); $myForm = $formContainer->getForm(); @@ -235,6 +241,23 @@ public function authoring() if (!empty($authoringUrl)) { $userId = common_session_SessionManager::getSession()->getUser()->getIdentifier(); LockManager::getImplementation()->setLock($test, $userId); + + // Add support for the translation and the side-by-side authoring tool + if ($this->getRequestParameter('translation') !== null) { + $authoringUrl = sprintf( + '%s&translation=%s', + $authoringUrl, + $this->getRequestParameter('translation') + ); + } + if ($this->getRequestParameter('originResourceUri') !== null) { + $authoringUrl = sprintf( + '%s&originResourceUri=%s', + $authoringUrl, + $this->getRequestParameter('originResourceUri') + ); + } + return $this->forwardUrl($authoringUrl); } throw new common_exception_NoImplementation(); diff --git a/actions/structures.xml b/actions/structures.xml index 4e648a8c..29ac397a 100644 --- a/actions/structures.xml +++ b/actions/structures.xml @@ -69,6 +69,9 @@ + + + diff --git a/composer.json b/composer.json index 69c224c9..44590c18 100644 --- a/composer.json +++ b/composer.json @@ -62,10 +62,10 @@ }, "require": { "oat-sa/oatbox-extension-installer": "~1.1||dev-master", - "oat-sa/generis": ">=15.24", - "oat-sa/tao-core": ">=53.0.0", + "oat-sa/generis": ">=15.39.0", + "oat-sa/tao-core": ">=54.23.0", "oat-sa/extension-tao-backoffice": ">=6.0.0", - "oat-sa/extension-tao-item": ">=12.0.0" + "oat-sa/extension-tao-item": ">=12.4.0" }, "autoload": { "psr-4": { diff --git a/manifest.php b/manifest.php index 0d6fe79a..9813496e 100755 --- a/manifest.php +++ b/manifest.php @@ -32,13 +32,16 @@ use oat\tao\model\accessControl\func\AccessRule; use oat\tao\model\user\TaoRoles; use oat\taoTests\models\Copier\CopierServiceProvider; +use oat\taoTests\models\Form\ServiceProvider\FormServiceProvider; +use oat\taoTests\models\Translation\ServiceProvider\TranslationServiceProvider; use oat\taoTests\models\user\TaoTestsRoles; -use oat\taoTests\scripts\update\Updater; -use oat\taoTests\scripts\install\SetupProvider; use oat\taoTests\scripts\install\RegisterFrontendPaths; use oat\taoTests\scripts\install\RegisterTestPluginService; -use oat\taoTests\scripts\install\RegisterTestProviderService; use oat\taoTests\scripts\install\RegisterTestPreviewerRegistryService; +use oat\taoTests\scripts\install\RegisterTestProviderService; +use oat\taoTests\scripts\install\SetupEventListeners; +use oat\taoTests\scripts\install\SetupProvider; +use oat\taoTests\scripts\update\Updater; $extpath = __DIR__ . DIRECTORY_SEPARATOR; @@ -62,6 +65,7 @@ RegisterFrontendPaths::class, RegisterTestPreviewerRegistryService::class, SetupProvider::class, + SetupEventListeners::class, ], ], 'update' => Updater::class, @@ -96,6 +100,14 @@ AccessRule::GRANT, TaoTestsRoles::RESTRICTED_TEST_AUTHOR, ['ext' => 'taoTests', 'mod' => 'Tests'] + ], + [ + AccessRule::GRANT, + TaoTestsRoles::TEST_TRANSLATOR, + [ + 'ext' => 'tao', + 'mod' => 'Translation' + ] ] ], 'optimizableClasses' => [ @@ -122,5 +134,7 @@ ], 'containerServiceProviders' => [ CopierServiceProvider::class, + TranslationServiceProvider::class, + FormServiceProvider::class, ], ]; diff --git a/migrations/Version202409060743452141_taoTests.php b/migrations/Version202409060743452141_taoTests.php new file mode 100644 index 00000000..1857e1ac --- /dev/null +++ b/migrations/Version202409060743452141_taoTests.php @@ -0,0 +1,85 @@ +getRule()); + + $this->addReport(Report::createSuccess('Applied rules for role ' . TaoTestsRoles::TEST_TRANSLATOR)); + + /** @var SectionVisibilityFilter $sectionVisibilityFilter */ + $sectionVisibilityFilter = $this->getServiceManager()->get(SectionVisibilityFilter::SERVICE_ID); + + $sectionVisibilityFilter->showSectionByFeatureFlag( + $sectionVisibilityFilter->createSectionPath( + [ + 'manage_tests', + 'test-translate' + ] + ), + 'FEATURE_FLAG_TRANSLATION_ENABLED' + ); + $this->getServiceManager()->register(SectionVisibilityFilter::SERVICE_ID, $sectionVisibilityFilter); + + $this->addReport( + Report::createSuccess('Hide test section for feature flag FEATURE_FLAG_TRANSLATION_ENABLED') + ); + + /** @var EventManager $eventManager */ + $eventManager = $this->getServiceManager()->get(EventManager::SERVICE_ID); + $eventManager->attach( + TestCreatedEvent::class, + [TestCreatedEventListener::class, 'populateTranslationProperties'] + ); + $this->getServiceManager()->register(EventManager::SERVICE_ID, $eventManager); + } + + public function down(Schema $schema): void + { + AclProxy::revokeRule($this->getRule()); + + /** @var EventManager $eventManager */ + $eventManager = $this->getServiceManager()->get(EventManager::SERVICE_ID); + $eventManager->detach( + TestCreatedEvent::class, + [TestCreatedEventListener::class, 'populateTranslationProperties'] + ); + $this->getServiceManager()->register(EventManager::SERVICE_ID, $eventManager); + } + + private function getRule(): AccessRule + { + return new AccessRule( + AccessRule::GRANT, + TaoTestsRoles::TEST_TRANSLATOR, + [ + 'ext' => 'tao', + 'mod' => 'Translation' + ] + ); + } +} diff --git a/migrations/Version202411111300542363_taoTests.php b/migrations/Version202411111300542363_taoTests.php new file mode 100644 index 00000000..fd7bbae2 --- /dev/null +++ b/migrations/Version202411111300542363_taoTests.php @@ -0,0 +1,30 @@ +call( + 'withEventManager', + [ + service(EventManager::class), + ] ); $services diff --git a/models/classes/Form/Modifier/FormModifierProxy.php b/models/classes/Form/Modifier/FormModifierProxy.php new file mode 100644 index 00000000..a6ee981c --- /dev/null +++ b/models/classes/Form/Modifier/FormModifierProxy.php @@ -0,0 +1,29 @@ +services(); + + $services + ->set(FormModifierProxy::class, FormModifierProxy::class) + ->public(); + + $services + ->get(FormModifierProxy::class) + ->call( + 'addModifier', + [ + service(UniqueIdFormModifier::class), + ] + ); + } +} diff --git a/models/classes/TaoTestOntology.php b/models/classes/TaoTestOntology.php new file mode 100644 index 00000000..2a7d0155 --- /dev/null +++ b/models/classes/TaoTestOntology.php @@ -0,0 +1,32 @@ +featureFlagChecker = $featureFlagChecker; + $this->ontology = $ontology; + } + + public function modify(Form $form, array $options = []): void + { + if (!$this->featureFlagChecker->isEnabled('FEATURE_FLAG_TRANSLATION_ENABLED')) { + $form->removeElement(tao_helpers_Uri::encode(TaoTestOntology::PROPERTY_TRANSLATION_COMPLETION)); + + return; + } + + $instance = $this->ontology->getResource($form->getValue('uri')); + + $translationType = $instance->getOnePropertyValue( + $this->ontology->getProperty(TaoOntology::PROPERTY_TRANSLATION_TYPE) + ); + $translationTypeUri = $translationType instanceof core_kernel_classes_Literal + ? (string) $translationType + : ($translationType instanceof core_kernel_classes_Resource ? $translationType->getUri() : null); + + if ( + empty($translationType) + || $translationTypeUri === TaoOntology::PROPERTY_VALUE_TRANSLATION_TYPE_ORIGINAL + ) { + $form->removeElement(tao_helpers_Uri::encode(TaoTestOntology::PROPERTY_TRANSLATION_COMPLETION)); + } + } +} diff --git a/models/classes/Translation/Form/Modifier/TranslationFormModifierProxy.php b/models/classes/Translation/Form/Modifier/TranslationFormModifierProxy.php new file mode 100644 index 00000000..965b0257 --- /dev/null +++ b/models/classes/Translation/Form/Modifier/TranslationFormModifierProxy.php @@ -0,0 +1,29 @@ +featureFlagChecker = $featureFlagChecker; + $this->ontology = $ontology; + $this->resourceLanguageRetriever = $resourceLanguageRetriever; + $this->logger = $logger; + } + + public function populateTranslationProperties(TestCreatedEvent $event): void + { + if (!$this->featureFlagChecker->isEnabled('FEATURE_FLAG_TRANSLATION_ENABLED')) { + return; + } + + $test = $this->ontology->getResource($event->getTestUri()); + + $this->setLanguage($test); + $this->setTranslationType($test); + $this->setTranslationStatus($test); + } + + private function setLanguage(core_kernel_classes_Resource $test): void + { + $this->setProperty( + $test, + TaoOntology::PROPERTY_LANGUAGE, + TaoOntology::LANGUAGE_PREFIX . $this->resourceLanguageRetriever->retrieve($test) + ); + } + + private function setTranslationType(core_kernel_classes_Resource $test): void + { + $this->setProperty( + $test, + TaoOntology::PROPERTY_TRANSLATION_TYPE, + TaoOntology::PROPERTY_VALUE_TRANSLATION_TYPE_ORIGINAL + ); + } + + private function setTranslationStatus(core_kernel_classes_Resource $test): void + { + $this->setProperty( + $test, + TaoOntology::PROPERTY_TRANSLATION_STATUS, + TaoOntology::PROPERTY_VALUE_TRANSLATION_STATUS_NOT_READY + ); + } + + private function setProperty(core_kernel_classes_Resource $test, string $propertyUri, string $value): void + { + $property = $this->ontology->getProperty($propertyUri); + + if (!$this->isPropertySet($test, $property)) { + $test->editPropertyValues($property, $value); + } + } + + private function isPropertySet(core_kernel_classes_Resource $test, core_kernel_classes_Property $property): bool + { + if (empty($test->getOnePropertyValue($property))) { + return false; + } + + $this->logger->info( + sprintf( + 'The property "%s" for the test "%s" has already been set.', + $property->getUri(), + $test->getUri() + ) + ); + + return true; + } +} diff --git a/models/classes/Translation/Service/TranslationPostCreationService.php b/models/classes/Translation/Service/TranslationPostCreationService.php new file mode 100644 index 00000000..80b71ece --- /dev/null +++ b/models/classes/Translation/Service/TranslationPostCreationService.php @@ -0,0 +1,46 @@ +logger = $logger; + } + + /** + * @TODO When time comes, we need to deal set translation items to the test + */ + public function __invoke(core_kernel_classes_Resource $resource): core_kernel_classes_Resource + { + $this->logger->debug(sprintf('TODO: Deal with post test translation for %s', $resource->getUri())); + + return $resource; + } +} diff --git a/models/classes/Translation/ServiceProvider/TranslationServiceProvider.php b/models/classes/Translation/ServiceProvider/TranslationServiceProvider.php new file mode 100644 index 00000000..4474628d --- /dev/null +++ b/models/classes/Translation/ServiceProvider/TranslationServiceProvider.php @@ -0,0 +1,119 @@ +services(); + + $services->get(ResourceMetadataPopulateService::class) + ->call( + 'addMetadata', + [ + TaoOntology::CLASS_URI_TEST, + TaoTestOntology::PROPERTY_TRANSLATION_COMPLETION, + ] + ); + + $services + ->set(TranslationFormModifier::class, TranslationFormModifier::class) + ->args([ + service(FeatureFlagChecker::class), + service(Ontology::SERVICE_ID), + ]); + + $services + ->set(TranslationFormModifierProxy::class, TranslationFormModifierProxy::class) + ->call( + 'addModifier', + [ + service(TaoTranslationFormModifier::class), + ] + ) + ->call( + 'addModifier', + [ + service(TranslationFormModifier::class), + ] + )->public(); + + $services + ->set(TestCreatedEventListener::class, TestCreatedEventListener::class) + ->public() + ->args([ + service(FeatureFlagChecker::class), + service(Ontology::SERVICE_ID), + service(ResourceLanguageRetriever::class), + service(LoggerService::SERVICE_ID), + ]); + + $services + ->set(TranslationPostCreationService::class, TranslationPostCreationService::class) + ->args( + [ + service(LoggerService::SERVICE_ID), + ] + ); + + $services + ->get(TranslationCreationService::class) + ->call( + 'setResourceTransfer', + [ + TaoOntology::CLASS_URI_TEST, + service(InstanceCopier::class . '::TESTS') + ] + ) + ->call( + 'addPostCreation', + [ + TaoOntology::CLASS_URI_TEST, + service(TranslationPostCreationService::class) + ] + ); + } +} diff --git a/models/classes/event/TestCreatedEvent.php b/models/classes/event/TestCreatedEvent.php index fcc467fb..660528c9 100644 --- a/models/classes/event/TestCreatedEvent.php +++ b/models/classes/event/TestCreatedEvent.php @@ -47,6 +47,11 @@ public function getName() return get_class($this); } + public function getTestUri(): string + { + return $this->testUri; + } + /** * Specify data which should be serialized to JSON * @link http://php.net/manual/en/jsonserializable.jsonserialize.php diff --git a/models/classes/event/TestDuplicatedEvent.php b/models/classes/event/TestDuplicatedEvent.php index 147e5817..e840a422 100644 --- a/models/classes/event/TestDuplicatedEvent.php +++ b/models/classes/event/TestDuplicatedEvent.php @@ -67,4 +67,9 @@ public function jsonSerialize() 'cloneUri' => $this->cloneUri ]; } + + public function getCloneUri(): string + { + return $this->cloneUri; + } } diff --git a/models/classes/user/TaoTestsRoles.php b/models/classes/user/TaoTestsRoles.php index 2b79febd..17754943 100644 --- a/models/classes/user/TaoTestsRoles.php +++ b/models/classes/user/TaoTestsRoles.php @@ -28,4 +28,5 @@ interface TaoTestsRoles public const TEST_EXPORTER = 'http://www.tao.lu/Ontologies/TAOTest.rdf#TestExporterRole'; public const TEST_MANAGER = 'http://www.tao.lu/Ontologies/TAOTest.rdf#TestsManagerRole'; public const RESTRICTED_TEST_AUTHOR = 'http://www.tao.lu/Ontologies/TAO.rdf#RestrictedTestAuthor'; + public const TEST_TRANSLATOR = 'http://www.tao.lu/Ontologies/TAOTest.rdf#TestTranslator'; } diff --git a/models/ontology/taotest.rdf b/models/ontology/taotest.rdf index c0516306..71a1eeb4 100644 --- a/models/ontology/taotest.rdf +++ b/models/ontology/taotest.rdf @@ -22,7 +22,7 @@ - + @@ -44,7 +44,7 @@ - + @@ -85,4 +85,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/scripts/install/SetupEventListeners.php b/scripts/install/SetupEventListeners.php new file mode 100644 index 00000000..a2020772 --- /dev/null +++ b/scripts/install/SetupEventListeners.php @@ -0,0 +1,43 @@ +registerEvent( + TestCreatedEvent::class, + [TestCreatedEventListener::class, 'populateTranslationProperties'] + ); + } +} diff --git a/test/unit/models/classes/Translation/Form/Modifier/TranslationFormModifierTest.php b/test/unit/models/classes/Translation/Form/Modifier/TranslationFormModifierTest.php new file mode 100644 index 00000000..6c00af1c --- /dev/null +++ b/test/unit/models/classes/Translation/Form/Modifier/TranslationFormModifierTest.php @@ -0,0 +1,193 @@ +form = $this->createMock(tao_helpers_form_Form::class); + + $this->featureFlagChecker = $this->createMock(FeatureFlagCheckerInterface::class); + $this->ontology = $this->createMock(Ontology::class); + + $this->sut = new TranslationFormModifier($this->featureFlagChecker, $this->ontology); + } + + public function testModifyTranslationEnabledNoType(): void + { + $this->featureFlagChecker + ->expects($this->once()) + ->method('isEnabled') + ->with('FEATURE_FLAG_TRANSLATION_ENABLED') + ->willReturn(true); + + $this->form + ->expects($this->once()) + ->method('getValue') + ->with('uri') + ->willReturn('instanceUri'); + + $instance = $this->createMock(core_kernel_classes_Resource::class); + + $this->ontology + ->expects($this->once()) + ->method('getResource') + ->with('instanceUri') + ->willReturn($instance); + + $property = $this->createMock(core_kernel_classes_Property::class); + + $this->ontology + ->expects($this->once()) + ->method('getProperty') + ->with(TaoOntology::PROPERTY_TRANSLATION_TYPE) + ->willReturn($property); + + $instance + ->expects($this->once()) + ->method('getOnePropertyValue') + ->with($property) + ->willReturn(null); + + $this->form + ->expects($this->once()) + ->method('removeElement') + ->with(tao_helpers_Uri::encode(TaoTestOntology::PROPERTY_TRANSLATION_COMPLETION)); + + $this->sut->modify($this->form); + } + + /** + * @dataProvider translationTypeDataProvider + */ + public function testModifyTranslationEnabledWithType(string $type): void + { + $this->featureFlagChecker + ->expects($this->once()) + ->method('isEnabled') + ->with('FEATURE_FLAG_TRANSLATION_ENABLED') + ->willReturn(true); + + $this->form + ->expects($this->once()) + ->method('getValue') + ->with('uri') + ->willReturn('instanceUri'); + + $instance = $this->createMock(core_kernel_classes_Resource::class); + + $this->ontology + ->expects($this->once()) + ->method('getResource') + ->with('instanceUri') + ->willReturn($instance); + + $property = $this->createMock(core_kernel_classes_Property::class); + + $this->ontology + ->expects($this->once()) + ->method('getProperty') + ->with(TaoOntology::PROPERTY_TRANSLATION_TYPE) + ->willReturn($property); + + $typeValue = $this->createMock(core_kernel_classes_Resource::class); + + $instance + ->expects($this->once()) + ->method('getOnePropertyValue') + ->with($property) + ->willReturn($typeValue); + + $typeValue + ->expects($this->once()) + ->method('getUri') + ->willReturn($type); + + $this->form + ->expects( + $type === TaoOntology::PROPERTY_VALUE_TRANSLATION_TYPE_ORIGINAL + ? $this->once() + : $this->never() + ) + ->method('removeElement') + ->with(tao_helpers_Uri::encode(TaoTestOntology::PROPERTY_TRANSLATION_COMPLETION)); + + $this->sut->modify($this->form); + } + + public function testModifyTranslationDisabled(): void + { + $this->featureFlagChecker + ->expects($this->once()) + ->method('isEnabled') + ->with('FEATURE_FLAG_TRANSLATION_ENABLED') + ->willReturn(false); + + $this->form + ->expects($this->once()) + ->method('removeElement') + ->with(tao_helpers_Uri::encode(TaoTestOntology::PROPERTY_TRANSLATION_COMPLETION)); + + $this->ontology + ->expects($this->never()) + ->method($this->anything()); + + $this->sut->modify($this->form); + } + + public function translationTypeDataProvider(): array + { + return [ + 'Original' => [ + 'type' => TaoOntology::PROPERTY_VALUE_TRANSLATION_TYPE_ORIGINAL, + ], + 'Translation' => [ + 'type' => TaoOntology::PROPERTY_VALUE_TRANSLATION_TYPE_TRANSLATION, + ], + ]; + } +} diff --git a/test/unit/models/classes/Translation/Listener/TestCreatedEventListenerTest.php b/test/unit/models/classes/Translation/Listener/TestCreatedEventListenerTest.php new file mode 100644 index 00000000..8df523ce --- /dev/null +++ b/test/unit/models/classes/Translation/Listener/TestCreatedEventListenerTest.php @@ -0,0 +1,241 @@ +testCreatedEvent = $this->createMock(TestCreatedEvent::class); + $this->test = $this->createMock(core_kernel_classes_Resource::class); + $this->languageProperty = $this->createMock(core_kernel_classes_Property::class); + $this->translationTypeProperty = $this->createMock(core_kernel_classes_Property::class); + $this->translationStatusProperty = $this->createMock(core_kernel_classes_Property::class); + + $this->featureFlagChecker = $this->createMock(FeatureFlagCheckerInterface::class); + $this->ontology = $this->createMock(Ontology::class); + $this->resourceLanguageRetriever = $this->createMock(ResourceLanguageRetriever::class); + $this->logger = $this->createMock(LoggerInterface::class); + + $this->sut = new TestCreatedEventListener( + $this->featureFlagChecker, + $this->ontology, + $this->resourceLanguageRetriever, + $this->logger + ); + } + + public function testPopulateTranslationPropertiesTranslationDisabled(): void + { + $this->featureFlagChecker + ->expects($this->once()) + ->method('isEnabled') + ->with('FEATURE_FLAG_TRANSLATION_ENABLED') + ->willReturn(false); + + $this->ontology + ->expects($this->never()) + ->method($this->anything()); + $this->logger + ->expects($this->never()) + ->method($this->anything()); + $this->testCreatedEvent + ->expects($this->never()) + ->method($this->anything()); + $this->test + ->expects($this->never()) + ->method($this->anything()); + + $this->sut->populateTranslationProperties($this->testCreatedEvent); + } + + public function testPopulateTranslationProperties(): void + { + $this->featureFlagChecker + ->expects($this->once()) + ->method('isEnabled') + ->with('FEATURE_FLAG_TRANSLATION_ENABLED') + ->willReturn(true); + + $this->testCreatedEvent + ->expects($this->once()) + ->method('getTestUri') + ->willReturn('testUri'); + + $this->ontology + ->expects($this->once()) + ->method('getResource') + ->with('testUri') + ->willReturn($this->test); + + $this->ontology + ->expects($this->exactly(3)) + ->method('getProperty') + ->withConsecutive( + [TaoOntology::PROPERTY_LANGUAGE], + [TaoOntology::PROPERTY_TRANSLATION_TYPE], + [TaoOntology::PROPERTY_TRANSLATION_STATUS], + ) + ->willReturnOnConsecutiveCalls( + $this->languageProperty, + $this->translationTypeProperty, + $this->translationStatusProperty, + ); + + $this->test + ->expects($this->exactly(3)) + ->method('getOnePropertyValue') + ->withConsecutive( + [$this->languageProperty], + [$this->translationTypeProperty], + [$this->translationStatusProperty], + ) + ->willReturnOnConsecutiveCalls(null, null, null); + + $this->logger + ->expects($this->never()) + ->method('info'); + + $this->resourceLanguageRetriever + ->expects($this->once()) + ->method('retrieve') + ->with($this->test) + ->willReturn('en-US'); + + $this->test + ->expects($this->exactly(3)) + ->method('editPropertyValues') + ->withConsecutive( + [$this->languageProperty, TaoOntology::LANGUAGE_PREFIX . 'en-US'], + [$this->translationTypeProperty, TaoOntology::PROPERTY_VALUE_TRANSLATION_TYPE_ORIGINAL], + [$this->translationStatusProperty, TaoOntology::PROPERTY_VALUE_TRANSLATION_STATUS_NOT_READY], + ); + + $this->sut->populateTranslationProperties($this->testCreatedEvent); + } + + public function testPopulateTranslationPropertiesValueSet(): void + { + $this->featureFlagChecker + ->expects($this->once()) + ->method('isEnabled') + ->with('FEATURE_FLAG_TRANSLATION_ENABLED') + ->willReturn(true); + + $this->testCreatedEvent + ->expects($this->once()) + ->method('getTestUri') + ->willReturn('testUri'); + + $this->ontology + ->expects($this->once()) + ->method('getResource') + ->with('testUri') + ->willReturn($this->test); + + $this->ontology + ->expects($this->exactly(3)) + ->method('getProperty') + ->withConsecutive( + [TaoOntology::PROPERTY_LANGUAGE], + [TaoOntology::PROPERTY_TRANSLATION_TYPE], + [TaoOntology::PROPERTY_TRANSLATION_STATUS], + ) + ->willReturnOnConsecutiveCalls( + $this->languageProperty, + $this->translationTypeProperty, + $this->translationStatusProperty, + ); + + $this->test + ->expects($this->exactly(3)) + ->method('getOnePropertyValue') + ->withConsecutive( + [$this->languageProperty], + [$this->translationTypeProperty], + [$this->translationStatusProperty], + ) + ->willReturnOnConsecutiveCalls( + $this->createMock(core_kernel_classes_Resource::class), + $this->createMock(core_kernel_classes_Resource::class), + $this->createMock(core_kernel_classes_Resource::class) + ); + + $this->logger + ->expects($this->exactly(3)) + ->method('info'); + + $this->resourceLanguageRetriever + ->expects($this->once()) + ->method('retrieve') + ->with($this->test) + ->willReturn('en-US'); + + $this->test + ->expects($this->never()) + ->method('editPropertyValues'); + + $this->sut->populateTranslationProperties($this->testCreatedEvent); + } +} diff --git a/test/unit/models/classes/Translation/Service/TranslationPostCreationServiceTest.php b/test/unit/models/classes/Translation/Service/TranslationPostCreationServiceTest.php new file mode 100644 index 00000000..b9d6edca --- /dev/null +++ b/test/unit/models/classes/Translation/Service/TranslationPostCreationServiceTest.php @@ -0,0 +1,58 @@ +logger = $this->createMock(LoggerInterface::class); + $this->service = new TranslationPostCreationService($this->logger); + } + + public function testInvokeLogsMessage(): void + { + $resource = $this->createMock(core_kernel_classes_Resource::class); + $resourceUri = 'http://example.com/resource/1'; + $resource + ->method('getUri') + ->willReturn($resourceUri); + + $this->logger + ->expects($this->once()) + ->method('debug'); + + ($this->service)($resource); + } +} diff --git a/views/js/controller/tests/action.js b/views/js/controller/tests/action.js index 24a673dd..2f2469ed 100644 --- a/views/js/controller/tests/action.js +++ b/views/js/controller/tests/action.js @@ -18,17 +18,60 @@ */ define([ 'i18n', - 'layout/actions/binder', + 'module', 'uri', + 'layout/actions', + 'layout/actions/binder', + 'layout/section', + 'form/translation', + 'services/translation', 'ui/feedback', 'core/logger', - 'taoTests/previewer/factory', - 'module' -], function (__, binder, uri, feedback, loggerFactory, previewerFactory, module) { + 'taoTests/previewer/factory' +], function ( + __, + module, + uri, + actionManager, + binder, + section, + translationFormFactory, + translationService, + feedback, + loggerFactory, + previewerFactory +) { 'use strict'; const logger = loggerFactory('taoTests/controller/action'); + binder.register('translateTest', function (actionContext) { + section.current().updateContentBlock('
'); + const $container = $('.main-container', section.selected.panel); + const { rootClassUri, id: resourceUri } = actionContext; + translationFormFactory($container, { rootClassUri, resourceUri, allowDeletion: true }) + .on('edit', (id, language) => { + return actionManager.exec('test-authoring', { + id, + language, + rootClassUri, + originResourceUri: resourceUri, + translation: true, + actionParams: ['originResourceUri', 'language', 'translation'] + }); + }) + .on('delete', function onDelete(id, language) { + return translationService.deleteTranslation(resourceUri, language).then(() => { + feedback().success(__('Translation deleted')); + return this.refresh(); + }); + }) + .on('error', error => { + logger.error(error); + feedback().error(__('An error occurred while processing your request.')); + }); + }); + binder.register('testPreview', function testPreview(actionContext) { const config = module.config(); const previewerConfig = Object.fromEntries( diff --git a/views/js/loader/taoTests.min.js b/views/js/loader/taoTests.min.js index 4183c9d1..2c7c0dd2 100644 --- a/views/js/loader/taoTests.min.js +++ b/views/js/loader/taoTests.min.js @@ -1,2 +1,2 @@ -define("taoTests/controller/routes",[],function(){"use strict";return{Tests:{deps:"controller/tests/action",actions:{editTest:"controller/tests/editTest"}},TestImport:{actions:{index:"controller/testImport/index"}}}}),define("taoTests/util/provider/itemClassProvider",["jquery","i18n","util/url"],function($,__,urlUtils){"use strict";var providers={listTests(data){return new Promise(function(resolve,reject){$.ajax({url:urlUtils.route("getItemClasses","SaSItems","taoItems"),data:{q:data.q,page:data.page},type:"GET",dataType:"JSON"}).done(function(tests){tests?resolve(tests):reject(new Error(__("Unable to load tests")))}).fail(function(){reject(new Error(__("Unable to load tests")))})})}};return providers}),define("taoTests/util/form/itemClassSelectorForm",["jquery","i18n","ui/filter","ui/feedback"],function($,__,filterFactory,feedback){"use strict";return{createSelectorInput(_ref){let{$filterContainer,$inputElement,dataProvider,inputPlaceholder=__("Select the item destination class"),inputLabel=__("Select Item Destination")}=_ref;return filterFactory($filterContainer,{placeholder:inputPlaceholder,label:inputLabel,width:"64%",quietMillis:1e3}).on("change",function(selection){$inputElement.val(selection)}).on("request",function(params){dataProvider.list(params.data).then(function(data){params.success(data)}).catch(function(err){params.error(err),feedback().error(err)})}).render("<%- text %>")},setupTaoLocalForm($form,providers){const $filterContainer=$(".item-select-container",$form),$inputElement=$("#itemClassDestination",$form);this.createSelectorInput({$filterContainer,$inputElement,dataProvider:{list:providers.listTests}})}}}),define("taoTests/controller/testImport/index",["jquery","taoTests/util/provider/itemClassProvider","taoTests/util/form/itemClassSelectorForm"],function($,itemClassProvider,itemClassSelectorForm){"use strict";return{start(){const $form=$("#import");itemClassSelectorForm.setupTaoLocalForm($form,itemClassProvider)}}}),define("taoTests/previewer/factory",["lodash","context","module","core/providerLoader","core/providerRegistry","core/logger"],function(_,context,module,providerLoaderFactory,providerRegistry){"use strict";function previewerFactory(type,uri,config){return config=Object.assign({},module.config(),config),providerLoaderFactory().addList(config.previewers).load(context.bundle).then(function(providers){providers.forEach(function(provider){previewerFactory.registerProvider(provider.name,provider)})}).then(function(){return previewerFactory.getProvider(type)}).then(function(provider){return provider.init(uri,config)})}return providerRegistry(previewerFactory,function validateProvider(provider){if("function"!=typeof provider.init)throw new TypeError("The previewer provider MUST have a init() method");return!0})}),define("taoTests/controller/tests/action",["i18n","layout/actions/binder","uri","ui/feedback","core/logger","taoTests/previewer/factory","module"],function(__,binder,uri,feedback,loggerFactory,previewerFactory,module){"use strict";const logger=loggerFactory("taoTests/controller/action");binder.register("testPreview",function testPreview(actionContext){const config=module.config(),previewerConfig=Object.fromEntries(Object.entries({readOnly:!1,fullPage:!0,pluginsOptions:config.pluginsOptions}).filter(_ref2=>{let[key,value]=_ref2;return value!==void 0})),getProvider=id=>{if(!id||!config.providers)return config.provider;const previewerId=parseInt(`${id}`.split("-").pop(),10)||0;return config.providers[previewerId]?config.providers[previewerId].id:config.provider};previewerFactory(getProvider(this.id)||"qtiTest",uri.decode(actionContext.uri),previewerConfig).catch(err=>{logger.error(err),feedback().error(__("Test Preview is not installed, please contact to your administrator."))})})}),define("taoTests/controller/tests/editTest",["jquery","ui/lock","module","layout/actions"],function($,lock,module,actions){"use strict";return{start(){const config=module.config(),maxButtons=10,getPreviewId=idx=>`test-preview${idx?`-${idx}`:""}`,previewActions=[];for(let i=0;i{previewAction.state.disabled=!config.isPreviewEnabled}),actions.updateState(),$("#lock-box").each(function(){lock($(this)).register()})}}}),define("taoTests/loader/taoTests.bundle",function(){}),define("taoTests/loader/taoTests.min",["taoItems/loader/taoItems.min"],function(){}); +define("taoTests/controller/routes",[],function(){"use strict";return{Tests:{deps:"controller/tests/action",actions:{editTest:"controller/tests/editTest"}},TestImport:{actions:{index:"controller/testImport/index"}}}}),define("taoTests/util/provider/itemClassProvider",["jquery","i18n","util/url"],function($,__,urlUtils){"use strict";var providers={listTests(data){return new Promise(function(resolve,reject){$.ajax({url:urlUtils.route("getItemClasses","SaSItems","taoItems"),data:{q:data.q,page:data.page},type:"GET",dataType:"JSON"}).done(function(tests){tests?resolve(tests):reject(new Error(__("Unable to load tests")))}).fail(function(){reject(new Error(__("Unable to load tests")))})})}};return providers}),define("taoTests/util/form/itemClassSelectorForm",["jquery","i18n","ui/filter","ui/feedback"],function($,__,filterFactory,feedback){"use strict";return{createSelectorInput(_ref){let{$filterContainer,$inputElement,dataProvider,inputPlaceholder=__("Select the item destination class"),inputLabel=__("Select Item Destination")}=_ref;return filterFactory($filterContainer,{placeholder:inputPlaceholder,label:inputLabel,width:"64%",quietMillis:1e3}).on("change",function(selection){$inputElement.val(selection)}).on("request",function(params){dataProvider.list(params.data).then(function(data){params.success(data)}).catch(function(err){params.error(err),feedback().error(err)})}).render("<%- text %>")},setupTaoLocalForm($form,providers){const $filterContainer=$(".item-select-container",$form),$inputElement=$("#itemClassDestination",$form);this.createSelectorInput({$filterContainer,$inputElement,dataProvider:{list:providers.listTests}})}}}),define("taoTests/controller/testImport/index",["jquery","taoTests/util/provider/itemClassProvider","taoTests/util/form/itemClassSelectorForm"],function($,itemClassProvider,itemClassSelectorForm){"use strict";return{start(){const $form=$("#import");itemClassSelectorForm.setupTaoLocalForm($form,itemClassProvider)}}}),define("taoTests/previewer/factory",["lodash","context","module","core/providerLoader","core/providerRegistry","core/logger"],function(_,context,module,providerLoaderFactory,providerRegistry){"use strict";function previewerFactory(type,uri,config){return config=Object.assign({},module.config(),config),providerLoaderFactory().addList(config.previewers).load(context.bundle).then(function(providers){providers.forEach(function(provider){previewerFactory.registerProvider(provider.name,provider)})}).then(function(){return previewerFactory.getProvider(type)}).then(function(provider){return provider.init(uri,config)})}return providerRegistry(previewerFactory,function validateProvider(provider){if("function"!=typeof provider.init)throw new TypeError("The previewer provider MUST have a init() method");return!0})}),define("taoTests/controller/tests/action",["i18n","module","uri","layout/actions","layout/actions/binder","layout/section","form/translation","services/translation","ui/feedback","core/logger","taoTests/previewer/factory"],function(__,module,uri,actionManager,binder,section,translationFormFactory,translationService,feedback,loggerFactory,previewerFactory){"use strict";const logger=loggerFactory("taoTests/controller/action");binder.register("translateTest",function(actionContext){section.current().updateContentBlock("
");const $container=$(".main-container",section.selected.panel),{rootClassUri,id:resourceUri}=actionContext;translationFormFactory($container,{rootClassUri,resourceUri,allowDeletion:!0}).on("edit",(id,language)=>actionManager.exec("test-authoring",{id,language,rootClassUri,originResourceUri:resourceUri,translation:!0,actionParams:["originResourceUri","language","translation"]})).on("delete",function onDelete(id,language){return translationService.deleteTranslation(resourceUri,language).then(()=>(feedback().success(__("Translation deleted")),this.refresh()))}).on("error",error=>{logger.error(error),feedback().error(__("An error occurred while processing your request."))})}),binder.register("testPreview",function testPreview(actionContext){const config=module.config(),previewerConfig=Object.fromEntries(Object.entries({readOnly:!1,fullPage:!0,pluginsOptions:config.pluginsOptions}).filter(_ref2=>{let[key,value]=_ref2;return value!==void 0})),getProvider=id=>{if(!id||!config.providers)return config.provider;const previewerId=parseInt(`${id}`.split("-").pop(),10)||0;return config.providers[previewerId]?config.providers[previewerId].id:config.provider};previewerFactory(getProvider(this.id)||"qtiTest",uri.decode(actionContext.uri),previewerConfig).catch(err=>{logger.error(err),feedback().error(__("Test Preview is not installed, please contact to your administrator."))})})}),define("taoTests/controller/tests/editTest",["jquery","ui/lock","module","layout/actions"],function($,lock,module,actions){"use strict";return{start(){const config=module.config(),maxButtons=10,getPreviewId=idx=>`test-preview${idx?`-${idx}`:""}`,previewActions=[];for(let i=0;i{previewAction.state.disabled=!config.isPreviewEnabled}),actions.updateState(),$("#lock-box").each(function(){lock($(this)).register()})}}}),define("taoTests/loader/taoTests.bundle",function(){}),define("taoTests/loader/taoTests.min",["taoItems/loader/taoItems.min"],function(){}); //# sourceMappingURL=taoTests.min.js.map \ No newline at end of file diff --git a/views/js/loader/taoTests.min.js.map b/views/js/loader/taoTests.min.js.map index 88d8a924..02e392ee 100644 --- a/views/js/loader/taoTests.min.js.map +++ b/views/js/loader/taoTests.min.js.map @@ -1 +1 @@ -{"version":3,"names":["define","Tests","deps","actions","editTest","TestImport","index","$","__","urlUtils","providers","listTests","data","Promise","resolve","reject","ajax","url","route","q","page","type","dataType","done","tests","Error","fail","filterFactory","feedback","createSelectorInput","_ref","$filterContainer","$inputElement","dataProvider","inputPlaceholder","inputLabel","placeholder","label","width","quietMillis","on","selection","val","params","list","then","success","catch","err","error","render","setupTaoLocalForm","$form","itemClassProvider","itemClassSelectorForm","start","_","context","module","providerLoaderFactory","providerRegistry","previewerFactory","uri","config","Object","assign","addList","previewers","load","bundle","forEach","provider","registerProvider","name","getProvider","init","validateProvider","TypeError","binder","loggerFactory","logger","register","testPreview","actionContext","previewerConfig","fromEntries","entries","readOnly","fullPage","pluginsOptions","filter","_ref2","key","value","id","previewerId","parseInt","split","pop","decode","lock","maxButtons","getPreviewId","idx","previewActions","i","action","getBy","push","previewAction","state","disabled","isPreviewEnabled","updateState","each"],"sources":["/github/workspace/tao/views/build/config-wrap-start-default.js","../controller/routes.js","../util/provider/itemClassProvider.js","../util/form/itemClassSelectorForm.js","../controller/testImport/index.js","../previewer/factory.js","../controller/tests/action.js","../controller/tests/editTest.js","module-create.js","/github/workspace/tao/views/build/config-wrap-end-default.js"],"sourcesContent":["\n","/**\n * This program is free software; you can redistribute it and/or\n * modify it under the terms of the GNU General Public License\n * as published by the Free Software Foundation; under version 2\n * of the License (non-upgradable).\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n *\n * Copyright (c) 2014-2020 (original work) Open Assessment Technologies SA\n */\n\n//@see http://forge.taotesting.com/projects/tao/wiki/Front_js\ndefine('taoTests/controller/routes',[],function(){\n 'use strict';\n return {\n 'Tests' : {\n 'deps' : 'controller/tests/action',\n 'actions' : {\n 'editTest' : 'controller/tests/editTest'\n }\n },\n 'TestImport' : {\n 'actions' : {\n 'index' : 'controller/testImport/index'\n }\n },\n };\n});\n\n","/**\n * This program is free software; you can redistribute it and/or\n * modify it under the terms of the GNU General Public License\n * as published by the Free Software Foundation; under version 2\n * of the License (non-upgradable).\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n *\n * Copyright (c) 2024 (original work) Open Assessment Technologies SA;\n */\ndefine('taoTests/util/provider/itemClassProvider',['jquery', 'i18n', 'util/url'], function ($, __, urlUtils) {\n 'use strict';\n\n var providers = {\n /**\n * List available tests\n * @param {Object} data\n * @returns {Promise}\n */\n listTests(data) {\n return new Promise(function (resolve, reject) {\n $.ajax({\n //Find and setup class list for items\n url: urlUtils.route('getItemClasses', 'SaSItems', 'taoItems'), data: {\n q: data.q, page: data.page\n }, type: 'GET', dataType: 'JSON'\n }).done(function (tests) {\n if (tests) {\n resolve(tests);\n } else {\n reject(new Error(__('Unable to load tests')));\n }\n }).fail(function () {\n reject(new Error(__('Unable to load tests')));\n });\n });\n }\n };\n\n return providers;\n\n});\n\n","/**\n * This program is free software; you can redistribute it and/or\n * modify it under the terms of the GNU General Public License\n * as published by the Free Software Foundation; under version 2\n * of the License (non-upgradable).\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n *\n * Copyright (c) 2024 (original work) Open Assessment Technologies SA (under the project TAO-PRODUCT);\n *\n */\ndefine('taoTests/util/form/itemClassSelectorForm',[\n 'jquery',\n 'i18n',\n 'ui/filter',\n 'ui/feedback'\n], function ($, __, filterFactory, feedback) {\n 'use strict';\n\n return {\n /**\n * Enhances a hidden form field, rendering a text input with filter, autocomplete and dropdown\n * @param {Object} options\n * @param {jQuery} options.$filterContainer\n * @param {jQuery} options.$inputElement\n * @param {taskQueueButton} options.taskButton - button which submits the form\n * @param {Function} options.dataProvider - provider function which returns a Promise\n * @param {String} options.inputPlaceholder\n * @param {String} options.inputLabel\n * @returns {filter} component which manages the form input\n */\n createSelectorInput({\n $filterContainer,\n $inputElement,\n dataProvider,\n inputPlaceholder = __('Select the item destination class'),\n inputLabel = __('Select Item Destination')\n }) {\n return filterFactory($filterContainer, {\n placeholder: inputPlaceholder,\n label: inputLabel,\n width: '64%',\n quietMillis: 1000\n })\n .on('change', function(selection) {\n $inputElement.val(selection);\n })\n .on('request', function(params) {\n dataProvider\n .list(params.data)\n .then(function(data) {\n params.success(data);\n })\n .catch(function(err) {\n params.error(err);\n feedback().error(err);\n });\n })\n .render('<%- text %>');\n },\n\n /**\n * Set up the wizard form for publishing a TAO Local delivery\n * @param {jQuery} $form\n * @param {Object} providers - contains function(s) for fetching data\n */\n setupTaoLocalForm($form, providers) {\n const $filterContainer = $('.item-select-container', $form);\n const $inputElement = $('#itemClassDestination', $form);\n\n // Enhanced selector input for tests:\n this.createSelectorInput({\n $filterContainer,\n $inputElement,\n dataProvider: {\n list: providers.listTests\n }\n });\n }\n };\n});\n\n","/**\n * This program is free software; you can redistribute it and/or\n * modify it under the terms of the GNU General Public License\n * as published by the Free Software Foundation; under version 2\n * of the License (non-upgradable).\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n *\n * Copyright (c) 2024 (original work) Open Assessment Technologies SA;\n *\n */\ndefine('taoTests/controller/testImport/index',[\n 'jquery',\n 'taoTests/util/provider/itemClassProvider',\n 'taoTests/util/form/itemClassSelectorForm',\n], function ($, itemClassProvider, itemClassSelectorForm) {\n 'use strict';\n\n return {\n start() {\n const $form = $('#import');\n itemClassSelectorForm.setupTaoLocalForm($form, itemClassProvider);\n }\n };\n});\n\n","/**\n * This program is free software; you can redistribute it and/or\n * modify it under the terms of the GNU General Public License\n * as published by the Free Software Foundation; under version 2\n * of the License (non-upgradable).\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n *\n * Copyright (c) 2020 (original work) Open Assessment Technologies SA ;\n */\n/**\n * @author Hanna Dzmitryieva \n */\ndefine('taoTests/previewer/factory',[\n 'lodash',\n 'context',\n 'module',\n 'core/providerLoader',\n 'core/providerRegistry',\n 'core/logger'\n], function (\n _,\n context,\n module,\n providerLoaderFactory,\n providerRegistry\n) {\n 'use strict';\n\n /**\n * Loads and display the test previewer\n * @param {String} type - The type of previewer\n * @param {String} uri - The URI of the test to load\n * @param {Object} [config] - Some config entries\n * @param {String} [config.fullPage] - Force the previewer to occupy the full window.\n * @param {String} [config.readOnly] - Do not allow to modify the previewed test.\n * @param {Object} [config.previewers] - Optionally load static adapters. By default take them from the module's config.\n * @returns {Promise}\n */\n function previewerFactory(type, uri, config) {\n config = Object.assign({}, module.config(), config);\n return providerLoaderFactory()\n .addList(config.previewers)\n .load(context.bundle)\n .then(function (providers) {\n providers.forEach(function (provider) {\n previewerFactory.registerProvider(provider.name, provider);\n });\n })\n .then(function () {\n return previewerFactory.getProvider(type);\n })\n .then(function (provider) {\n return provider.init(uri, config);\n });\n }\n\n return providerRegistry(previewerFactory, function validateProvider(provider) {\n if (typeof provider.init !== 'function') {\n throw new TypeError('The previewer provider MUST have a init() method');\n }\n return true;\n });\n});\n\n","/*\n * This program is free software; you can redistribute it and/or\n * modify it under the terms of the GNU General Public License\n * as published by the Free Software Foundation; under version 2\n * of the License (non-upgradable).\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n *\n * Copyright (c) 2014 - 2020 (original work) Open Assessment Technologies SA\n *\n */\ndefine('taoTests/controller/tests/action',[\n 'i18n',\n 'layout/actions/binder',\n 'uri',\n 'ui/feedback',\n 'core/logger',\n 'taoTests/previewer/factory',\n 'module'\n], function (__, binder, uri, feedback, loggerFactory, previewerFactory, module) {\n 'use strict';\n\n const logger = loggerFactory('taoTests/controller/action');\n\n binder.register('testPreview', function testPreview(actionContext) {\n const config = module.config();\n const previewerConfig = Object.fromEntries(\n Object.entries({\n readOnly: false,\n fullPage: true,\n pluginsOptions: config.pluginsOptions\n }).filter(([key, value]) => value !== undefined)\n );\n\n const getProvider = id => {\n if (!id || !config.providers) {\n return config.provider;\n }\n const previewerId = parseInt(`${id}`.split('-').pop(), 10) || 0;\n if (!config.providers[previewerId]) {\n return config.provider;\n }\n return config.providers[previewerId].id;\n };\n\n previewerFactory(getProvider(this.id) || 'qtiTest', uri.decode(actionContext.uri), previewerConfig).catch(\n err => {\n logger.error(err);\n feedback().error(__('Test Preview is not installed, please contact to your administrator.'));\n }\n );\n });\n});\n\n","/**\n * This program is free software; you can redistribute it and/or\n * modify it under the terms of the GNU General Public License\n * as published by the Free Software Foundation; under version 2\n * of the License (non-upgradable).\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n *\n * Copyright (c) 2015-2024 (original work) Open Assessment Technologies SA;\n */\n\n/**\n * Test edition controller\n *\n */\ndefine('taoTests/controller/tests/editTest',['jquery', 'ui/lock', 'module', 'layout/actions'], function ($, lock, module, actions) {\n 'use strict';\n\n return {\n /**\n * Controller's entrypoint\n */\n start() {\n const config = module.config();\n const maxButtons = 10; // arbitrary value for the max number of buttons\n\n const getPreviewId = idx => `test-preview${idx ? `-${idx}` : ''}`;\n const previewActions = [];\n for (let i = 0; i < maxButtons; i++) {\n const action = actions.getBy(getPreviewId(i));\n if (!action) {\n break;\n }\n previewActions.push(action);\n }\n previewActions.forEach(previewAction => {\n previewAction.state.disabled = !config.isPreviewEnabled;\n });\n actions.updateState();\n\n $('#lock-box').each(function () {\n lock($(this)).register();\n });\n }\n };\n});\n\n","\ndefine(\"taoTests/loader/taoTests.bundle\", function(){});\n","define(\"taoTests/loader/taoTests.min\", [\"taoItems/loader/taoItems.min\"], function(){});\n"],"mappings":"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"} \ No newline at end of file +{"version":3,"names":["define","Tests","deps","actions","editTest","TestImport","index","$","__","urlUtils","providers","listTests","data","Promise","resolve","reject","ajax","url","route","q","page","type","dataType","done","tests","Error","fail","filterFactory","feedback","createSelectorInput","_ref","$filterContainer","$inputElement","dataProvider","inputPlaceholder","inputLabel","placeholder","label","width","quietMillis","on","selection","val","params","list","then","success","catch","err","error","render","setupTaoLocalForm","$form","itemClassProvider","itemClassSelectorForm","start","_","context","module","providerLoaderFactory","providerRegistry","previewerFactory","uri","config","Object","assign","addList","previewers","load","bundle","forEach","provider","registerProvider","name","getProvider","init","validateProvider","TypeError","actionManager","binder","section","translationFormFactory","translationService","loggerFactory","logger","register","actionContext","current","updateContentBlock","$container","selected","panel","rootClassUri","id","resourceUri","allowDeletion","language","exec","originResourceUri","translation","actionParams","onDelete","deleteTranslation","refresh","testPreview","previewerConfig","fromEntries","entries","readOnly","fullPage","pluginsOptions","filter","_ref2","key","value","previewerId","parseInt","split","pop","decode","lock","maxButtons","getPreviewId","idx","previewActions","i","action","getBy","push","previewAction","state","disabled","isPreviewEnabled","updateState","each"],"sources":["/Users/oat/Projects/terre/tr-enterprise/files/delivery/tao/views/build/config-wrap-start-default.js","../controller/routes.js","../util/provider/itemClassProvider.js","../util/form/itemClassSelectorForm.js","../controller/testImport/index.js","../previewer/factory.js","../controller/tests/action.js","../controller/tests/editTest.js","module-create.js","/Users/oat/Projects/terre/tr-enterprise/files/delivery/tao/views/build/config-wrap-end-default.js"],"sourcesContent":["\n","/**\n * This program is free software; you can redistribute it and/or\n * modify it under the terms of the GNU General Public License\n * as published by the Free Software Foundation; under version 2\n * of the License (non-upgradable).\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n *\n * Copyright (c) 2014-2020 (original work) Open Assessment Technologies SA\n */\n\n//@see http://forge.taotesting.com/projects/tao/wiki/Front_js\ndefine('taoTests/controller/routes',[],function(){\n 'use strict';\n return {\n 'Tests' : {\n 'deps' : 'controller/tests/action',\n 'actions' : {\n 'editTest' : 'controller/tests/editTest'\n }\n },\n 'TestImport' : {\n 'actions' : {\n 'index' : 'controller/testImport/index'\n }\n },\n };\n});\n\n","/**\n * This program is free software; you can redistribute it and/or\n * modify it under the terms of the GNU General Public License\n * as published by the Free Software Foundation; under version 2\n * of the License (non-upgradable).\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n *\n * Copyright (c) 2024 (original work) Open Assessment Technologies SA;\n */\ndefine('taoTests/util/provider/itemClassProvider',['jquery', 'i18n', 'util/url'], function ($, __, urlUtils) {\n 'use strict';\n\n var providers = {\n /**\n * List available tests\n * @param {Object} data\n * @returns {Promise}\n */\n listTests(data) {\n return new Promise(function (resolve, reject) {\n $.ajax({\n //Find and setup class list for items\n url: urlUtils.route('getItemClasses', 'SaSItems', 'taoItems'), data: {\n q: data.q, page: data.page\n }, type: 'GET', dataType: 'JSON'\n }).done(function (tests) {\n if (tests) {\n resolve(tests);\n } else {\n reject(new Error(__('Unable to load tests')));\n }\n }).fail(function () {\n reject(new Error(__('Unable to load tests')));\n });\n });\n }\n };\n\n return providers;\n\n});\n\n","/**\n * This program is free software; you can redistribute it and/or\n * modify it under the terms of the GNU General Public License\n * as published by the Free Software Foundation; under version 2\n * of the License (non-upgradable).\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n *\n * Copyright (c) 2024 (original work) Open Assessment Technologies SA (under the project TAO-PRODUCT);\n *\n */\ndefine('taoTests/util/form/itemClassSelectorForm',[\n 'jquery',\n 'i18n',\n 'ui/filter',\n 'ui/feedback'\n], function ($, __, filterFactory, feedback) {\n 'use strict';\n\n return {\n /**\n * Enhances a hidden form field, rendering a text input with filter, autocomplete and dropdown\n * @param {Object} options\n * @param {jQuery} options.$filterContainer\n * @param {jQuery} options.$inputElement\n * @param {taskQueueButton} options.taskButton - button which submits the form\n * @param {Function} options.dataProvider - provider function which returns a Promise\n * @param {String} options.inputPlaceholder\n * @param {String} options.inputLabel\n * @returns {filter} component which manages the form input\n */\n createSelectorInput({\n $filterContainer,\n $inputElement,\n dataProvider,\n inputPlaceholder = __('Select the item destination class'),\n inputLabel = __('Select Item Destination')\n }) {\n return filterFactory($filterContainer, {\n placeholder: inputPlaceholder,\n label: inputLabel,\n width: '64%',\n quietMillis: 1000\n })\n .on('change', function(selection) {\n $inputElement.val(selection);\n })\n .on('request', function(params) {\n dataProvider\n .list(params.data)\n .then(function(data) {\n params.success(data);\n })\n .catch(function(err) {\n params.error(err);\n feedback().error(err);\n });\n })\n .render('<%- text %>');\n },\n\n /**\n * Set up the wizard form for publishing a TAO Local delivery\n * @param {jQuery} $form\n * @param {Object} providers - contains function(s) for fetching data\n */\n setupTaoLocalForm($form, providers) {\n const $filterContainer = $('.item-select-container', $form);\n const $inputElement = $('#itemClassDestination', $form);\n\n // Enhanced selector input for tests:\n this.createSelectorInput({\n $filterContainer,\n $inputElement,\n dataProvider: {\n list: providers.listTests\n }\n });\n }\n };\n});\n\n","/**\n * This program is free software; you can redistribute it and/or\n * modify it under the terms of the GNU General Public License\n * as published by the Free Software Foundation; under version 2\n * of the License (non-upgradable).\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n *\n * Copyright (c) 2024 (original work) Open Assessment Technologies SA;\n *\n */\ndefine('taoTests/controller/testImport/index',[\n 'jquery',\n 'taoTests/util/provider/itemClassProvider',\n 'taoTests/util/form/itemClassSelectorForm',\n], function ($, itemClassProvider, itemClassSelectorForm) {\n 'use strict';\n\n return {\n start() {\n const $form = $('#import');\n itemClassSelectorForm.setupTaoLocalForm($form, itemClassProvider);\n }\n };\n});\n\n","/**\n * This program is free software; you can redistribute it and/or\n * modify it under the terms of the GNU General Public License\n * as published by the Free Software Foundation; under version 2\n * of the License (non-upgradable).\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n *\n * Copyright (c) 2020 (original work) Open Assessment Technologies SA ;\n */\n/**\n * @author Hanna Dzmitryieva \n */\ndefine('taoTests/previewer/factory',[\n 'lodash',\n 'context',\n 'module',\n 'core/providerLoader',\n 'core/providerRegistry',\n 'core/logger'\n], function (\n _,\n context,\n module,\n providerLoaderFactory,\n providerRegistry\n) {\n 'use strict';\n\n /**\n * Loads and display the test previewer\n * @param {String} type - The type of previewer\n * @param {String} uri - The URI of the test to load\n * @param {Object} [config] - Some config entries\n * @param {String} [config.fullPage] - Force the previewer to occupy the full window.\n * @param {String} [config.readOnly] - Do not allow to modify the previewed test.\n * @param {Object} [config.previewers] - Optionally load static adapters. By default take them from the module's config.\n * @returns {Promise}\n */\n function previewerFactory(type, uri, config) {\n config = Object.assign({}, module.config(), config);\n return providerLoaderFactory()\n .addList(config.previewers)\n .load(context.bundle)\n .then(function (providers) {\n providers.forEach(function (provider) {\n previewerFactory.registerProvider(provider.name, provider);\n });\n })\n .then(function () {\n return previewerFactory.getProvider(type);\n })\n .then(function (provider) {\n return provider.init(uri, config);\n });\n }\n\n return providerRegistry(previewerFactory, function validateProvider(provider) {\n if (typeof provider.init !== 'function') {\n throw new TypeError('The previewer provider MUST have a init() method');\n }\n return true;\n });\n});\n\n","/*\n * This program is free software; you can redistribute it and/or\n * modify it under the terms of the GNU General Public License\n * as published by the Free Software Foundation; under version 2\n * of the License (non-upgradable).\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n *\n * Copyright (c) 2014 - 2020 (original work) Open Assessment Technologies SA\n *\n */\ndefine('taoTests/controller/tests/action',[\n 'i18n',\n 'module',\n 'uri',\n 'layout/actions',\n 'layout/actions/binder',\n 'layout/section',\n 'form/translation',\n 'services/translation',\n 'ui/feedback',\n 'core/logger',\n 'taoTests/previewer/factory'\n], function (\n __,\n module,\n uri,\n actionManager,\n binder,\n section,\n translationFormFactory,\n translationService,\n feedback,\n loggerFactory,\n previewerFactory\n) {\n 'use strict';\n\n const logger = loggerFactory('taoTests/controller/action');\n\n binder.register('translateTest', function (actionContext) {\n section.current().updateContentBlock('
');\n const $container = $('.main-container', section.selected.panel);\n const { rootClassUri, id: resourceUri } = actionContext;\n translationFormFactory($container, { rootClassUri, resourceUri, allowDeletion: true })\n .on('edit', (id, language) => {\n return actionManager.exec('test-authoring', {\n id,\n language,\n rootClassUri,\n originResourceUri: resourceUri,\n translation: true,\n actionParams: ['originResourceUri', 'language', 'translation']\n });\n })\n .on('delete', function onDelete(id, language) {\n return translationService.deleteTranslation(resourceUri, language).then(() => {\n feedback().success(__('Translation deleted'));\n return this.refresh();\n });\n })\n .on('error', error => {\n logger.error(error);\n feedback().error(__('An error occurred while processing your request.'));\n });\n });\n\n binder.register('testPreview', function testPreview(actionContext) {\n const config = module.config();\n const previewerConfig = Object.fromEntries(\n Object.entries({\n readOnly: false,\n fullPage: true,\n pluginsOptions: config.pluginsOptions\n }).filter(([key, value]) => value !== undefined)\n );\n\n const getProvider = id => {\n if (!id || !config.providers) {\n return config.provider;\n }\n const previewerId = parseInt(`${id}`.split('-').pop(), 10) || 0;\n if (!config.providers[previewerId]) {\n return config.provider;\n }\n return config.providers[previewerId].id;\n };\n\n previewerFactory(getProvider(this.id) || 'qtiTest', uri.decode(actionContext.uri), previewerConfig).catch(\n err => {\n logger.error(err);\n feedback().error(__('Test Preview is not installed, please contact to your administrator.'));\n }\n );\n });\n});\n\n","/**\n * This program is free software; you can redistribute it and/or\n * modify it under the terms of the GNU General Public License\n * as published by the Free Software Foundation; under version 2\n * of the License (non-upgradable).\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n *\n * Copyright (c) 2015-2024 (original work) Open Assessment Technologies SA;\n */\n\n/**\n * Test edition controller\n *\n */\ndefine('taoTests/controller/tests/editTest',['jquery', 'ui/lock', 'module', 'layout/actions'], function ($, lock, module, actions) {\n 'use strict';\n\n return {\n /**\n * Controller's entrypoint\n */\n start() {\n const config = module.config();\n const maxButtons = 10; // arbitrary value for the max number of buttons\n\n const getPreviewId = idx => `test-preview${idx ? `-${idx}` : ''}`;\n const previewActions = [];\n for (let i = 0; i < maxButtons; i++) {\n const action = actions.getBy(getPreviewId(i));\n if (!action) {\n break;\n }\n previewActions.push(action);\n }\n previewActions.forEach(previewAction => {\n previewAction.state.disabled = !config.isPreviewEnabled;\n });\n actions.updateState();\n\n $('#lock-box').each(function () {\n lock($(this)).register();\n });\n }\n };\n});\n\n","\ndefine(\"taoTests/loader/taoTests.bundle\", function(){});\n","define(\"taoTests/loader/taoTests.min\", [\"taoItems/loader/taoItems.min\"], function(){});\n"],"mappings":"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"} \ No newline at end of file diff --git a/views/js/loader/taoTestsRunner.min.js.map b/views/js/loader/taoTestsRunner.min.js.map index 1c3ba3a1..c30aee2d 100644 --- a/views/js/loader/taoTestsRunner.min.js.map +++ b/views/js/loader/taoTestsRunner.min.js.map @@ -1 +1 @@ -{"version":3,"names":["define","_","areaBroker$1","Object","prototype","hasOwnProperty","call","requireAreas","areaBroker","partial","dataHolderFactory","map","Map","defaultObjects","forEach","entry","set","pluginFactory","plugin","partialRight","hostName","moment","uuid","momentTimezone_min","probeOverseerFactory","runner","collectEvent","probe","eventNs","name","probeHandler","now","data","id","type","timestamp","format","timezone","tz","timeZone","capture","context","apply","concat","slice","arguments","overseer","push","latency","collectLatencyEvent","events","eventName","listen","indexOf","on","startHandler","marker","stopHandler","last","args","findLast","immutableQueue","startEvents","stopEvents","queueStorage","probes","queue","writing","Promise","resolve","started","getStorage","getTestStore","getStore","then","newStorage","resetStorage","isPlainObject","isFunction","init","TypeError","add","isString","isEmpty","some","val","length","isArray","getQueue","storage","getItem","getProbes","setItem","flush","flushed","start","savedQueue","stop","removeHandler","off","removeItem","guess","Array","eventifier","providerRegistry","testRunnerFactory","providerName","providerRun","method","_len","_key","provider","pluginRun","execStack","getPlugins","all","reportError","err","trigger","dataHolder","pluginFactories","config","plugins","states","ready","render","finish","destroy","itemStates","getProvider","proxy","probeOverseer","testStore","getDataHolder","getAreaBroker","getName","setState","after","catch","loadItem","itemRef","itemData","setItemState","renderItem","unloadItem","omit","disableItem","getItemState","enableItem","setTestContext","setTestMap","getConfig","getOptions","options","getPlugin","getPluginsConfig","getPluginConfig","pluginName","pluginsConfig","loadAreaBroker","getProxy","loadProxy","Error","error","install","getProbeOverseer","loadProbeOverseer","loadTestStore","getPluginStore","loadedStore","reject","getState","active","getPersistentState","state","setPersistentState","stored","loaded","disabled","getTestData","get","setTestData","testData","getTestContext","testContext","getTestMap","testMap","loadDataHolder","next","scope","previous","jump","position","skip","direction","ref","exit","why","pause","resume","timeout","timer","destroyCleanUp","clear","validateProvider","async","delegator","tokenHandlerFactory","connectivity","proxyFactory","proxyName","getParams","params","mergedParams","merge","extraCallParams","getMiddlewares","list","middlewares","applyMiddlewares","request","response","command","middleware","series","status","delegate","fnName","_slice","initialized","includes","delegateProxy","communicator","communicatorPromise","testDataHolder","proxyAdapter","initConfig","defaults","_defaults","tokenHandler","onlineStatus","isOnline","use","each","cb","destroyCommunicator","setOnline","isOffline","setOffline","source","isConnectivityError","isObject","code","sent","getTokenHandler","hasCommunicator","getCommunicator","self","loadCommunicator","before","e","open","channel","handler","communicatorInstance","noop","send","message","addCallActionParams","sendVariables","variables","deferred","callTestAction","action","uri","submitItem","callItemAction","telemetry","signal","messages","msg","wrapper","pluginWrapper","loggerFactory","providerLoader","pluginLoader","itemRunner","loadTestRunnerProviders","providers","loadFromBundle","loadAndRegisterProvider","providersToLoad","target","registerProvider","addList","load","loadedProviders","registration","runnerProviders","itemRunnerProviders","register","communicatorProviders","proxyProviders","logger","warn","keys","providerType","debug","results","reduce","acc","value","assign","sampleProxy","component","runnerFactory","Handlebars","runnerComponentTpl","asString","html","Template","$","validateTestRunnerConfiguration","requiredProperties","property","join","getSelectedProvider","typeProviders","runnerComponentFactory","container","template","runnerComponent","getOption","getRunner","setTemplate","hide","runnerConfig","renderTo","getElement","defer","show","spread","destroying","removeAllListeners","depth0","helpers","partials","compilerInfo","runnerComponentApi","configuration","document","createElement","classList","append","remove","store","testStoreLoader","testId","preselectedBackend","testMode","volatiles","changeTracking","isStoreModeUnified","isUndefined","selectStoreMode","result","modes","unified","storeName","trackChange","isBoolean","isUnified","loadStore","keyPattern","RegExp","storeKey","key","getItems","entries","transform","test","replace","setVolatile","clearVolatileIfStoreChange","storeId","shouldClear","getIdentifier","savedStoreId","info","clearVolatileStores","clearing","storeInstance","startChangeTracking","hasChanges","resetChanges","legacyStoreExp","removeStore","removeAll","getStorageIdentifier","legacyPrefixes","fragmented","getAll","validate","prefix","foundStores"],"sources":["/github/workspace/tao/views/build/config-wrap-start-default.js","../runner/areaBroker.js","../runner/dataHolder.js","../runner/plugin.js","../runner/probeOverseer.js","../runner/runner.js","../runner/proxy.js","../runner/providerLoader.js","../runner/proxy/sample.js","../runner/runnerComponent.js","../runner/runnerComponentSimple.js","../runner/testStore.js","module-create.js","/github/workspace/tao/views/build/config-wrap-end-default.js"],"sourcesContent":["\n","define('taoTests/runner/areaBroker',['lodash', 'ui/areaBroker'], function (_, areaBroker$1) { 'use strict';\n\n _ = _ && Object.prototype.hasOwnProperty.call(_, 'default') ? _['default'] : _;\n areaBroker$1 = areaBroker$1 && Object.prototype.hasOwnProperty.call(areaBroker$1, 'default') ? areaBroker$1['default'] : areaBroker$1;\n\n /*\n * This program is free software; you can redistribute it and/or\n * modify it under the terms of the GNU General Public License\n * as published by the Free Software Foundation; under version 2\n * of the License (non-upgradable).\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n *\n * Copyright (c) 2016-2019 (original work) Open Assessment Technlogies SA\n *\n */\n var requireAreas = ['content',\n //where the content is renderer, for example an item\n 'toolbox',\n //the place to add arbitrary tools, like a zoom, a comment box, etc.\n 'navigation',\n //the navigation controls like next, previous, skip\n 'control',\n //the control center of the test, progress, timers, etc.\n 'header',\n //the area that could contains the test titles\n 'panel' //a panel to add more advanced GUI (item review, navigation pane, etc.)\n ];\n\n /**\n * Creates an area broker with the required areas for the test runner.\n *\n * @see ui/areaBroker\n *\n * @param {jQueryElement|HTMLElement|String} $container - the main container\n * @param {Object} mapping - keys are the area names, values are jQueryElement\n * @returns {broker} the broker\n * @throws {TypeError} without a valid container\n */\n var areaBroker = _.partial(areaBroker$1, requireAreas);\n\n return areaBroker;\n\n});\n\n","define('taoTests/runner/dataHolder',[],function () { 'use strict';\n\n /*\n * This program is free software; you can redistribute it and/or\n * modify it under the terms of the GNU General Public License\n * as published by the Free Software Foundation; under version 2\n * of the License (non-upgradable).\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n *\n * Copyright (c) 2017-2019 (original work) Open Assessment Technlogies SA\n *\n */\n\n /**\n * Holds the test runner data.\n *\n * @example\n * var holder = holder();\n * holder.get('testMap');\n *\n * @author Bertrand Chevrier \n */\n\n /**\n * @type {String[]} the list of default objects to create\n */\n const defaultObjects = ['testContext', 'testMap'];\n\n /**\n * Creates a new data holder,\n * with default entries.\n *\n * @returns {Map} the holder\n */\n function dataHolderFactory() {\n var map = new Map();\n defaultObjects.forEach(function (entry) {\n map.set(entry, {});\n });\n return map;\n }\n\n return dataHolderFactory;\n\n});\n\n","define('taoTests/runner/plugin',['lodash', 'core/plugin'], function (_, pluginFactory) { 'use strict';\n\n _ = _ && Object.prototype.hasOwnProperty.call(_, 'default') ? _['default'] : _;\n pluginFactory = pluginFactory && Object.prototype.hasOwnProperty.call(pluginFactory, 'default') ? pluginFactory['default'] : pluginFactory;\n\n /**\n * This program is free software; you can redistribute it and/or\n * modify it under the terms of the GNU General Public License\n * as published by the Free Software Foundation; under version 2\n * of the License (non-upgradable).\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n *\n * Copyright (c) 2016-2019 (original work) Open Assessment Technologies SA ;\n */\n\n /**\n * A pluginFactory configured for the test runner\n * @returns {Function} the preconfigured plugin factory\n */\n var plugin = _.partialRight(pluginFactory, {\n //alias getHost to getTestRunner\n hostName: 'testRunner'\n });\n\n return plugin;\n\n});\n\n","define('taoTests/runner/probeOverseer',['lodash', 'moment', 'lib/uuid', 'lib/moment-timezone.min'], function (_, moment, uuid, momentTimezone_min) { 'use strict';\n\n _ = _ && Object.prototype.hasOwnProperty.call(_, 'default') ? _['default'] : _;\n moment = moment && Object.prototype.hasOwnProperty.call(moment, 'default') ? moment['default'] : moment;\n uuid = uuid && Object.prototype.hasOwnProperty.call(uuid, 'default') ? uuid['default'] : uuid;\n\n /*\n * This program is free software; you can redistribute it and/or\n * modify it under the terms of the GNU General Public License\n * as published by the Free Software Foundation; under version 2\n * of the License (non-upgradable).\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n *\n * Copyright (c) 2016-2019 (original work) Open Assessment Technlogies SA\n *\n */\n var timeZone = moment.tz.guess();\n var slice = Array.prototype.slice;\n\n /**\n * Create the overseer intance\n * @param {runner} runner - a instance of a test runner\n * @returns {probeOverseer} the new probe overseer\n * @throws TypeError if something goes wrong\n */\n function probeOverseerFactory(runner) {\n // the created instance\n var overseer;\n\n // the list of registered probes\n var probes = [];\n\n //temp queue\n var queue = [];\n\n //immutable queue which will not be flushed\n var immutableQueue = [];\n\n /**\n * @type {Storage} to store the collected events\n */\n var queueStorage;\n\n /**\n * @type {Promise} Promises chain to avoid write collisions\n */\n var writing = Promise.resolve();\n\n //is the overseer started\n var started = false;\n\n /**\n * Get the storage instance\n * @returns {Promise} that resolves with the storage\n */\n var getStorage = function getStorage() {\n if (queueStorage) {\n return Promise.resolve(queueStorage);\n }\n return runner.getTestStore().getStore('test-probe').then(function (newStorage) {\n queueStorage = newStorage;\n return Promise.resolve(queueStorage);\n });\n };\n\n /**\n * Unset the storage instance\n */\n var resetStorage = function resetStorage() {\n queueStorage = null;\n };\n\n /**\n * Register the collection event of a probe against a runner\n * @param {Object} probe - a valid probe\n */\n function collectEvent(probe) {\n var eventNs = `.probe-${probe.name}`;\n\n //event handler registered to collect data\n var probeHandler = function probeHandler() {\n var now = moment();\n var data = {\n id: uuid(12, 16),\n type: probe.name,\n timestamp: now.format('x') / 1000,\n timezone: now.tz(timeZone).format('Z')\n };\n if (typeof probe.capture === 'function') {\n data.context = probe.capture.apply(probe, [runner].concat(slice.call(arguments)));\n }\n overseer.push(data);\n };\n\n //fallback\n if (probe.latency) {\n return collectLatencyEvent(probe);\n }\n _.forEach(probe.events, function (eventName) {\n var listen = eventName.indexOf('.') > 0 ? eventName : eventName + eventNs;\n runner.on(listen, _.partial(probeHandler, eventName));\n });\n }\n function collectLatencyEvent(probe) {\n var eventNs = `.probe-${probe.name}`;\n\n //start event handler registered to collect data\n var startHandler = function startHandler() {\n var now = moment();\n var data = {\n id: uuid(12, 16),\n marker: 'start',\n type: probe.name,\n timestamp: now.format('x') / 1000,\n timezone: now.tz(timeZone).format('Z')\n };\n if (typeof probe.capture === 'function') {\n data.context = probe.capture.apply(probe, [runner].concat(slice.call(arguments)));\n }\n overseer.push(data);\n };\n\n //stop event handler registered to collect data\n var stopHandler = function stopHandler() {\n var now = moment();\n var last;\n var data = {\n type: probe.name,\n timestamp: now.format('x') / 1000,\n timezone: now.tz(timeZone).format('Z')\n };\n var args = slice.call(arguments);\n last = _.findLast(immutableQueue, {\n type: probe.name,\n marker: 'start'\n });\n if (last && !_.findLast(immutableQueue, {\n type: probe.name,\n marker: 'end',\n id: last.id\n })) {\n data.id = last.id;\n data.marker = 'end';\n if (typeof probe.capture === 'function') {\n data.context = probe.capture.apply(probe, [runner].concat(args));\n }\n overseer.push(data);\n }\n };\n\n //fallback\n if (!probe.latency) {\n return collectEvent(probe);\n }\n _.forEach(probe.startEvents, function (eventName) {\n var listen = eventName.indexOf('.') > 0 ? eventName : eventName + eventNs;\n runner.on(listen, _.partial(startHandler, eventName));\n });\n _.forEach(probe.stopEvents, function (eventName) {\n var listen = eventName.indexOf('.') > 0 ? eventName : eventName + eventNs;\n runner.on(listen, _.partial(stopHandler, eventName));\n });\n }\n\n //argument validation\n if (!_.isPlainObject(runner) || !_.isFunction(runner.init) || !_.isFunction(runner.on)) {\n throw new TypeError('Please set a test runner');\n }\n\n /**\n * @typedef {probeOverseer}\n */\n overseer = {\n /**\n * Add a new probe\n * @param {Object} probe\n * @param {String} probe.name - the probe name\n * @param {Boolean} [probe.latency = false] - simple or latency mode\n * @param {String[]} [probe.events] - the list of events to listen (simple mode)\n * @param {String[]} [probe.startEvents] - the list of events to mark the start (lantency mode)\n * @param {String[]} [probe.stopEvents] - the list of events to mark the end (latency mode)\n * @param {Function} [probe.capture] - lambda fn to define the data context, it receive the test runner and the event parameters\n * @returns {probeOverseer} chains\n * @throws TypeError if the probe is not well formatted\n */\n add: function add(probe) {\n // probe structure strict validation\n\n if (!_.isPlainObject(probe)) {\n throw new TypeError('A probe is a plain object');\n }\n if (!_.isString(probe.name) || _.isEmpty(probe.name)) {\n throw new TypeError('A probe must have a name');\n }\n if (probes.some(val => val.name === probe.name)) {\n throw new TypeError('A probe with this name is already regsitered');\n }\n if (probe.latency) {\n if (_.isString(probe.startEvents) && !_.isEmpty(probe.startEvents)) {\n probe.startEvents = [probe.startEvents];\n }\n if (_.isString(probe.stopEvents) && !_.isEmpty(probe.stopEvents)) {\n probe.stopEvents = [probe.stopEvents];\n }\n if (!probe.startEvents.length || !probe.stopEvents.length) {\n throw new TypeError('Latency based probes must have startEvents and stopEvents defined');\n }\n\n //if already started we register the events on addition\n if (started) {\n collectLatencyEvent(probe);\n }\n } else {\n if (_.isString(probe.events) && !_.isEmpty(probe.events)) {\n probe.events = [probe.events];\n }\n if (!_.isArray(probe.events) || probe.events.length === 0) {\n throw new TypeError('A probe must define events');\n }\n\n //if already started we register the events on addition\n if (started) {\n collectEvent(probe);\n }\n }\n probes.push(probe);\n return this;\n },\n /**\n * Get the time entries queue\n * @returns {Promise} with the data in parameterj\n */\n getQueue: function getQueue() {\n return getStorage().then(function (storage) {\n return storage.getItem('queue');\n });\n },\n /**\n * Get the list of defined probes\n * @returns {Object[]} the probes collection\n */\n getProbes: function getProbes() {\n return probes;\n },\n /**\n * Push a time entry to the queue\n * @param {Object} entry - the time entry\n */\n push: function push(entry) {\n getStorage().then(function (storage) {\n //ensure the queue is pushed to the store consistently and atomically\n writing = writing.then(function () {\n queue.push(entry);\n immutableQueue.push(entry);\n return storage.setItem('queue', queue);\n });\n });\n },\n /**\n * Flush the queue and get the entries\n * @returns {Promise} with the data in parameter\n */\n flush: function flush() {\n return new Promise(function (resolve) {\n getStorage().then(function (storage) {\n writing = writing.then(function () {\n return storage.getItem('queue').then(function (flushed) {\n queue = [];\n return storage.setItem('queue', queue).then(function () {\n resolve(flushed);\n });\n });\n });\n });\n });\n },\n /**\n * Start the probes\n * @returns {Promise} once started\n */\n start: function start() {\n return getStorage().then(function (storage) {\n return storage.getItem('queue').then(function (savedQueue) {\n if (_.isArray(savedQueue)) {\n queue = savedQueue;\n immutableQueue = savedQueue;\n }\n _.forEach(probes, collectEvent);\n started = true;\n });\n });\n },\n /**\n * Stop the probes\n * Be carefull, stop will also clear the store and the queue\n * @returns {Promise} once stopped\n */\n stop: function stop() {\n started = false;\n _.forEach(probes, function (probe) {\n var eventNs = `.probe-${probe.name}`;\n var removeHandler = function removeHandler(eventName) {\n runner.off(eventName + eventNs);\n };\n _.forEach(probe.startEvents, removeHandler);\n _.forEach(probe.stopEvents, removeHandler);\n _.forEach(probe.events, removeHandler);\n });\n queue = [];\n immutableQueue = [];\n return getStorage().then(function (storage) {\n return storage.removeItem('queue').then(resetStorage);\n });\n }\n };\n return overseer;\n }\n\n return probeOverseerFactory;\n\n});\n\n","define('taoTests/runner/runner',['lodash', 'core/eventifier', 'core/providerRegistry', 'taoTests/runner/dataHolder'], function (_, eventifier, providerRegistry, dataHolderFactory) { 'use strict';\n\n _ = _ && Object.prototype.hasOwnProperty.call(_, 'default') ? _['default'] : _;\n eventifier = eventifier && Object.prototype.hasOwnProperty.call(eventifier, 'default') ? eventifier['default'] : eventifier;\n providerRegistry = providerRegistry && Object.prototype.hasOwnProperty.call(providerRegistry, 'default') ? providerRegistry['default'] : providerRegistry;\n dataHolderFactory = dataHolderFactory && Object.prototype.hasOwnProperty.call(dataHolderFactory, 'default') ? dataHolderFactory['default'] : dataHolderFactory;\n\n /**\n * This program is free software; you can redistribute it and/or\n * modify it under the terms of the GNU General Public License\n * as published by the Free Software Foundation; under version 2\n * of the License (non-upgradable).\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n *\n * Copyright (c) 2015-2020 (original work) Open Assessment Technologies SA ;\n */\n\n /**\n * Builds an instance of the QTI test runner\n *\n * @param {String} providerName\n * @param {Function[]} pluginFactories\n * @param {Object} config\n * @param {String} config.serviceCallId - the identifier of the test session\n * @param {String} [config.testDefinition] - the identifier of the test definition\n * @param {String} [config.testCompilation] - the identifier of the compiled test\n * @param {Object} config.options - the test runner configuration options\n * @param {Object} config.options.plugins - the plugins configuration\n * @param {jQueryElement} [config.renderTo] - the dom element that is going to holds the test content (item, rubick, etc)\n * @returns {runner}\n */\n function testRunnerFactory(providerName) {\n let pluginFactories = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];\n let config = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n /**\n * @type {Object} The test runner instance\n */\n let runner;\n\n /**\n * @type {Map} Contains the test runner data\n */\n let dataHolder;\n\n /**\n * @type {Object} the registered plugins\n */\n const plugins = {};\n\n /**\n * @type {Object} the test of the runner\n */\n const states = {\n init: false,\n ready: false,\n render: false,\n finish: false,\n destroy: false\n };\n\n /**\n * @type {Object} keeps the states of the items\n */\n let itemStates = {};\n\n /**\n * The selected test runner provider\n */\n const provider = testRunnerFactory.getProvider(providerName);\n\n /**\n * Keep the area broker instance\n * @see taoTests/runner/areaBroker\n */\n let areaBroker;\n\n /**\n * Keep the proxy instance\n * @see taoTests/runner/proxy\n */\n let proxy;\n\n /**\n * Keep the instance of the probes overseer\n * @see taoTests/runner/probeOverseer\n */\n let probeOverseer;\n\n /**\n * Keep the instance of a testStore\n * @see taoTests/runner/testStore\n */\n let testStore;\n\n /**\n * Run a method of the provider (by delegation)\n *\n * @param {String} method - the method to run\n * @param {...} args - rest parameters given to the provider method\n * @returns {Promise} so provider can do async stuffs\n */\n function providerRun(method) {\n for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {\n args[_key - 1] = arguments[_key];\n }\n return new Promise(resolve => {\n if (!_.isFunction(provider[method])) {\n return resolve();\n }\n return resolve(provider[method].apply(runner, args));\n });\n }\n\n /**\n * Run a method in all plugins\n *\n * @param {String} method - the method to run\n * @returns {Promise} once that resolve when all plugins are done\n */\n function pluginRun(method) {\n var execStack = [];\n _.forEach(runner.getPlugins(), plugin => {\n if (_.isFunction(plugin[method])) {\n execStack.push(plugin[method]());\n }\n });\n return Promise.all(execStack);\n }\n\n /**\n * Trigger error event\n * @param {Error|String} err - the error\n * @fires runner#error\n */\n function reportError(err) {\n runner.trigger('error', err);\n }\n\n /**\n * Defines the test runner\n *\n * @type {runner}\n */\n runner = eventifier({\n /**\n * Initialize the runner\n * - instantiate the plugins\n * - provider init\n * - plugins init\n * - call render\n * @fires runner#init\n * @returns {runner} chains\n */\n init() {\n if (!dataHolder) {\n dataHolder = this.getDataHolder();\n }\n\n //instantiate the plugins first\n _.forEach(pluginFactories, pluginFactory => {\n const plugin = pluginFactory(runner, this.getAreaBroker());\n plugins[plugin.getName()] = plugin;\n });\n providerRun('install').then(_.partial(providerRun, 'loadPersistentStates')).then(_.partial(pluginRun, 'install')).then(_.partial(providerRun, 'init')).then(_.partial(pluginRun, 'init')).then(() => {\n this.setState('init', true).off('init.internal').after('init.internal', () => this.render()).trigger('init');\n }).catch(reportError);\n return this;\n },\n /**\n * Render the runner\n * - provider render\n * - plugins render\n * @fires runner#render\n * @fires runner#ready\n * @returns {runner} chains\n */\n render() {\n providerRun('render').then(() => pluginRun('render')).then(() => {\n this.setState('ready', true).trigger('render').trigger('ready');\n }).catch(reportError);\n return this;\n },\n /**\n * Load an item\n * - provider loadItem, resolve or return the itemData\n * - plugins loadItem\n * - call renderItem\n * @param {*} itemRef - something that let you identify the item to load\n * @fires runner#loaditem\n * @returns {runner} chains\n */\n loadItem(itemRef) {\n providerRun('loadItem', itemRef).then(itemData => {\n this.setItemState(itemRef, 'loaded', true).off('loaditem.internal').after('loaditem.internal', () => this.renderItem(itemRef, itemData)).trigger('loaditem', itemRef, itemData);\n }).catch(reportError);\n return this;\n },\n /**\n * Render an item\n * - provider renderItem\n * - plugins renderItem\n * @param {Object} itemRef\n * @param {Object} itemData - the loaded item data\n * @fires runner#renderitem\n * @returns {runner} chains\n */\n renderItem(itemRef, itemData) {\n providerRun('renderItem', itemRef, itemData).then(() => {\n this.setItemState(itemRef, 'ready', true).trigger('renderitem', itemRef, itemData);\n }).catch(reportError);\n return this;\n },\n /**\n * Unload an item (for example to destroy the item)\n * - provider unloadItem\n * - plugins unloadItem\n * @param {*} itemRef - something that let you identify the item to unload\n * @fires runner#unloaditem\n * @returns {runner} chains\n */\n unloadItem(itemRef) {\n providerRun('unloadItem', itemRef).then(() => {\n itemStates = _.omit(itemStates, itemRef);\n this.trigger('unloaditem', itemRef);\n }).catch(reportError);\n return this;\n },\n /**\n * Disable an item\n * - provider disableItem\n * @param {*} itemRef - something that let you identify the item\n * @fires runner#disableitem\n * @returns {runner} chains\n */\n disableItem(itemRef) {\n if (!this.getItemState(itemRef, 'disabled')) {\n providerRun('disableItem', itemRef).then(() => {\n this.setItemState(itemRef, 'disabled', true).trigger('disableitem', itemRef);\n }).catch(reportError);\n }\n return this;\n },\n /**\n * Enable an item\n * - provider enableItem\n * @param {*} itemRef - something that let you identify the item\n * @fires runner#disableitem\n * @returns {runner} chains\n */\n enableItem(itemRef) {\n if (this.getItemState(itemRef, 'disabled')) {\n providerRun('enableItem', itemRef).then(() => {\n this.setItemState(itemRef, 'disabled', false).trigger('enableitem', itemRef);\n }).catch(reportError);\n }\n return this;\n },\n /**\n * When the test is terminated\n * - provider finish\n * - plugins finsh\n * @fires runner#finish\n * @returns {runner} chains\n */\n finish() {\n providerRun('finish').then(() => pluginRun('finish')).then(() => {\n this.setState('finish', true).trigger('finish');\n }).catch(reportError);\n return this;\n },\n /**\n * Flushes the runner\n * - provider flush\n * - plugins flush\n * @fires runner#flush\n * @returns {runner} chains\n */\n flush() {\n providerRun('flush').then(() => pluginRun('flush')).then(() => {\n this.setState('flush', true).trigger('flush');\n }).catch(reportError);\n return this;\n },\n /**\n * Destroy\n * - provider destroy\n * - plugins destroy\n * @fires runner#destroy\n * @returns {runner} chains\n */\n destroy() {\n providerRun('destroy').then(() => pluginRun('destroy')).then(() => {\n if (proxy) {\n return proxy.destroy();\n }\n }).then(() => {\n this.setTestContext({}).setTestMap({}).setState('destroy', true).trigger('destroy');\n }).catch(reportError);\n return this;\n },\n /**\n * Get the whole test runner configuration\n * @returns {Object} the config\n */\n getConfig() {\n return config || {};\n },\n /**\n * Get the options from the configuration parameters, (feature flags, parameter values, etc.)\n *\n * Alias to getConfig().options\n *\n * In deprecated mode, this is initialized through getTestData (after /init)\n *\n * @returns {Object} the configuration options\n */\n getOptions() {\n return this.getConfig().options || {};\n },\n /**\n * Get the runner pugins\n * @returns {plugin[]} the plugins\n */\n getPlugins() {\n return plugins;\n },\n /**\n * Get a plugin\n * @param {String} name - the plugin name\n * @returns {plugin} the plugin\n */\n getPlugin(name) {\n return plugins[name];\n },\n /**\n * Get the configuration of the plugins\n *\n * Alias to getConfig().options.plugins\n *\n * In deprecated mode, this is initialized through getTestData (after /init)\n *\n * @returns {Object} the configuration options\n */\n getPluginsConfig() {\n return this.getOptions().plugins || {};\n },\n /**\n * Get the configuration of a given plugin\n *\n * In deprecated mode, this is initialized through getTestData (after /init)\n *\n * @param {String} pluginName - the name of the plugin\n * @returns {Object} the configuration options of the plugin\n */\n getPluginConfig(pluginName) {\n if (pluginName && plugins[pluginName]) {\n const pluginsConfig = this.getPluginsConfig();\n if (pluginsConfig[pluginName]) {\n return pluginsConfig[pluginName];\n }\n }\n return {};\n },\n /**\n * Get the area broker, load it if not present\n *\n * @returns {areaBroker} the areaBroker\n */\n getAreaBroker() {\n if (!areaBroker) {\n areaBroker = provider.loadAreaBroker.call(this);\n }\n return areaBroker;\n },\n /**\n * Get the proxy, load it if not present\n *\n * @returns {proxy} the proxy\n */\n getProxy() {\n if (!proxy) {\n if (!_.isFunction(provider.loadProxy)) {\n throw new Error('The provider does not have a loadProxy method');\n }\n proxy = provider.loadProxy.call(this);\n proxy.on('error', error => this.trigger('error', error));\n proxy.install(this.getDataHolder());\n }\n return proxy;\n },\n /**\n * Get the probeOverseer, and load it if not present\n *\n * @returns {probeOverseer} the probe overseer\n */\n getProbeOverseer() {\n if (!probeOverseer && _.isFunction(provider.loadProbeOverseer)) {\n probeOverseer = provider.loadProbeOverseer.call(this);\n }\n return probeOverseer;\n },\n /**\n * Get the testStore, and load it if not present\n *\n * @returns {testStore} the testStore instance\n */\n getTestStore() {\n if (!testStore && _.isFunction(provider.loadTestStore)) {\n testStore = provider.loadTestStore.call(this);\n }\n return testStore;\n },\n /**\n * Get a plugin store.\n * It's a convenience method that calls testStore.getStore\n * @param {String} name - the name of store, usually the plugin name.\n *\n * @returns {Promise} the plugin store\n */\n getPluginStore(name) {\n const loadedStore = this.getTestStore();\n if (!loadedStore || !_.isFunction(loadedStore.getStore)) {\n return Promise.reject(new Error('Please configure a testStore via loadTestStore to be able to get a plugin store'));\n }\n return this.getTestStore().getStore(name);\n },\n /**\n * Check a runner state\n *\n * @param {String} name - the state name\n * @returns {Boolean} if active, false if not set\n */\n getState(name) {\n return !!states[name];\n },\n /**\n * Define a runner state\n *\n * @param {String} name - the state name\n * @param {Boolean} active - is the state active\n * @returns {runner} chains\n * @throws {TypeError} if the state name is not a valid string\n */\n setState(name, active) {\n if (!_.isString(name) || _.isEmpty(name)) {\n throw new TypeError('The state must have a name');\n }\n states[name] = !!active;\n return this;\n },\n /**\n * Checks a runner persistent state\n * - provider getPersistentState\n *\n * @param {String} name - the state name\n * @returns {Boolean} if active, false if not set\n */\n getPersistentState(name) {\n let state;\n if (_.isFunction(provider.getPersistentState)) {\n state = provider.getPersistentState.call(runner, name);\n }\n return !!state;\n },\n /**\n * Defines a runner persistent state\n * - provider setPersistentState\n *\n * @param {String} name - the state name\n * @param {Boolean} active - is the state active\n * @returns {Promise} Returns a promise that:\n * - will be resolved once the state is fully stored\n * - will be rejected if any error occurs or if the state name is not a valid string\n */\n setPersistentState(name, active) {\n let stored;\n if (!_.isString(name) || _.isEmpty(name)) {\n stored = Promise.reject(new TypeError('The state must have a name'));\n } else {\n stored = providerRun('setPersistentState', name, !!active);\n }\n stored.catch(reportError);\n return stored;\n },\n /**\n * Check an item state\n *\n * @param {*} itemRef - something that let you identify the item\n * @param {String} name - the state name\n * @returns {Boolean} if active, false if not set\n *\n * @throws {TypeError} if there is no itemRef nor name\n */\n getItemState(itemRef, name) {\n if (_.isEmpty(itemRef) || _.isEmpty(name)) {\n throw new TypeError('The state is identified by an itemRef and a name');\n }\n return !!(itemStates[itemRef] && itemStates[itemRef][name]);\n },\n /**\n * Check an item state\n *\n * @param {*} itemRef - something that let you identify the item\n * @param {String} name - the state name\n * @param {Boolean} active - is the state active\n * @returns {runner} chains\n *\n * @throws {TypeError} if there is no itemRef nor name\n */\n setItemState(itemRef, name, active) {\n if (_.isEmpty(itemRef) || _.isEmpty(name)) {\n throw new TypeError('The state is identified by an itemRef and a name');\n }\n itemStates[itemRef] = itemStates[itemRef] || {\n loaded: false,\n ready: false,\n disabled: false\n };\n itemStates[itemRef][name] = !!active;\n return this;\n },\n /**\n * Get the test data/definition\n * @deprecated\n * @returns {Object} the test data\n */\n getTestData() {\n return dataHolder && dataHolder.get('testData');\n },\n /**\n * Set the test data/definition\n * @deprecated\n * @param {Object} testData - the test data\n * @returns {runner} chains\n */\n setTestData(testData) {\n if (dataHolder && _.isPlainObject(testData)) {\n dataHolder.set('testData', testData);\n }\n return this;\n },\n /**\n * Get the test context/state\n * @returns {Object} the test context\n */\n getTestContext() {\n return dataHolder && dataHolder.get('testContext');\n },\n /**\n * Set the test context/state\n * @param {Object} testContext - the context to set\n * @returns {runner} chains\n */\n setTestContext(testContext) {\n if (dataHolder && _.isPlainObject(testContext)) {\n dataHolder.set('testContext', testContext);\n }\n return this;\n },\n /**\n * Get the test items map\n * @returns {Object} the test map\n */\n getTestMap() {\n return dataHolder && dataHolder.get('testMap');\n },\n /**\n * Set the test items map\n * @param {Object} testMap - the map to set\n * @returns {runner} chains\n */\n setTestMap(testMap) {\n if (dataHolder && _.isPlainObject(testMap)) {\n dataHolder.set('testMap', testMap);\n }\n return this;\n },\n /**\n * Get the data holder\n * @returns {dataHolder}\n */\n getDataHolder() {\n if (!dataHolder) {\n if (_.isFunction(provider.loadDataHolder)) {\n dataHolder = provider.loadDataHolder.call(this);\n } else {\n dataHolder = dataHolderFactory();\n }\n }\n return dataHolder;\n },\n /**\n * Move next alias\n * @param {String|*} [scope] - the movement scope\n * @fires runner#move\n * @returns {runner} chains\n */\n next(scope) {\n if (_.isFunction(provider.next)) {\n return providerRun('next', scope);\n }\n\n //backward compat\n this.trigger('move', 'next', scope);\n return this;\n },\n /**\n * Move previous alias\n * @param {String|*} [scope] - the movement scope\n * @fires runner#move\n * @returns {runner} chains\n */\n previous(scope) {\n if (_.isFunction(provider.previous)) {\n return providerRun('previous', scope);\n }\n\n //backward compat\n this.trigger('move', 'previous', scope);\n return this;\n },\n /**\n * Move to alias\n * @param {String|Number} position - where to jump\n * @param {String|*} [scope] - the movement scope\n * @fires runner#move\n * @returns {runner} chains\n */\n jump(position, scope) {\n if (_.isFunction(provider.jump)) {\n return providerRun('jump', position, scope);\n }\n\n //backward compat\n this.trigger('move', 'jump', scope, position);\n return this;\n },\n /**\n * Skip alias\n * @param {String|*} [scope] - the movement scope\n * @param {String|*} [direction] - next/previous/jump\n * @param {Number|*} [ref] - the item ref\n * @fires runner#skip\n * @returns {runner} chains\n */\n skip(scope, direction, ref) {\n if (_.isFunction(provider.skip)) {\n return providerRun('skip', scope, direction, ref);\n }\n\n //backward compat\n this.trigger('skip', scope, direction, ref);\n return this;\n },\n /**\n * Exit the test\n * @param {String|*} [why] - reason the test is exited\n * @fires runner#exit\n * @returns {runner} chains\n */\n exit(why) {\n if (_.isFunction(provider.exit)) {\n return providerRun('exit', why);\n }\n\n //backward compat\n this.trigger('exit', why);\n return this;\n },\n /**\n * Pause the current execution\n * @fires runner#pause\n * @returns {runner} chains\n */\n pause() {\n if (_.isFunction(provider.pause)) {\n if (!this.getState('pause')) {\n this.setState('pause', true);\n return providerRun('pause');\n }\n return Promise.resolve();\n }\n\n //backward compat\n if (!this.getState('pause')) {\n this.setState('pause', true).trigger('pause');\n }\n return this;\n },\n /**\n * Resume a paused test\n * @fires runner#pause\n * @returns {runner} chains\n */\n resume() {\n if (_.isFunction(provider.resume)) {\n if (this.getState('pause')) {\n this.setState('pause', false);\n return providerRun('resume');\n }\n return Promise.resolve();\n }\n\n //backward compat\n if (this.getState('pause') === true) {\n this.setState('pause', false).trigger('resume');\n }\n return this;\n },\n /**\n * Notify a test timeout\n * @param {String} scope - The scope where the timeout occurred\n * @param {String} ref - The reference to the place where the timeout occurred\n * @param {Object} [timer] - The timer's descriptor, if any\n * @fires runner#timeout\n * @returns {runner} chains\n */\n timeout(scope, ref, timer) {\n if (_.isFunction(provider.timeout)) {\n return providerRun('timeout', scope, ref, timer);\n }\n\n //backward compat\n this.trigger('timeout', scope, ref, timer);\n return this;\n }\n });\n runner.on('move', function () {\n this.trigger(...arguments);\n }).after('destroy', function destroyCleanUp() {\n if (dataHolder) {\n dataHolder.clear();\n }\n areaBroker = null;\n proxy = null;\n probeOverseer = null;\n testStore = null;\n });\n return runner;\n }\n\n //bind the provider registration capabilities to the testRunnerFactory\n var runner = providerRegistry(testRunnerFactory, function validateProvider(provider) {\n //mandatory methods\n if (!_.isFunction(provider.loadAreaBroker)) {\n throw new TypeError('The runner provider MUST have a method that returns an areaBroker');\n }\n return true;\n });\n\n return runner;\n\n});\n\n","define('taoTests/runner/proxy',['lodash', 'async', 'core/delegator', 'core/eventifier', 'core/providerRegistry', 'core/tokenHandler', 'core/connectivity'], function (_, async, delegator, eventifier, providerRegistry, tokenHandlerFactory, connectivity) { 'use strict';\n\n _ = _ && Object.prototype.hasOwnProperty.call(_, 'default') ? _['default'] : _;\n async = async && Object.prototype.hasOwnProperty.call(async, 'default') ? async['default'] : async;\n delegator = delegator && Object.prototype.hasOwnProperty.call(delegator, 'default') ? delegator['default'] : delegator;\n eventifier = eventifier && Object.prototype.hasOwnProperty.call(eventifier, 'default') ? eventifier['default'] : eventifier;\n providerRegistry = providerRegistry && Object.prototype.hasOwnProperty.call(providerRegistry, 'default') ? providerRegistry['default'] : providerRegistry;\n tokenHandlerFactory = tokenHandlerFactory && Object.prototype.hasOwnProperty.call(tokenHandlerFactory, 'default') ? tokenHandlerFactory['default'] : tokenHandlerFactory;\n connectivity = connectivity && Object.prototype.hasOwnProperty.call(connectivity, 'default') ? connectivity['default'] : connectivity;\n\n /**\n * This program is free software; you can redistribute it and/or\n * modify it under the terms of the GNU General Public License\n * as published by the Free Software Foundation; under version 2\n * of the License (non-upgradable).\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n *\n * Copyright (c) 2016-2019 (original work) Open Assessment Technologies SA ;\n */\n var _defaults = {};\n var _slice = [].slice;\n\n /**\n * Defines a proxy bound to a particular adapter\n *\n * @param {String} proxyName - The name of the proxy adapter to use in the returned proxy instance\n * @param {Object} [config] - Some optional config depending of implementation,\n * this object will be forwarded to the proxy adapter\n * @returns {proxy} - The proxy instance, bound to the selected proxy adapter\n */\n function proxyFactory(proxyName, config) {\n var proxy, delegateProxy, communicator, communicatorPromise;\n var testDataHolder;\n var extraCallParams = {};\n var proxyAdapter = proxyFactory.getProvider(proxyName);\n var initConfig = _.defaults(config || {}, _defaults);\n var tokenHandler = tokenHandlerFactory();\n var middlewares = {};\n var initialized = false;\n var onlineStatus = connectivity.isOnline();\n\n /**\n * Gets parameters merged with extra parameters\n * @param {Object} [params]\n * @returns {Object}\n */\n function getParams(params) {\n var mergedParams = _.merge({}, params, extraCallParams);\n extraCallParams = {};\n return mergedParams;\n }\n\n /**\n * Gets the aggregated list of middlewares for a particular queue name\n * @param {String} queue - The name of the queue to get\n * @returns {Array}\n */\n function getMiddlewares(queue) {\n var list = middlewares[queue] || [];\n if (middlewares.all) {\n list = list.concat(middlewares.all);\n }\n return list;\n }\n\n /**\n * Applies the list of registered middlewares onto the received response\n * @param {Object} request - The request descriptor\n * @param {String} request.command - The name of the requested command\n * @param {Object} request.params - The map of provided parameters\n * @param {Object} response The response descriptor\n * @param {String} response.status The status of the response, can be either 'success' or 'error'\n * @param {Object} response.data The full response data\n * @returns {Promise}\n */\n function applyMiddlewares(request, response) {\n // wrap each middleware to provide parameters\n var list = _.map(getMiddlewares(request.command), function (middleware) {\n return function (next) {\n middleware(request, response, next);\n };\n });\n\n // apply each middleware in series, then resolve or reject the promise\n return new Promise(function (resolve, reject) {\n async.series(list, function (err) {\n // handle implicit error from response descriptor\n if (!err && 'error' === response.status) {\n err = response.data;\n }\n if (err) {\n reject(err);\n } else {\n proxy.trigger('receive', response.data, 'proxy');\n resolve(response.data);\n }\n });\n });\n }\n\n /**\n * Delegates the call to the proxy implementation and apply the middleware.\n *\n * @param {String} fnName - The name of the delegated method to call\n * @returns {Promise} - The delegated method must return a promise\n * @private\n * @throws Error\n */\n function delegate(fnName) {\n var request = {\n command: fnName,\n params: _slice.call(arguments, 1)\n };\n if (!initialized && !['install', 'init'].includes(fnName)) {\n return Promise.reject(new Error('Proxy is not properly initialized or has been destroyed!'));\n }\n return delegateProxy.apply(null, arguments).then(function (data) {\n // If the delegate call succeed the proxy is initialized.\n // Place this set here to avoid to wrap the init() into another promise.\n initialized = true;\n\n // handle successful request\n return applyMiddlewares(request, {\n status: 'success',\n data: data\n });\n }).catch(function (data) {\n // handle failed request\n return applyMiddlewares(request, {\n status: 'error',\n data: data\n });\n });\n }\n\n /**\n * Defines the test runner proxy\n * @typedef {proxy}\n */\n proxy = eventifier({\n /**\n * Add a middleware\n * @param {String} [command] The command queue in which add the middleware (default: 'all')\n * @param {Function...} callback - A middleware callback. Must accept 3 parameters: request, response, next.\n * @returns {proxy}\n */\n use: function use(command) {\n var queue = command && _.isString(command) ? command : 'all';\n var list = middlewares[queue] || [];\n middlewares[queue] = list;\n _.each(arguments, function (cb) {\n if (_.isFunction(cb)) {\n list.push(cb);\n }\n });\n return this;\n },\n /**\n * Install the proxy.\n * This step let's attach some features before the proxy reallys starts (before init).\n *\n * @param {Map} dataHolder - the test runner data holder\n * @returns {*}\n */\n install: function install(dataHolder) {\n if (dataHolder) {\n testDataHolder = dataHolder;\n }\n return delegate('install', initConfig);\n },\n /**\n * Initializes the proxy\n * @param {Object} [params] - An optional list of parameters\n * @returns {Promise} - Returns a promise. The proxy will be fully initialized on resolve.\n * Any error will be provided if rejected.\n * @fires init\n */\n init: function init(params) {\n /**\n * @event proxy#init\n * @param {Promise} promise\n * @param {Object} config\n * @param {Object} params\n */\n return delegate('init', initConfig, getParams(params));\n },\n /**\n * Uninstalls the proxy\n * @returns {Promise} - Returns a promise. The proxy will be fully uninstalled on resolve.\n * Any error will be provided if rejected.\n * @fires destroy\n */\n destroy: function destroy() {\n /**\n * @event proxy#destroy\n * @param {Promise} promise\n */\n return delegate('destroy').then(function () {\n // The proxy is now destroyed. A call to init() is mandatory to be able to use it again.\n initialized = false;\n\n // a communicator has been invoked and...\n if (communicatorPromise) {\n return new Promise(function (resolve, reject) {\n function destroyCommunicator() {\n communicator.destroy().then(resolve).catch(reject);\n }\n communicatorPromise\n // ... has been loaded successfully, then destroy it\n .then(function () {\n destroyCommunicator();\n })\n // ...has failed to be loaded, maybe no need to destroy it\n .catch(function () {\n if (communicator) {\n destroyCommunicator();\n } else {\n resolve();\n }\n });\n });\n }\n });\n },\n /**\n * Get the map that holds the test data\n * @returns {Map|Object} the dataHolder\n */\n getDataHolder: function getDataHolder() {\n return testDataHolder;\n },\n /**\n * Set the proxy as online\n * @returns {proxy} chains\n * @fires {proxy#reconnect}\n */\n setOnline: function setOnline() {\n if (this.isOffline()) {\n onlineStatus = true;\n this.trigger('reconnect');\n }\n return this;\n },\n /**\n * Set the proxy as offline\n * @param {String} [source] - source of the connectivity change\n * @returns {proxy} chains\n * @fires {proxy#disconnect}\n */\n setOffline: function setOffline(source) {\n if (this.isOnline()) {\n onlineStatus = false;\n this.trigger('disconnect', source);\n }\n return this;\n },\n /**\n * Are we online ?\n * @returns {Boolean}\n */\n isOnline: function isOnline() {\n return onlineStatus;\n },\n /**\n * Are we offline\n * @returns {Boolean}\n */\n isOffline: function isOffline() {\n return !onlineStatus;\n },\n /**\n * For the proxy a connection error is an error object with\n * source 'network', a 0 code and a false sent attribute.\n *\n * @param {Error|Object} err - the error to verify\n * @returns {Boolean} true if a connection error.\n */\n isConnectivityError: function isConnectivityError(err) {\n return _.isObject(err) && err.source === 'network' && err.code === 0 && err.sent === false;\n },\n /**\n * Gets the security token handler\n * @returns {tokenHandler}\n */\n getTokenHandler: function getTokenHandler() {\n return tokenHandler;\n },\n /**\n * Checks if a communication channel has been requested.\n * @returns {Boolean}\n */\n hasCommunicator: function hasCommunicator() {\n return !!communicatorPromise;\n },\n /**\n * Gets access to the communication channel, load it if not present\n * @returns {Promise} Returns a promise that will resolve the communication channel\n */\n getCommunicator: function getCommunicator() {\n var self = this;\n if (!initialized) {\n return Promise.reject(new Error('Proxy is not properly initialized or has been destroyed!'));\n }\n if (!communicatorPromise) {\n communicatorPromise = new Promise(function (resolve, reject) {\n if (_.isFunction(proxyAdapter.loadCommunicator)) {\n communicator = proxyAdapter.loadCommunicator.call(self);\n if (communicator) {\n communicator.before('error', function (e, err) {\n if (self.isConnectivityError(err)) {\n self.setOffline('communicator');\n }\n }).on('error', function (err) {\n self.trigger('error', err);\n }).on('receive', function (response) {\n self.setOnline();\n self.trigger('receive', response, 'communicator');\n }).init().then(function () {\n return communicator.open().then(function () {\n resolve(communicator);\n }).catch(reject);\n }).catch(reject);\n } else {\n reject(new Error('No communicator has been set up!'));\n }\n } else {\n reject(new Error('The proxy provider does not have a loadCommunicator method'));\n }\n });\n }\n return communicatorPromise;\n },\n /**\n * Registers a listener on a particular channel\n * @param {String} name - The name of the channel to listen\n * @param {Function} handler - The listener callback\n * @returns {proxy}\n * @throws TypeError if the name is missing or the handler is not a callback\n */\n channel: function channel(name, handler) {\n if (!_.isString(name) || name.length <= 0) {\n throw new TypeError('A channel must have a name');\n }\n if (!_.isFunction(handler)) {\n throw new TypeError('A handler must be attached to a channel');\n }\n this.getCommunicator().then(function (communicatorInstance) {\n communicatorInstance.channel(name, handler);\n })\n // just an empty catch to avoid any error to be displayed in the console when the communicator is not enabled\n .catch(_.noop);\n this.on(`channel-${name}`, handler);\n return this;\n },\n /**\n * Sends an messages through the communication implementation.\n * @param {String} channel - The name of the communication channel to use\n * @param {Object} message - The message to send\n * @returns {Promise} The delegated provider's method must return a promise\n */\n send: function send(channel, message) {\n return this.getCommunicator().then(function (communicatorInstance) {\n return communicatorInstance.send(channel, message);\n });\n },\n /**\n * Add extra parameters that will be added to the init or the next callTestAction or callItemAction\n * This enables plugins to place parameters for next calls\n * @param {Object} params - the extra parameters\n * @returns {proxy}\n */\n addCallActionParams: function addCallActionParams(params) {\n if (_.isPlainObject(params)) {\n _.merge(extraCallParams, params);\n }\n return this;\n },\n /**\n * Gets the test definition data\n * @deprecated\n *\n * @returns {Promise} - Returns a promise. The test definition data will be provided on resolve.\n * Any error will be provided if rejected.\n * @fires getTestData\n */\n getTestData: function getTestData() {\n /**\n * @event proxy#getTestData\n * @param {Promise} promise\n */\n return delegate('getTestData');\n },\n /**\n * Gets the test context\n * @returns {Promise} - Returns a promise. The context object will be provided on resolve.\n * Any error will be provided if rejected.\n */\n getTestContext: function getTestContext() {\n /**\n * @event proxy#getTestContext\n * @param {Promise} promise\n */\n return delegate('getTestContext');\n },\n /**\n * Gets the test map\n * @returns {Promise} - Returns a promise. The test map object will be provided on resolve.\n * Any error will be provided if rejected.\n */\n getTestMap: function getTestMap() {\n /**\n * @event proxy#getTestMap\n * @param {Promise} promise\n */\n return delegate('getTestMap');\n },\n /**\n * Sends the test variables\n * @param {Object} variables\n * @param {Boolean} deferred whether action can be scheduled (put into queue) to be sent in a bunch of actions later (default: false).\n * @returns {Promise} - Returns a promise. The result of the request will be provided on resolve.\n * Any error will be provided if rejected.\n * @fires sendVariables\n */\n sendVariables: function sendVariables(variables, deferred) {\n /**\n * @event proxy#sendVariables\n * @param {Promise} promise\n */\n return delegate('sendVariables', variables, deferred);\n },\n /**\n * Calls an action related to the test\n * @param {String} action - The name of the action to call\n * @param {Object} [params] - Some optional parameters to join to the call\n * @param {Boolean} deferred whether action can be scheduled (put into queue) to be sent in a bunch of actions later.\n * @returns {Promise} - Returns a promise. The result of the request will be provided on resolve.\n * Any error will be provided if rejected.\n * @fires callTestAction\n */\n callTestAction: function callTestAction(action, params, deferred) {\n /**\n * @event proxy#callTestAction\n * @param {Promise} promise\n * @param {String} action\n * @param {Object} params\n */\n return delegate('callTestAction', action, getParams(params), deferred);\n },\n /**\n * Gets an item definition by its URI, also gets its current state\n * @param {String} uri - The URI of the item to get\n * @param {Object} [params] - addtional params to be appended\n * @returns {Promise} - Returns a promise. The item data will be provided on resolve.\n * Any error will be provided if rejected.\n * @fires getItem\n */\n getItem: function getItem(uri, params) {\n /**\n * @event proxy#getItem\n * @param {Promise} promise\n * @param {String} uri\n */\n return delegate('getItem', uri, params);\n },\n /**\n * Submits the state and the response of a particular item\n * @param {String} uri - The URI of the item to update\n * @param {Object} state - The state to submit\n * @param {Object} response - The response object to submit\n * @param {Object} [params] - addtional params to be appended\n * @returns {Promise} - Returns a promise. The result of the request will be provided on resolve.\n * Any error will be provided if rejected.\n * @fires submitItem\n */\n submitItem: function submitItem(uri, state, response, params) {\n /**\n * @event proxy#submitItem\n * @param {Promise} promise\n * @param {String} uri\n * @param {Object} state\n * @param {Object} response\n */\n return delegate('submitItem', uri, state, response, getParams(params));\n },\n /**\n * Calls an action related to a particular item\n * @param {String} uri - The URI of the item for which call the action\n * @param {String} action - The name of the action to call\n * @param {Object} [params] - Some optional parameters to join to the call\n * @param {Boolean} deferred whether action can be scheduled (put into queue) to be sent in a bunch of actions later.\n * @returns {Promise} - Returns a promise. The result of the request will be provided on resolve.\n * Any error will be provided if rejected.\n * @fires callItemAction\n */\n callItemAction: function callItemAction(uri, action, params, deferred) {\n /**\n * @event proxy#callItemAction\n * @param {Promise} promise\n * @param {String} uri\n * @param {String} action\n * @param {Object} params\n */\n return delegate('callItemAction', uri, action, getParams(params), deferred);\n },\n /**\n * Sends a telemetry signal\n * @param {String} uri - The URI of the item for which sends the telemetry signal\n * @param {String} signal - The name of the signal to send\n * @param {Object} [params] - Some optional parameters to join to the signal\n * @returns {Promise} - Returns a promise. The result of the request will be provided on resolve.\n * Any error will be provided if rejected.\n * @fires telemetry\n */\n telemetry: function telemetry(uri, signal, params) {\n /**\n * @event proxy#telemetry\n * @param {Promise} promise\n * @param {String} uri\n * @param {String} signal\n * @param {Object} params\n */\n return delegate('telemetry', uri, signal, params);\n }\n });\n\n //listen for connectivty changes\n connectivity.on('offline', function () {\n proxy.setOffline('device');\n }).on('online', function () {\n proxy.setOnline();\n });\n\n // catch platform messages that come outside of the communicator component, then each is dispatched to the right channel\n proxy.on('message', function (channel, message) {\n this.trigger(`channel-${channel}`, message);\n }).use(function (request, response, next) {\n if (response.data && response.data.messages) {\n // receive server messages\n _.forEach(response.data.messages, function (msg) {\n if (msg.channel) {\n proxy.trigger('message', msg.channel, msg.message);\n } else {\n proxy.trigger('message', 'malformed', msg);\n }\n });\n }\n next();\n })\n //detect failing request and change the online status\n .use(function (request, response, next) {\n if (proxy.isConnectivityError(response.data)) {\n proxy.setOffline('request');\n } else if (response.data && response.data.sent === true) {\n proxy.setOnline();\n }\n next();\n });\n delegateProxy = delegator(proxy, proxyAdapter, {\n name: 'proxy',\n wrapper: function pluginWrapper(response) {\n return Promise.resolve(response);\n }\n });\n return proxy;\n }\n var proxy = providerRegistry(proxyFactory);\n\n return proxy;\n\n});\n\n","define('taoTests/runner/providerLoader',['core/logger', 'core/providerLoader', 'core/pluginLoader', 'core/communicator', 'taoTests/runner/runner', 'taoTests/runner/proxy', 'taoItems/runner/api/itemRunner'], function (loggerFactory, providerLoader, pluginLoader, communicator, runner, proxy, itemRunner) { 'use strict';\n\n loggerFactory = loggerFactory && Object.prototype.hasOwnProperty.call(loggerFactory, 'default') ? loggerFactory['default'] : loggerFactory;\n providerLoader = providerLoader && Object.prototype.hasOwnProperty.call(providerLoader, 'default') ? providerLoader['default'] : providerLoader;\n pluginLoader = pluginLoader && Object.prototype.hasOwnProperty.call(pluginLoader, 'default') ? pluginLoader['default'] : pluginLoader;\n communicator = communicator && Object.prototype.hasOwnProperty.call(communicator, 'default') ? communicator['default'] : communicator;\n runner = runner && Object.prototype.hasOwnProperty.call(runner, 'default') ? runner['default'] : runner;\n proxy = proxy && Object.prototype.hasOwnProperty.call(proxy, 'default') ? proxy['default'] : proxy;\n itemRunner = itemRunner && Object.prototype.hasOwnProperty.call(itemRunner, 'default') ? itemRunner['default'] : itemRunner;\n\n /**\n * This program is free software; you can redistribute it and/or\n * modify it under the terms of the GNU General Public License\n * as published by the Free Software Foundation; under version 2\n * of the License (non-upgradable).\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n *\n * Copyright (c) 2019 Open Assessment Technologies SA ;\n */\n const logger = loggerFactory('taoTests/runner/loader');\n\n /**\n * @typedef {Object} provider - A provider is an object exposing a list of methods with respect to the API managed by the target.\n * @property {String} name - The name of the provider. It should be unique among all.\n * @property {Function} init - Each provider much expose at least a method `init()`\n * @property {Function} ... - Any other method the target is expecting\n */\n\n /**\n * Load the providers that match the registration\n * @param {Object} providers\n * @param {provider|provider[]} providers.runner\n * @param {provider|provider[]} [providers.proxy]\n * @param {provider|provider[]} [providers.communicator]\n * @param {provider|provider[]} [providers.plugins]\n * @param {Boolean} loadFromBundle - does the loader load the modules from the sources (dev mode) or the bundles\n * @returns {Promise} resolves with the loaded providers per provider type\n */\n function loadTestRunnerProviders() {\n let providers = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n let loadFromBundle = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;\n /**\n * Default way to load the modules and register the providers\n * @param {Object[]} providersToLoad - the list of providers\n * @param {Object} target - a provider target (an object that use the providers), it needs to expose registerProvider\n * @returns {Promise} resolves with the target\n * @throws {TypeError} if the target is not a provider target\n */\n const loadAndRegisterProvider = function () {\n let providersToLoad = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];\n let target = arguments.length > 1 ? arguments[1] : undefined;\n if (!target || typeof target.registerProvider !== 'function') {\n throw new TypeError('Trying to register providers on a target that is not a provider API');\n }\n return providerLoader().addList(providersToLoad).load(loadFromBundle).then(loadedProviders => {\n loadedProviders.forEach(provider => target.registerProvider(provider.name, provider));\n return target;\n });\n };\n\n /**\n * Available provider registration\n */\n const registration = {\n runner() {\n let runnerProviders = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];\n return loadAndRegisterProvider(runnerProviders, runner);\n },\n itemRunner() {\n let itemRunnerProviders = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];\n return providerLoader().addList(itemRunnerProviders).load(loadFromBundle).then(loadedProviders => {\n loadedProviders.forEach(provider => itemRunner.register(provider.name, provider));\n return itemRunner;\n });\n },\n communicator() {\n let communicatorProviders = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];\n return loadAndRegisterProvider(communicatorProviders, communicator);\n },\n proxy() {\n let proxyProviders = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];\n return loadAndRegisterProvider(proxyProviders, proxy);\n },\n plugins() {\n let plugins = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];\n return pluginLoader().addList(plugins).load(loadFromBundle);\n }\n };\n if (!loadFromBundle) {\n logger.warn('All modules will be loaded from sources');\n }\n return Promise.all(Object.keys(providers).map(providerType => {\n if (typeof registration[providerType] === 'function') {\n logger.debug(`Start to load and register the '${providerType}' providers`);\n const providersToLoad = Array.isArray(providers[providerType]) ? providers[providerType] : [providers[providerType]];\n return registration[providerType](providersToLoad).then(loaded => {\n logger.debug(`'${providerType}' providers are loaded and registered`);\n return {\n [providerType]: loaded\n };\n });\n } else {\n logger.warn(`Ignoring the '${providerType}' providers loading, no registration method found`);\n }\n })).then(results => results.reduce((acc, value) => Object.assign(acc, value), {})).catch(err => {\n logger.error(`Error in test runner providers and plugins loading : ${err.message}`);\n throw err;\n });\n }\n\n return loadTestRunnerProviders;\n\n});\n\n","define('taoTests/runner/proxy/sample',[],function () { 'use strict';\n\n /**\n * This program is free software; you can redistribute it and/or\n * modify it under the terms of the GNU General Public License\n * as published by the Free Software Foundation; under version 2\n * of the License (non-upgradable).\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n *\n * Copyright (c) 2016-2019 (original work) Open Assessment Technologies SA ;\n */\n /**\n * @author Jean-Sébastien Conan \n */\n\n /**\n * Sample proxy definition\n * @type {Object}\n */\n var sampleProxy = {\n /**\n * Initializes the proxy\n * @returns {Promise} - Returns a promise. The proxy will be fully initialized on resolve.\n * Any error will be provided if rejected.\n */\n init: function init() {\n // the method must return a promise\n return new Promise(function (resolve) {\n // do initialisation\n // once the proxy has been fully initialized notify the success by resolving the promise\n resolve();\n\n // you can also notify error by rejecting the promise\n // reject(error);\n });\n },\n\n /**\n * Uninstalls the proxy\n * @returns {Promise} - Returns a promise. The proxy will be fully uninstalled on resolve.\n * Any error will be provided if rejected.\n */\n destroy: function destroy() {\n // the method must return a promise\n return new Promise(function (resolve) {\n // do uninstall actions\n // once the proxy has been fully uninstalled notify the success by resolving the promise\n resolve();\n\n // you can also notify error by rejecting the promise\n // reject(error);\n });\n },\n\n /**\n * Gets the test definition data\n * @param {Object} config - The config provided to the proxy factory\n * @returns {Promise} - Returns a promise. The test definition data will be provided on resolve.\n * Any error will be provided if rejected.\n */\n getTestData: function getTestData() {\n // the method must return a promise\n return new Promise(function (resolve) {\n // get the test definition data\n\n // once the action has been processed notify the success by resolving the promise\n resolve( /* the test definition data */);\n\n // you can also notify error by rejecting the promise\n // reject(error);\n });\n },\n\n /**\n * Gets the test context\n * @returns {Promise} - Returns a promise. The context object will be provided on resolve.\n * Any error will be provided if rejected.\n */\n getTestContext: function getTestContext() {\n // the method must return a promise\n return new Promise(function (resolve) {\n // get the test context object\n\n // once the action has been processed notify the success by resolving the promise\n resolve( /* the test context object */);\n\n // you can also notify error by rejecting the promise\n // reject(error);\n });\n },\n\n /**\n * Calls an action related to the test\n * @param {String} action - The name of the action to call\n * @param {Object} [params] - Some optional parameters to join to the call\n * @returns {Promise} - Returns a promise. The result of the request will be provided on resolve.\n * Any error will be provided if rejected.\n */\n callTestAction: function callTestAction() {\n // the method must return a promise\n return new Promise(function (resolve) {\n // call the action\n\n // once the action has been processed notify the success by resolving the promise\n resolve( /* the action response */);\n\n // you can also notify error by rejecting the promise\n // reject(error);\n });\n },\n\n /**\n * Gets an item definition by its URI, also gets its current state\n * @param {String} uri - The URI of the item to get\n * @returns {Promise} - Returns a promise. The item data will be provided on resolve.\n * Any error will be provided if rejected.\n * @fires getItem\n */\n getItem: function getItem() {\n // the method must return a promise\n return new Promise(function (resolve) {\n // get the definition data and the state of the item\n // once the item data is loaded provide the data by resolving the promise\n resolve( /* the item data */);\n\n // you can also notify error by rejecting the promise\n // reject(error);\n });\n },\n\n /**\n * Submits the state and the response of a particular item\n * @param {String} uri - The URI of the item to update\n * @param {Object} state - The state to submit\n * @param {Object} response - The response object to submit\n * @returns {Promise} - Returns a promise. The result of the request will be provided on resolve.\n * Any error will be provided if rejected.\n * @fires submitItem\n */\n submitItem: function submitItem() {\n // the method must return a promise\n return new Promise(function (resolve) {\n // submit the state and the response of the item\n\n // once the data has been processed notify the success by resolving the promise\n resolve( /* the action response */);\n\n // you can also notify error by rejecting the promise\n // reject(error);\n });\n },\n\n /**\n * Calls an action related to a particular item\n * @param {String} uri - The URI of the item for which call the action\n * @param {String} action - The name of the action to call\n * @param {Object} [params] - Some optional parameters to join to the call\n * @returns {Promise} - Returns a promise. The result of the request will be provided on resolve.\n * Any error will be provided if rejected.\n */\n callItemAction: function callItemAction() {\n // the method must return a promise\n return new Promise(function (resolve) {\n // call the action\n\n // once the action has been processed notify the success by resolving the promise\n resolve( /* the action response */);\n\n // you can also notify error by rejecting the promise\n // reject(error);\n });\n },\n\n /**\n * Sends a telemetry signal\n * @param {String} uri - The URI of the item for which sends the telemetry signal\n * @param {String} signal - The name of the signal to send\n * @param {Object} [params] - Some optional parameters to join to the signal\n * @returns {Promise} - Returns a promise. The result of the request will be provided on resolve.\n * Any error will be provided if rejected.\n * @fires telemetry\n */\n telemetry: function telemetry() {\n // the method must return a promise\n return new Promise(function (resolve) {\n // send the signal\n\n // once the signal has been processed notify the success by resolving the promise\n resolve( /* the signal response */);\n\n // you can also notify error by rejecting the promise\n // reject(error);\n });\n }\n };\n\n return sampleProxy;\n\n});\n\n","define('taoTests/runner/runnerComponent',['lodash', 'ui/component', 'taoTests/runner/runner', 'taoTests/runner/providerLoader', 'handlebars'], function (_, component, runnerFactory, providerLoader, Handlebars) { 'use strict';\n\n _ = _ && Object.prototype.hasOwnProperty.call(_, 'default') ? _['default'] : _;\n component = component && Object.prototype.hasOwnProperty.call(component, 'default') ? component['default'] : component;\n runnerFactory = runnerFactory && Object.prototype.hasOwnProperty.call(runnerFactory, 'default') ? runnerFactory['default'] : runnerFactory;\n providerLoader = providerLoader && Object.prototype.hasOwnProperty.call(providerLoader, 'default') ? providerLoader['default'] : providerLoader;\n Handlebars = Handlebars && Object.prototype.hasOwnProperty.call(Handlebars, 'default') ? Handlebars['default'] : Handlebars;\n\n var Template = Handlebars.template(function (Handlebars,depth0,helpers,partials,data) {\n this.compilerInfo = [4,'>= 1.0.0'];\n helpers = this.merge(helpers, Handlebars.helpers); \n\n\n return \"
\\n\";\n });\n function runnerComponentTpl(data, options, asString) {\n var html = Template(data, options);\n return (asString || true) ? html : $(html);\n }\n\n /**\n * This program is free software; you can redistribute it and/or\n * modify it under the terms of the GNU General Public License\n * as published by the Free Software Foundation; under version 2\n * of the License (non-upgradable).\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n *\n * Copyright (c) 2017-2019 (original work) Open Assessment Technologies SA ;\n */\n\n /**\n * Validate required options from the configuration\n * @param {Object} config\n * @returns {Boolean} true if valid\n * @throws {TypeError} in case of validation failure\n */\n function validateTestRunnerConfiguration() {\n let config = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n const requiredProperties = ['providers', 'options', 'serviceCallId'];\n if (typeof config !== 'object') {\n throw new TypeError(`The runner configuration must be an object, '${typeof config}' received`);\n }\n if (requiredProperties.some(property => typeof config[property] === 'undefined')) {\n throw new TypeError(`The runner configuration must contains at least the following properties : ${requiredProperties.join(',')}`);\n }\n return true;\n }\n\n /**\n * Get the selected provider if set or infer it from the providers list\n * @param {String} type - the type of provider (runner, communicator, proxy, etc.)\n * @param {Object} config\n * @returns {String} the selected provider for the given type\n */\n function getSelectedProvider() {\n let type = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'runner';\n let config = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n if (config.provider && config.provider[type]) {\n return config.provider[type];\n }\n if (config.providers && config.providers[type]) {\n const typeProviders = config.providers[type];\n if (typeof typeProviders === 'object' && (typeProviders.id || typeProviders.name)) {\n return typeProviders.id || typeProviders.name;\n }\n if (Array.isArray(typeProviders) && typeProviders.length > 0) {\n return typeProviders[0].id || typeProviders[0].name;\n }\n }\n return false;\n }\n\n /**\n * Wraps a test runner into a component\n * @param {jQuery|HTMLElement|String} container - The container in which renders the component\n * @param {Object} config - The component configuration options\n * @param {String} config.serviceCallId - The identifier of the test session\n * @param {Object} config.providers\n * @param {Object} config.options\n * @param {Boolean} [config.loadFromBundle=false] - do we load the modules from the bundles\n * @param {Boolean} [config.replace] - When the component is appended to its container, clears the place before\n * @param {Number|String} [config.width] - The width in pixels, or 'auto' to use the container's width\n * @param {Number|String} [config.height] - The height in pixels, or 'auto' to use the container's height\n * @param {Function} [template] - An optional template for the component\n * @returns {runnerComponent}\n */\n function runnerComponentFactory() {\n let container = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;\n let config = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n let template = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : runnerComponentTpl;\n let runner = null;\n let plugins = [];\n if (!container) {\n throw new TypeError('A container element must be defined to contain the runnerComponent');\n }\n validateTestRunnerConfiguration(config);\n\n /**\n * @typedef {runner} runnerComponent\n */\n const runnerComponent = component({\n /**\n * Gets the option's value\n * @param {String} name - the option key\n * @returns {*}\n */\n getOption(name) {\n return this.config.options[name];\n },\n /**\n * Gets the test runner\n * @returns {runner}\n */\n getRunner() {\n return runner;\n }\n }).setTemplate(template).on('init', function () {\n //load the defined providers for the runner, the proxy, the communicator, the plugins, etc.\n return providerLoader(config.providers, config.loadFromBundle).then(results => {\n if (results && results.plugins) {\n plugins = results.plugins;\n }\n this.render(container);\n this.hide();\n }).catch(err => this.trigger('error', err));\n }).on('render', function () {\n const runnerConfig = Object.assign(_.omit(this.config, ['providers']), {\n renderTo: this.getElement()\n });\n runnerConfig.provider = Object.keys(this.config.providers).reduce((acc, providerType) => {\n if (!acc[providerType] && providerType !== 'plugins') {\n acc[providerType] = getSelectedProvider(providerType, this.config);\n }\n return acc;\n }, runnerConfig.provider || {});\n runner = runnerFactory(runnerConfig.provider.runner, plugins, runnerConfig).on('ready', () => {\n _.defer(() => {\n this.setState('ready').trigger('ready', runner).show();\n });\n }).on('destroy', () => runner = null).spread(this, 'error').init();\n }).on('destroy', function () {\n var destroying = runner && runner.destroy();\n runner = null;\n return destroying;\n }).after('destroy', function () {\n this.removeAllListeners();\n });\n return runnerComponent.init(config);\n }\n\n return runnerComponentFactory;\n\n});\n\n","define('taoTests/runner/runnerComponentSimple',['lodash', 'core/eventifier', 'taoTests/runner/runner', 'taoTests/runner/providerLoader'], function (_, eventifier, runnerFactory, providerLoader) { 'use strict';\n\n _ = _ && Object.prototype.hasOwnProperty.call(_, 'default') ? _['default'] : _;\n eventifier = eventifier && Object.prototype.hasOwnProperty.call(eventifier, 'default') ? eventifier['default'] : eventifier;\n runnerFactory = runnerFactory && Object.prototype.hasOwnProperty.call(runnerFactory, 'default') ? runnerFactory['default'] : runnerFactory;\n providerLoader = providerLoader && Object.prototype.hasOwnProperty.call(providerLoader, 'default') ? providerLoader['default'] : providerLoader;\n\n /**\n * This program is free software; you can redistribute it and/or\n * modify it under the terms of the GNU General Public License\n * as published by the Free Software Foundation; under version 2\n * of the License (non-upgradable).\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n *\n * Copyright (c) 2017-2023 (original work) Open Assessment Technologies SA ;\n */\n\n /**\n * Validate required options from the configuration\n * @param {Object} config\n * @returns {Boolean} true if valid\n * @throws {TypeError} in case of validation failure\n */\n function validateTestRunnerConfiguration() {\n let config = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n const requiredProperties = ['providers', 'options', 'serviceCallId'];\n if (typeof config !== 'object') {\n throw new TypeError(`The runner configuration must be an object, '${typeof config}' received`);\n }\n if (requiredProperties.some(property => typeof config[property] === 'undefined')) {\n throw new TypeError(`The runner configuration must contains at least the following properties : ${requiredProperties.join(',')}`);\n }\n return true;\n }\n\n /**\n * Get the selected provider if set or infer it from the providers list\n * @param {String} type - the type of provider (runner, communicator, proxy, etc.)\n * @param {Object} config\n * @returns {String} the selected provider for the given type\n */\n function getSelectedProvider() {\n let type = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'runner';\n let config = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n if (config.provider && config.provider[type]) {\n return config.provider[type];\n }\n if (config.providers && config.providers[type]) {\n const typeProviders = config.providers[type];\n if (typeof typeProviders === 'object' && (typeProviders.id || typeProviders.name)) {\n return typeProviders.id || typeProviders.name;\n }\n if (Array.isArray(typeProviders) && typeProviders.length > 0) {\n return typeProviders[0].id || typeProviders[0].name;\n }\n }\n return false;\n }\n\n /**\n * Wraps a test runner into a component\n * @param {jQuery|HTMLElement|String} container - The container in which renders the component\n * @param {Object} config - The component configuration options\n * @param {String} config.serviceCallId - The identifier of the test session\n * @param {Object} config.providers\n * @param {Object} config.options\n * @param {Boolean} [config.loadFromBundle=false] - do we load the modules from the bundles\n * @param {Boolean} [config.replace] - When the component is appended to its container, clears the place before\n * @param {Number|String} [config.width] - The width in pixels, or 'auto' to use the container's width\n * @param {Number|String} [config.height] - The height in pixels, or 'auto' to use the container's height\n * @returns {runnerComponent}\n */\n function runnerComponentFactory() {\n let container = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;\n let config = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n let runner = null;\n let plugins = [];\n if (!container) {\n throw new TypeError('A container element must be defined to contain the runnerComponent');\n }\n validateTestRunnerConfiguration(config);\n const runnerComponentApi = {\n /**\n * Initializes the component\n * @param {Object} configuration\n * @returns {runner}\n * @fires runner#init\n */\n init: function init(configuration) {\n this.config = _(configuration || {}).omit(function (value) {\n return value === null || typeof value === 'undefined';\n }).value();\n this.trigger('init');\n return this;\n },\n /**\n * Uninstalls the component\n * @returns {runner}\n * @fires component#destroy\n */\n destroy: function destroy() {\n this.trigger('destroy');\n return this;\n },\n /**\n * Renders the component\n * @returns {runner}\n * @fires runner#render\n */\n render: function render() {\n this.trigger('render');\n return this;\n },\n /**\n * Shows the component\n * @returns {runner}\n * @fires runner#show\n */\n show: function show() {\n this.trigger('show', this);\n return this;\n },\n /**\n * Hides the component\n * @returns {runner}\n * @fires runner#hide\n */\n hide: function hide() {\n this.trigger('hide', this);\n return this;\n },\n /**\n * Get the component's configuration\n * @returns {Object}\n */\n getConfig: function getConfig() {\n return this.config || {};\n },\n /**\n * Gets the test runner\n * @returns {runner}\n */\n getRunner() {\n return runner;\n }\n };\n const runnerComponent = eventifier(runnerComponentApi);\n runnerComponent.on('init', function () {\n //load the defined providers for the runner, the proxy, the communicator, the plugins, etc.\n return providerLoader(config.providers, config.loadFromBundle).then(results => {\n if (results && results.plugins) {\n plugins = results.plugins;\n }\n this.render(container);\n this.hide();\n }).catch(err => this.trigger('error', err));\n }).on('render', function () {\n this.component = document.createElement('div');\n this.component.classList.add('runner-component');\n container.append(this.component);\n const runnerConfig = Object.assign(_.omit(this.config, ['providers']), {\n renderTo: this.component\n });\n runnerConfig.provider = Object.keys(this.config.providers).reduce((acc, providerType) => {\n if (!acc[providerType] && providerType !== 'plugins') {\n acc[providerType] = getSelectedProvider(providerType, this.config);\n }\n return acc;\n }, runnerConfig.provider || {});\n runner = runnerFactory(runnerConfig.provider.runner, plugins, runnerConfig).on('ready', () => {\n _.defer(() => {\n this.trigger('ready', runner).show();\n });\n }).on('destroy', () => runner = null).spread(this, 'error').init();\n }).on('hide', function () {\n if (this.component) {\n this.component.classList.add('hidden');\n }\n }).on('show', function () {\n if (this.component) {\n this.component.classList.remove('hidden');\n }\n }).on('destroy', function () {\n var destroying = runner && runner.destroy();\n runner = null;\n if (this.component) {\n this.component.remove();\n }\n return destroying;\n }).after('destroy', function () {\n this.removeAllListeners();\n });\n return runnerComponent.init(config);\n }\n\n return runnerComponentFactory;\n\n});\n\n","define('taoTests/runner/testStore',['lodash', 'core/store', 'core/logger'], function (_, store, loggerFactory) { 'use strict';\n\n _ = _ && Object.prototype.hasOwnProperty.call(_, 'default') ? _['default'] : _;\n store = store && Object.prototype.hasOwnProperty.call(store, 'default') ? store['default'] : store;\n loggerFactory = loggerFactory && Object.prototype.hasOwnProperty.call(loggerFactory, 'default') ? loggerFactory['default'] : loggerFactory;\n\n /*\n * This program is free software; you can redistribute it and/or\n * modify it under the terms of the GNU General Public License\n * as published by the Free Software Foundation; under version 2\n * of the License (non-upgradable).\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n *\n * Copyright (c) 2017-2019 (original work) Open Assessment Technologies SA\n *\n */\n\n /**\n * The test store logger\n * @type {core/logger}\n */\n var logger = loggerFactory('taoQtiTest/runner/provider/testStore');\n\n /**\n * Database name prefix (suffixed by the test identifier)\n * to check if we use the fragmented mode\n * or the unified mode.\n * @type {String[]}\n */\n var legacyPrefixes = ['actions-', 'duration-', 'test-probe', 'timer-'];\n\n /**\n * List the available modes\n */\n var modes = {\n unified: 'unified',\n //one db per test, new mode\n fragmented: 'fragmented' //mutliple dbs per test, legacy mode\n };\n\n /**\n * Check and select the store mode.\n * If any of the \"legacyPrefixes\" store is found, we used the fragmented mode\n * otherwise we'll use the unified mode.\n * @param {String} testId\n * @param {Object} [preselectedBackend] - the storage backend\n * @returns {Promise} resolves with the mode of the current test\n */\n var selectStoreMode = function selectStoreMode(testId, preselectedBackend) {\n return store.getAll(function validate(storeName) {\n return _.some(legacyPrefixes, function (prefix) {\n return !_.isEmpty(storeName) && prefix + testId === storeName;\n });\n }, preselectedBackend).then(function (foundStores) {\n if (_.isArray(foundStores) && foundStores.length > 0) {\n return modes.fragmented;\n }\n return modes.unified;\n });\n };\n\n /**\n * Get the store for the given test\n *\n * @param {String} testId - unique test instance id\n * @returns {testStore} a 'wrapped' store instance\n * @param {Object} [preselectedBackend] - the storage backend (automatically selected by default)\n * @throws {TypeError} without a testId\n */\n function testStoreLoader(testId, preselectedBackend) {\n var volatiles = [];\n var changeTracking = {};\n var testMode;\n\n /**\n * Is the test using a unified store mode ?\n * @returns {Promise} true if unified\n */\n var isStoreModeUnified = function isStoreModeUnified() {\n if (_.isUndefined(testMode)) {\n return selectStoreMode(testId, preselectedBackend).then(function (result) {\n if (result && typeof modes[result] !== 'undefined') {\n testMode = result;\n } else {\n //use the unified mode by default\n testMode = modes.unified;\n }\n logger.debug(`Test store mode ${result} for ${testId}`);\n return result === modes.unified;\n });\n }\n return Promise.resolve(testMode === modes.unified);\n };\n if (_.isEmpty(testId)) {\n throw new TypeError('The store must be identified with a unique test identifier');\n }\n\n /**\n * Wraps a store and add the support of \"volatile\" storages\n * @typedef {Object} testStore\n */\n return {\n /**\n * Get a wrapped store instance, that let's you use multiple stores inside one store...\n * (or in multiple stores if the test is in legacy mode)\n * @param {String} storeName - the name of the sub store\n * @returns {Promise}\n */\n getStore: function getStore(storeName) {\n //call when the current storge has been changed\n //only if the store is set to track changes\n var trackChange = function trackChange() {\n if (_.isBoolean(changeTracking[storeName])) {\n changeTracking[storeName] = true;\n }\n };\n if (_.isEmpty(storeName)) {\n throw new TypeError('A store name must be provided to get the store');\n }\n return isStoreModeUnified().then(function (isUnified) {\n var loadStore;\n if (isUnified) {\n loadStore = store(testId, preselectedBackend);\n } else {\n loadStore = store(`${storeName}-${testId}`, preselectedBackend);\n }\n return loadStore.then(function (loadedStore) {\n var keyPattern = new RegExp(`^${storeName}__`);\n var storeKey = function storeKey(key) {\n return isUnified ? `${storeName}__${key}` : key;\n };\n\n /**\n * The wrapped storage\n * @type {Object}\n */\n return {\n /**\n * Get an item with the given key\n * @param {String} key\n * @returns {Promise<*>} with the result in resolve, undefined if nothing\n */\n getItem: function getItem(key) {\n return loadedStore.getItem(storeKey(key));\n },\n /**\n * Get all store items\n * @returns {Promise} with a collection of items\n */\n getItems: function getItems() {\n if (isUnified) {\n return loadedStore.getItems().then(function (entries) {\n return _.transform(entries, function (acc, entry, key) {\n if (keyPattern.test(key)) {\n acc[key.replace(keyPattern, '')] = entry;\n }\n return acc;\n }, {});\n });\n } else {\n return loadedStore.getItems();\n }\n },\n /**\n * Set an item with the given key\n * @param {String} key - the item key\n * @param {*} value - the item value\n * @returns {Promise} with true in resolve if added/updated\n */\n setItem: function setItem(key, value) {\n trackChange();\n return loadedStore.setItem(storeKey(key), value);\n },\n /**\n * Remove an item with the given key\n * @param {String} key - the item key\n * @returns {Promise} with true in resolve if removed\n */\n removeItem: function removeItem(key) {\n trackChange();\n return loadedStore.removeItem(storeKey(key));\n },\n /**\n * Clear the current store\n * @returns {Promise} with true in resolve once cleared\n */\n clear: function clear() {\n trackChange();\n if (isUnified) {\n return loadedStore.getItems().then(function (entries) {\n _.forEach(entries, function (entry, key) {\n if (keyPattern.test(key)) {\n loadedStore.removeItem(key);\n }\n });\n });\n } else {\n return loadedStore.clear();\n }\n }\n };\n });\n });\n },\n /**\n * Define the given store as \"volatile\".\n * It means the store data can be revoked\n * if the user change browser for example\n * @param {String} storeName - the name of the store to set as volatile\n * @returns {testStore} chains\n */\n setVolatile: function setVolatile(storeName) {\n if (!volatiles.includes(storeName)) {\n volatiles.push(storeName);\n }\n return this;\n },\n /**\n * Check the given storeId. If different from the current stored identifier\n * we initiate the invalidation of the volatile data.\n * @param {String} storeId - the id to check\n * @returns {Promise} true if cleared\n */\n clearVolatileIfStoreChange: function clearVolatileIfStoreChange(storeId) {\n var self = this;\n var shouldClear = false;\n return store.getIdentifier(preselectedBackend).then(function (savedStoreId) {\n if (!_.isEmpty(storeId) && !_.isEmpty(savedStoreId) && savedStoreId !== storeId) {\n logger.info(`Storage change detected (${savedStoreId} != ${storeId}) => volatiles data wipe out !`);\n shouldClear = true;\n }\n return shouldClear;\n }).then(function (clear) {\n if (clear) {\n return self.clearVolatileStores();\n }\n return false;\n });\n },\n /**\n * Clear the storages marked as volatile\n * @returns {Promise} true if cleared\n */\n clearVolatileStores: function clearVolatileStores() {\n var self = this;\n var clearing = volatiles.map(function (storeName) {\n return self.getStore(storeName).then(function (storeInstance) {\n return storeInstance.clear();\n });\n });\n return Promise.all(clearing).then(function (results) {\n return results && results.length === volatiles.length;\n });\n },\n /**\n * Observe changes on the given store\n *\n * @param {String} storeName - the name of the store to observe\n * @returns {testStore} chains\n */\n startChangeTracking: function startChangeTracking(storeName) {\n changeTracking[storeName] = false;\n return this;\n },\n /**\n * Has the store some changes\n *\n * @param {String} storeName - the name of the store to set as volatile\n * @returns {Boolean} true if the given store has some changes\n */\n hasChanges: function hasChanges(storeName) {\n return changeTracking[storeName] === true;\n },\n /**\n * Reset the change listening\n *\n * @param {String} storeName - the name of the store\n * @returns {testStore} chains\n */\n resetChanges: function resetChanges(storeName) {\n if (_.isBoolean(changeTracking[storeName])) {\n changeTracking[storeName] = false;\n }\n return this;\n },\n /**\n * Remove the whole store\n * @returns {Promise} true if done\n */\n remove: function remove() {\n var legacyStoreExp = new RegExp(`-${testId}$`);\n return isStoreModeUnified().then(function (isUnified) {\n if (isUnified) {\n return store(testId, preselectedBackend).then(function (storeInstance) {\n return storeInstance.removeStore();\n });\n }\n return store.removeAll(function (storeName) {\n return legacyStoreExp.test(storeName);\n }, preselectedBackend);\n });\n },\n /**\n * Wraps the identifier retrieval\n * @returns {Promise} the current store id\n */\n getStorageIdentifier: function getStorageIdentifier() {\n return store.getIdentifier(preselectedBackend);\n }\n };\n }\n\n return testStoreLoader;\n\n});\n\n","\ndefine(\"taoTests/loader/taoTestsRunner.bundle\", function(){});\n","define(\"taoTests/loader/taoTestsRunner.min\", [\"taoItems/loader/taoItems.min\"], function(){});\n"],"mappings":"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"} \ No newline at end of file +{"version":3,"names":["define","_","areaBroker$1","Object","prototype","hasOwnProperty","call","requireAreas","areaBroker","partial","dataHolderFactory","map","Map","defaultObjects","forEach","entry","set","pluginFactory","plugin","partialRight","hostName","moment","uuid","momentTimezone_min","probeOverseerFactory","runner","collectEvent","probe","eventNs","name","probeHandler","now","data","id","type","timestamp","format","timezone","tz","timeZone","capture","context","apply","concat","slice","arguments","overseer","push","latency","collectLatencyEvent","events","eventName","listen","indexOf","on","startHandler","marker","stopHandler","last","args","findLast","immutableQueue","startEvents","stopEvents","queueStorage","probes","queue","writing","Promise","resolve","started","getStorage","getTestStore","getStore","then","newStorage","resetStorage","isPlainObject","isFunction","init","TypeError","add","isString","isEmpty","some","val","length","isArray","getQueue","storage","getItem","getProbes","setItem","flush","flushed","start","savedQueue","stop","removeHandler","off","removeItem","guess","Array","eventifier","providerRegistry","testRunnerFactory","providerName","providerRun","method","_len","_key","provider","pluginRun","execStack","getPlugins","all","reportError","err","trigger","dataHolder","pluginFactories","config","plugins","states","ready","render","finish","destroy","itemStates","getProvider","proxy","probeOverseer","testStore","getDataHolder","getAreaBroker","getName","setState","after","catch","loadItem","itemRef","itemData","setItemState","renderItem","unloadItem","omit","disableItem","getItemState","enableItem","setTestContext","setTestMap","getConfig","getOptions","options","getPlugin","getPluginsConfig","getPluginConfig","pluginName","pluginsConfig","loadAreaBroker","getProxy","loadProxy","Error","error","install","getProbeOverseer","loadProbeOverseer","loadTestStore","getPluginStore","loadedStore","reject","getState","active","getPersistentState","state","setPersistentState","stored","loaded","disabled","getTestData","get","setTestData","testData","getTestContext","testContext","getTestMap","testMap","loadDataHolder","next","scope","previous","jump","position","skip","direction","ref","exit","why","pause","resume","timeout","timer","destroyCleanUp","clear","validateProvider","async","delegator","tokenHandlerFactory","connectivity","proxyFactory","proxyName","getParams","params","mergedParams","merge","extraCallParams","getMiddlewares","list","middlewares","applyMiddlewares","request","response","command","middleware","series","status","delegate","fnName","_slice","initialized","includes","delegateProxy","communicator","communicatorPromise","testDataHolder","proxyAdapter","initConfig","defaults","_defaults","tokenHandler","onlineStatus","isOnline","use","each","cb","destroyCommunicator","setOnline","isOffline","setOffline","source","isConnectivityError","isObject","code","sent","getTokenHandler","hasCommunicator","getCommunicator","self","loadCommunicator","before","e","open","channel","handler","communicatorInstance","noop","send","message","addCallActionParams","sendVariables","variables","deferred","callTestAction","action","uri","submitItem","callItemAction","telemetry","signal","messages","msg","wrapper","pluginWrapper","loggerFactory","providerLoader","pluginLoader","itemRunner","loadTestRunnerProviders","providers","loadFromBundle","loadAndRegisterProvider","providersToLoad","target","registerProvider","addList","load","loadedProviders","registration","runnerProviders","itemRunnerProviders","register","communicatorProviders","proxyProviders","logger","warn","keys","providerType","debug","results","reduce","acc","value","assign","sampleProxy","component","runnerFactory","Handlebars","runnerComponentTpl","asString","html","Template","$","validateTestRunnerConfiguration","requiredProperties","property","join","getSelectedProvider","typeProviders","runnerComponentFactory","container","template","runnerComponent","getOption","getRunner","setTemplate","hide","runnerConfig","renderTo","getElement","defer","show","spread","destroying","removeAllListeners","depth0","helpers","partials","compilerInfo","runnerComponentApi","configuration","document","createElement","classList","append","remove","store","testStoreLoader","testId","preselectedBackend","testMode","volatiles","changeTracking","isStoreModeUnified","isUndefined","selectStoreMode","result","modes","unified","storeName","trackChange","isBoolean","isUnified","loadStore","keyPattern","RegExp","storeKey","key","getItems","entries","transform","test","replace","setVolatile","clearVolatileIfStoreChange","storeId","shouldClear","getIdentifier","savedStoreId","info","clearVolatileStores","clearing","storeInstance","startChangeTracking","hasChanges","resetChanges","legacyStoreExp","removeStore","removeAll","getStorageIdentifier","legacyPrefixes","fragmented","getAll","validate","prefix","foundStores"],"sources":["/Users/oat/Projects/terre/tr-enterprise/files/delivery/tao/views/build/config-wrap-start-default.js","../runner/areaBroker.js","../runner/dataHolder.js","../runner/plugin.js","../runner/probeOverseer.js","../runner/runner.js","../runner/proxy.js","../runner/providerLoader.js","../runner/proxy/sample.js","../runner/runnerComponent.js","../runner/runnerComponentSimple.js","../runner/testStore.js","module-create.js","/Users/oat/Projects/terre/tr-enterprise/files/delivery/tao/views/build/config-wrap-end-default.js"],"sourcesContent":["\n","define('taoTests/runner/areaBroker',['lodash', 'ui/areaBroker'], function (_, areaBroker$1) { 'use strict';\n\n _ = _ && Object.prototype.hasOwnProperty.call(_, 'default') ? _['default'] : _;\n areaBroker$1 = areaBroker$1 && Object.prototype.hasOwnProperty.call(areaBroker$1, 'default') ? areaBroker$1['default'] : areaBroker$1;\n\n /*\n * This program is free software; you can redistribute it and/or\n * modify it under the terms of the GNU General Public License\n * as published by the Free Software Foundation; under version 2\n * of the License (non-upgradable).\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n *\n * Copyright (c) 2016-2019 (original work) Open Assessment Technlogies SA\n *\n */\n var requireAreas = ['content',\n //where the content is renderer, for example an item\n 'toolbox',\n //the place to add arbitrary tools, like a zoom, a comment box, etc.\n 'navigation',\n //the navigation controls like next, previous, skip\n 'control',\n //the control center of the test, progress, timers, etc.\n 'header',\n //the area that could contains the test titles\n 'panel' //a panel to add more advanced GUI (item review, navigation pane, etc.)\n ];\n\n /**\n * Creates an area broker with the required areas for the test runner.\n *\n * @see ui/areaBroker\n *\n * @param {jQueryElement|HTMLElement|String} $container - the main container\n * @param {Object} mapping - keys are the area names, values are jQueryElement\n * @returns {broker} the broker\n * @throws {TypeError} without a valid container\n */\n var areaBroker = _.partial(areaBroker$1, requireAreas);\n\n return areaBroker;\n\n});\n\n","define('taoTests/runner/dataHolder',[],function () { 'use strict';\n\n /*\n * This program is free software; you can redistribute it and/or\n * modify it under the terms of the GNU General Public License\n * as published by the Free Software Foundation; under version 2\n * of the License (non-upgradable).\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n *\n * Copyright (c) 2017-2019 (original work) Open Assessment Technlogies SA\n *\n */\n\n /**\n * Holds the test runner data.\n *\n * @example\n * var holder = holder();\n * holder.get('testMap');\n *\n * @author Bertrand Chevrier \n */\n\n /**\n * @type {String[]} the list of default objects to create\n */\n const defaultObjects = ['testContext', 'testMap'];\n\n /**\n * Creates a new data holder,\n * with default entries.\n *\n * @returns {Map} the holder\n */\n function dataHolderFactory() {\n var map = new Map();\n defaultObjects.forEach(function (entry) {\n map.set(entry, {});\n });\n return map;\n }\n\n return dataHolderFactory;\n\n});\n\n","define('taoTests/runner/plugin',['lodash', 'core/plugin'], function (_, pluginFactory) { 'use strict';\n\n _ = _ && Object.prototype.hasOwnProperty.call(_, 'default') ? _['default'] : _;\n pluginFactory = pluginFactory && Object.prototype.hasOwnProperty.call(pluginFactory, 'default') ? pluginFactory['default'] : pluginFactory;\n\n /**\n * This program is free software; you can redistribute it and/or\n * modify it under the terms of the GNU General Public License\n * as published by the Free Software Foundation; under version 2\n * of the License (non-upgradable).\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n *\n * Copyright (c) 2016-2019 (original work) Open Assessment Technologies SA ;\n */\n\n /**\n * A pluginFactory configured for the test runner\n * @returns {Function} the preconfigured plugin factory\n */\n var plugin = _.partialRight(pluginFactory, {\n //alias getHost to getTestRunner\n hostName: 'testRunner'\n });\n\n return plugin;\n\n});\n\n","define('taoTests/runner/probeOverseer',['lodash', 'moment', 'lib/uuid', 'lib/moment-timezone.min'], function (_, moment, uuid, momentTimezone_min) { 'use strict';\n\n _ = _ && Object.prototype.hasOwnProperty.call(_, 'default') ? _['default'] : _;\n moment = moment && Object.prototype.hasOwnProperty.call(moment, 'default') ? moment['default'] : moment;\n uuid = uuid && Object.prototype.hasOwnProperty.call(uuid, 'default') ? uuid['default'] : uuid;\n\n /*\n * This program is free software; you can redistribute it and/or\n * modify it under the terms of the GNU General Public License\n * as published by the Free Software Foundation; under version 2\n * of the License (non-upgradable).\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n *\n * Copyright (c) 2016-2019 (original work) Open Assessment Technlogies SA\n *\n */\n var timeZone = moment.tz.guess();\n var slice = Array.prototype.slice;\n\n /**\n * Create the overseer intance\n * @param {runner} runner - a instance of a test runner\n * @returns {probeOverseer} the new probe overseer\n * @throws TypeError if something goes wrong\n */\n function probeOverseerFactory(runner) {\n // the created instance\n var overseer;\n\n // the list of registered probes\n var probes = [];\n\n //temp queue\n var queue = [];\n\n //immutable queue which will not be flushed\n var immutableQueue = [];\n\n /**\n * @type {Storage} to store the collected events\n */\n var queueStorage;\n\n /**\n * @type {Promise} Promises chain to avoid write collisions\n */\n var writing = Promise.resolve();\n\n //is the overseer started\n var started = false;\n\n /**\n * Get the storage instance\n * @returns {Promise} that resolves with the storage\n */\n var getStorage = function getStorage() {\n if (queueStorage) {\n return Promise.resolve(queueStorage);\n }\n return runner.getTestStore().getStore('test-probe').then(function (newStorage) {\n queueStorage = newStorage;\n return Promise.resolve(queueStorage);\n });\n };\n\n /**\n * Unset the storage instance\n */\n var resetStorage = function resetStorage() {\n queueStorage = null;\n };\n\n /**\n * Register the collection event of a probe against a runner\n * @param {Object} probe - a valid probe\n */\n function collectEvent(probe) {\n var eventNs = `.probe-${probe.name}`;\n\n //event handler registered to collect data\n var probeHandler = function probeHandler() {\n var now = moment();\n var data = {\n id: uuid(12, 16),\n type: probe.name,\n timestamp: now.format('x') / 1000,\n timezone: now.tz(timeZone).format('Z')\n };\n if (typeof probe.capture === 'function') {\n data.context = probe.capture.apply(probe, [runner].concat(slice.call(arguments)));\n }\n overseer.push(data);\n };\n\n //fallback\n if (probe.latency) {\n return collectLatencyEvent(probe);\n }\n _.forEach(probe.events, function (eventName) {\n var listen = eventName.indexOf('.') > 0 ? eventName : eventName + eventNs;\n runner.on(listen, _.partial(probeHandler, eventName));\n });\n }\n function collectLatencyEvent(probe) {\n var eventNs = `.probe-${probe.name}`;\n\n //start event handler registered to collect data\n var startHandler = function startHandler() {\n var now = moment();\n var data = {\n id: uuid(12, 16),\n marker: 'start',\n type: probe.name,\n timestamp: now.format('x') / 1000,\n timezone: now.tz(timeZone).format('Z')\n };\n if (typeof probe.capture === 'function') {\n data.context = probe.capture.apply(probe, [runner].concat(slice.call(arguments)));\n }\n overseer.push(data);\n };\n\n //stop event handler registered to collect data\n var stopHandler = function stopHandler() {\n var now = moment();\n var last;\n var data = {\n type: probe.name,\n timestamp: now.format('x') / 1000,\n timezone: now.tz(timeZone).format('Z')\n };\n var args = slice.call(arguments);\n last = _.findLast(immutableQueue, {\n type: probe.name,\n marker: 'start'\n });\n if (last && !_.findLast(immutableQueue, {\n type: probe.name,\n marker: 'end',\n id: last.id\n })) {\n data.id = last.id;\n data.marker = 'end';\n if (typeof probe.capture === 'function') {\n data.context = probe.capture.apply(probe, [runner].concat(args));\n }\n overseer.push(data);\n }\n };\n\n //fallback\n if (!probe.latency) {\n return collectEvent(probe);\n }\n _.forEach(probe.startEvents, function (eventName) {\n var listen = eventName.indexOf('.') > 0 ? eventName : eventName + eventNs;\n runner.on(listen, _.partial(startHandler, eventName));\n });\n _.forEach(probe.stopEvents, function (eventName) {\n var listen = eventName.indexOf('.') > 0 ? eventName : eventName + eventNs;\n runner.on(listen, _.partial(stopHandler, eventName));\n });\n }\n\n //argument validation\n if (!_.isPlainObject(runner) || !_.isFunction(runner.init) || !_.isFunction(runner.on)) {\n throw new TypeError('Please set a test runner');\n }\n\n /**\n * @typedef {probeOverseer}\n */\n overseer = {\n /**\n * Add a new probe\n * @param {Object} probe\n * @param {String} probe.name - the probe name\n * @param {Boolean} [probe.latency = false] - simple or latency mode\n * @param {String[]} [probe.events] - the list of events to listen (simple mode)\n * @param {String[]} [probe.startEvents] - the list of events to mark the start (lantency mode)\n * @param {String[]} [probe.stopEvents] - the list of events to mark the end (latency mode)\n * @param {Function} [probe.capture] - lambda fn to define the data context, it receive the test runner and the event parameters\n * @returns {probeOverseer} chains\n * @throws TypeError if the probe is not well formatted\n */\n add: function add(probe) {\n // probe structure strict validation\n\n if (!_.isPlainObject(probe)) {\n throw new TypeError('A probe is a plain object');\n }\n if (!_.isString(probe.name) || _.isEmpty(probe.name)) {\n throw new TypeError('A probe must have a name');\n }\n if (probes.some(val => val.name === probe.name)) {\n throw new TypeError('A probe with this name is already regsitered');\n }\n if (probe.latency) {\n if (_.isString(probe.startEvents) && !_.isEmpty(probe.startEvents)) {\n probe.startEvents = [probe.startEvents];\n }\n if (_.isString(probe.stopEvents) && !_.isEmpty(probe.stopEvents)) {\n probe.stopEvents = [probe.stopEvents];\n }\n if (!probe.startEvents.length || !probe.stopEvents.length) {\n throw new TypeError('Latency based probes must have startEvents and stopEvents defined');\n }\n\n //if already started we register the events on addition\n if (started) {\n collectLatencyEvent(probe);\n }\n } else {\n if (_.isString(probe.events) && !_.isEmpty(probe.events)) {\n probe.events = [probe.events];\n }\n if (!_.isArray(probe.events) || probe.events.length === 0) {\n throw new TypeError('A probe must define events');\n }\n\n //if already started we register the events on addition\n if (started) {\n collectEvent(probe);\n }\n }\n probes.push(probe);\n return this;\n },\n /**\n * Get the time entries queue\n * @returns {Promise} with the data in parameterj\n */\n getQueue: function getQueue() {\n return getStorage().then(function (storage) {\n return storage.getItem('queue');\n });\n },\n /**\n * Get the list of defined probes\n * @returns {Object[]} the probes collection\n */\n getProbes: function getProbes() {\n return probes;\n },\n /**\n * Push a time entry to the queue\n * @param {Object} entry - the time entry\n */\n push: function push(entry) {\n getStorage().then(function (storage) {\n //ensure the queue is pushed to the store consistently and atomically\n writing = writing.then(function () {\n queue.push(entry);\n immutableQueue.push(entry);\n return storage.setItem('queue', queue);\n });\n });\n },\n /**\n * Flush the queue and get the entries\n * @returns {Promise} with the data in parameter\n */\n flush: function flush() {\n return new Promise(function (resolve) {\n getStorage().then(function (storage) {\n writing = writing.then(function () {\n return storage.getItem('queue').then(function (flushed) {\n queue = [];\n return storage.setItem('queue', queue).then(function () {\n resolve(flushed);\n });\n });\n });\n });\n });\n },\n /**\n * Start the probes\n * @returns {Promise} once started\n */\n start: function start() {\n return getStorage().then(function (storage) {\n return storage.getItem('queue').then(function (savedQueue) {\n if (_.isArray(savedQueue)) {\n queue = savedQueue;\n immutableQueue = savedQueue;\n }\n _.forEach(probes, collectEvent);\n started = true;\n });\n });\n },\n /**\n * Stop the probes\n * Be carefull, stop will also clear the store and the queue\n * @returns {Promise} once stopped\n */\n stop: function stop() {\n started = false;\n _.forEach(probes, function (probe) {\n var eventNs = `.probe-${probe.name}`;\n var removeHandler = function removeHandler(eventName) {\n runner.off(eventName + eventNs);\n };\n _.forEach(probe.startEvents, removeHandler);\n _.forEach(probe.stopEvents, removeHandler);\n _.forEach(probe.events, removeHandler);\n });\n queue = [];\n immutableQueue = [];\n return getStorage().then(function (storage) {\n return storage.removeItem('queue').then(resetStorage);\n });\n }\n };\n return overseer;\n }\n\n return probeOverseerFactory;\n\n});\n\n","define('taoTests/runner/runner',['lodash', 'core/eventifier', 'core/providerRegistry', 'taoTests/runner/dataHolder'], function (_, eventifier, providerRegistry, dataHolderFactory) { 'use strict';\n\n _ = _ && Object.prototype.hasOwnProperty.call(_, 'default') ? _['default'] : _;\n eventifier = eventifier && Object.prototype.hasOwnProperty.call(eventifier, 'default') ? eventifier['default'] : eventifier;\n providerRegistry = providerRegistry && Object.prototype.hasOwnProperty.call(providerRegistry, 'default') ? providerRegistry['default'] : providerRegistry;\n dataHolderFactory = dataHolderFactory && Object.prototype.hasOwnProperty.call(dataHolderFactory, 'default') ? dataHolderFactory['default'] : dataHolderFactory;\n\n /**\n * This program is free software; you can redistribute it and/or\n * modify it under the terms of the GNU General Public License\n * as published by the Free Software Foundation; under version 2\n * of the License (non-upgradable).\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n *\n * Copyright (c) 2015-2020 (original work) Open Assessment Technologies SA ;\n */\n\n /**\n * Builds an instance of the QTI test runner\n *\n * @param {String} providerName\n * @param {Function[]} pluginFactories\n * @param {Object} config\n * @param {String} config.serviceCallId - the identifier of the test session\n * @param {String} [config.testDefinition] - the identifier of the test definition\n * @param {String} [config.testCompilation] - the identifier of the compiled test\n * @param {Object} config.options - the test runner configuration options\n * @param {Object} config.options.plugins - the plugins configuration\n * @param {jQueryElement} [config.renderTo] - the dom element that is going to holds the test content (item, rubick, etc)\n * @returns {runner}\n */\n function testRunnerFactory(providerName) {\n let pluginFactories = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];\n let config = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n /**\n * @type {Object} The test runner instance\n */\n let runner;\n\n /**\n * @type {Map} Contains the test runner data\n */\n let dataHolder;\n\n /**\n * @type {Object} the registered plugins\n */\n const plugins = {};\n\n /**\n * @type {Object} the test of the runner\n */\n const states = {\n init: false,\n ready: false,\n render: false,\n finish: false,\n destroy: false\n };\n\n /**\n * @type {Object} keeps the states of the items\n */\n let itemStates = {};\n\n /**\n * The selected test runner provider\n */\n const provider = testRunnerFactory.getProvider(providerName);\n\n /**\n * Keep the area broker instance\n * @see taoTests/runner/areaBroker\n */\n let areaBroker;\n\n /**\n * Keep the proxy instance\n * @see taoTests/runner/proxy\n */\n let proxy;\n\n /**\n * Keep the instance of the probes overseer\n * @see taoTests/runner/probeOverseer\n */\n let probeOverseer;\n\n /**\n * Keep the instance of a testStore\n * @see taoTests/runner/testStore\n */\n let testStore;\n\n /**\n * Run a method of the provider (by delegation)\n *\n * @param {String} method - the method to run\n * @param {...} args - rest parameters given to the provider method\n * @returns {Promise} so provider can do async stuffs\n */\n function providerRun(method) {\n for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {\n args[_key - 1] = arguments[_key];\n }\n return new Promise(resolve => {\n if (!_.isFunction(provider[method])) {\n return resolve();\n }\n return resolve(provider[method].apply(runner, args));\n });\n }\n\n /**\n * Run a method in all plugins\n *\n * @param {String} method - the method to run\n * @returns {Promise} once that resolve when all plugins are done\n */\n function pluginRun(method) {\n var execStack = [];\n _.forEach(runner.getPlugins(), plugin => {\n if (_.isFunction(plugin[method])) {\n execStack.push(plugin[method]());\n }\n });\n return Promise.all(execStack);\n }\n\n /**\n * Trigger error event\n * @param {Error|String} err - the error\n * @fires runner#error\n */\n function reportError(err) {\n runner.trigger('error', err);\n }\n\n /**\n * Defines the test runner\n *\n * @type {runner}\n */\n runner = eventifier({\n /**\n * Initialize the runner\n * - instantiate the plugins\n * - provider init\n * - plugins init\n * - call render\n * @fires runner#init\n * @returns {runner} chains\n */\n init() {\n if (!dataHolder) {\n dataHolder = this.getDataHolder();\n }\n\n //instantiate the plugins first\n _.forEach(pluginFactories, pluginFactory => {\n const plugin = pluginFactory(runner, this.getAreaBroker());\n plugins[plugin.getName()] = plugin;\n });\n providerRun('install').then(_.partial(providerRun, 'loadPersistentStates')).then(_.partial(pluginRun, 'install')).then(_.partial(providerRun, 'init')).then(_.partial(pluginRun, 'init')).then(() => {\n this.setState('init', true).off('init.internal').after('init.internal', () => this.render()).trigger('init');\n }).catch(reportError);\n return this;\n },\n /**\n * Render the runner\n * - provider render\n * - plugins render\n * @fires runner#render\n * @fires runner#ready\n * @returns {runner} chains\n */\n render() {\n providerRun('render').then(() => pluginRun('render')).then(() => {\n this.setState('ready', true).trigger('render').trigger('ready');\n }).catch(reportError);\n return this;\n },\n /**\n * Load an item\n * - provider loadItem, resolve or return the itemData\n * - plugins loadItem\n * - call renderItem\n * @param {*} itemRef - something that let you identify the item to load\n * @fires runner#loaditem\n * @returns {runner} chains\n */\n loadItem(itemRef) {\n providerRun('loadItem', itemRef).then(itemData => {\n this.setItemState(itemRef, 'loaded', true).off('loaditem.internal').after('loaditem.internal', () => this.renderItem(itemRef, itemData)).trigger('loaditem', itemRef, itemData);\n }).catch(reportError);\n return this;\n },\n /**\n * Render an item\n * - provider renderItem\n * - plugins renderItem\n * @param {Object} itemRef\n * @param {Object} itemData - the loaded item data\n * @fires runner#renderitem\n * @returns {runner} chains\n */\n renderItem(itemRef, itemData) {\n providerRun('renderItem', itemRef, itemData).then(() => {\n this.setItemState(itemRef, 'ready', true).trigger('renderitem', itemRef, itemData);\n }).catch(reportError);\n return this;\n },\n /**\n * Unload an item (for example to destroy the item)\n * - provider unloadItem\n * - plugins unloadItem\n * @param {*} itemRef - something that let you identify the item to unload\n * @fires runner#unloaditem\n * @returns {runner} chains\n */\n unloadItem(itemRef) {\n providerRun('unloadItem', itemRef).then(() => {\n itemStates = _.omit(itemStates, itemRef);\n this.trigger('unloaditem', itemRef);\n }).catch(reportError);\n return this;\n },\n /**\n * Disable an item\n * - provider disableItem\n * @param {*} itemRef - something that let you identify the item\n * @fires runner#disableitem\n * @returns {runner} chains\n */\n disableItem(itemRef) {\n if (!this.getItemState(itemRef, 'disabled')) {\n providerRun('disableItem', itemRef).then(() => {\n this.setItemState(itemRef, 'disabled', true).trigger('disableitem', itemRef);\n }).catch(reportError);\n }\n return this;\n },\n /**\n * Enable an item\n * - provider enableItem\n * @param {*} itemRef - something that let you identify the item\n * @fires runner#disableitem\n * @returns {runner} chains\n */\n enableItem(itemRef) {\n if (this.getItemState(itemRef, 'disabled')) {\n providerRun('enableItem', itemRef).then(() => {\n this.setItemState(itemRef, 'disabled', false).trigger('enableitem', itemRef);\n }).catch(reportError);\n }\n return this;\n },\n /**\n * When the test is terminated\n * - provider finish\n * - plugins finsh\n * @fires runner#finish\n * @returns {runner} chains\n */\n finish() {\n providerRun('finish').then(() => pluginRun('finish')).then(() => {\n this.setState('finish', true).trigger('finish');\n }).catch(reportError);\n return this;\n },\n /**\n * Flushes the runner\n * - provider flush\n * - plugins flush\n * @fires runner#flush\n * @returns {runner} chains\n */\n flush() {\n providerRun('flush').then(() => pluginRun('flush')).then(() => {\n this.setState('flush', true).trigger('flush');\n }).catch(reportError);\n return this;\n },\n /**\n * Destroy\n * - provider destroy\n * - plugins destroy\n * @fires runner#destroy\n * @returns {runner} chains\n */\n destroy() {\n providerRun('destroy').then(() => pluginRun('destroy')).then(() => {\n if (proxy) {\n return proxy.destroy();\n }\n }).then(() => {\n this.setTestContext({}).setTestMap({}).setState('destroy', true).trigger('destroy');\n }).catch(reportError);\n return this;\n },\n /**\n * Get the whole test runner configuration\n * @returns {Object} the config\n */\n getConfig() {\n return config || {};\n },\n /**\n * Get the options from the configuration parameters, (feature flags, parameter values, etc.)\n *\n * Alias to getConfig().options\n *\n * In deprecated mode, this is initialized through getTestData (after /init)\n *\n * @returns {Object} the configuration options\n */\n getOptions() {\n return this.getConfig().options || {};\n },\n /**\n * Get the runner pugins\n * @returns {plugin[]} the plugins\n */\n getPlugins() {\n return plugins;\n },\n /**\n * Get a plugin\n * @param {String} name - the plugin name\n * @returns {plugin} the plugin\n */\n getPlugin(name) {\n return plugins[name];\n },\n /**\n * Get the configuration of the plugins\n *\n * Alias to getConfig().options.plugins\n *\n * In deprecated mode, this is initialized through getTestData (after /init)\n *\n * @returns {Object} the configuration options\n */\n getPluginsConfig() {\n return this.getOptions().plugins || {};\n },\n /**\n * Get the configuration of a given plugin\n *\n * In deprecated mode, this is initialized through getTestData (after /init)\n *\n * @param {String} pluginName - the name of the plugin\n * @returns {Object} the configuration options of the plugin\n */\n getPluginConfig(pluginName) {\n if (pluginName && plugins[pluginName]) {\n const pluginsConfig = this.getPluginsConfig();\n if (pluginsConfig[pluginName]) {\n return pluginsConfig[pluginName];\n }\n }\n return {};\n },\n /**\n * Get the area broker, load it if not present\n *\n * @returns {areaBroker} the areaBroker\n */\n getAreaBroker() {\n if (!areaBroker) {\n areaBroker = provider.loadAreaBroker.call(this);\n }\n return areaBroker;\n },\n /**\n * Get the proxy, load it if not present\n *\n * @returns {proxy} the proxy\n */\n getProxy() {\n if (!proxy) {\n if (!_.isFunction(provider.loadProxy)) {\n throw new Error('The provider does not have a loadProxy method');\n }\n proxy = provider.loadProxy.call(this);\n proxy.on('error', error => this.trigger('error', error));\n proxy.install(this.getDataHolder());\n }\n return proxy;\n },\n /**\n * Get the probeOverseer, and load it if not present\n *\n * @returns {probeOverseer} the probe overseer\n */\n getProbeOverseer() {\n if (!probeOverseer && _.isFunction(provider.loadProbeOverseer)) {\n probeOverseer = provider.loadProbeOverseer.call(this);\n }\n return probeOverseer;\n },\n /**\n * Get the testStore, and load it if not present\n *\n * @returns {testStore} the testStore instance\n */\n getTestStore() {\n if (!testStore && _.isFunction(provider.loadTestStore)) {\n testStore = provider.loadTestStore.call(this);\n }\n return testStore;\n },\n /**\n * Get a plugin store.\n * It's a convenience method that calls testStore.getStore\n * @param {String} name - the name of store, usually the plugin name.\n *\n * @returns {Promise} the plugin store\n */\n getPluginStore(name) {\n const loadedStore = this.getTestStore();\n if (!loadedStore || !_.isFunction(loadedStore.getStore)) {\n return Promise.reject(new Error('Please configure a testStore via loadTestStore to be able to get a plugin store'));\n }\n return this.getTestStore().getStore(name);\n },\n /**\n * Check a runner state\n *\n * @param {String} name - the state name\n * @returns {Boolean} if active, false if not set\n */\n getState(name) {\n return !!states[name];\n },\n /**\n * Define a runner state\n *\n * @param {String} name - the state name\n * @param {Boolean} active - is the state active\n * @returns {runner} chains\n * @throws {TypeError} if the state name is not a valid string\n */\n setState(name, active) {\n if (!_.isString(name) || _.isEmpty(name)) {\n throw new TypeError('The state must have a name');\n }\n states[name] = !!active;\n return this;\n },\n /**\n * Checks a runner persistent state\n * - provider getPersistentState\n *\n * @param {String} name - the state name\n * @returns {Boolean} if active, false if not set\n */\n getPersistentState(name) {\n let state;\n if (_.isFunction(provider.getPersistentState)) {\n state = provider.getPersistentState.call(runner, name);\n }\n return !!state;\n },\n /**\n * Defines a runner persistent state\n * - provider setPersistentState\n *\n * @param {String} name - the state name\n * @param {Boolean} active - is the state active\n * @returns {Promise} Returns a promise that:\n * - will be resolved once the state is fully stored\n * - will be rejected if any error occurs or if the state name is not a valid string\n */\n setPersistentState(name, active) {\n let stored;\n if (!_.isString(name) || _.isEmpty(name)) {\n stored = Promise.reject(new TypeError('The state must have a name'));\n } else {\n stored = providerRun('setPersistentState', name, !!active);\n }\n stored.catch(reportError);\n return stored;\n },\n /**\n * Check an item state\n *\n * @param {*} itemRef - something that let you identify the item\n * @param {String} name - the state name\n * @returns {Boolean} if active, false if not set\n *\n * @throws {TypeError} if there is no itemRef nor name\n */\n getItemState(itemRef, name) {\n if (_.isEmpty(itemRef) || _.isEmpty(name)) {\n throw new TypeError('The state is identified by an itemRef and a name');\n }\n return !!(itemStates[itemRef] && itemStates[itemRef][name]);\n },\n /**\n * Check an item state\n *\n * @param {*} itemRef - something that let you identify the item\n * @param {String} name - the state name\n * @param {Boolean} active - is the state active\n * @returns {runner} chains\n *\n * @throws {TypeError} if there is no itemRef nor name\n */\n setItemState(itemRef, name, active) {\n if (_.isEmpty(itemRef) || _.isEmpty(name)) {\n throw new TypeError('The state is identified by an itemRef and a name');\n }\n itemStates[itemRef] = itemStates[itemRef] || {\n loaded: false,\n ready: false,\n disabled: false\n };\n itemStates[itemRef][name] = !!active;\n return this;\n },\n /**\n * Get the test data/definition\n * @deprecated\n * @returns {Object} the test data\n */\n getTestData() {\n return dataHolder && dataHolder.get('testData');\n },\n /**\n * Set the test data/definition\n * @deprecated\n * @param {Object} testData - the test data\n * @returns {runner} chains\n */\n setTestData(testData) {\n if (dataHolder && _.isPlainObject(testData)) {\n dataHolder.set('testData', testData);\n }\n return this;\n },\n /**\n * Get the test context/state\n * @returns {Object} the test context\n */\n getTestContext() {\n return dataHolder && dataHolder.get('testContext');\n },\n /**\n * Set the test context/state\n * @param {Object} testContext - the context to set\n * @returns {runner} chains\n */\n setTestContext(testContext) {\n if (dataHolder && _.isPlainObject(testContext)) {\n dataHolder.set('testContext', testContext);\n }\n return this;\n },\n /**\n * Get the test items map\n * @returns {Object} the test map\n */\n getTestMap() {\n return dataHolder && dataHolder.get('testMap');\n },\n /**\n * Set the test items map\n * @param {Object} testMap - the map to set\n * @returns {runner} chains\n */\n setTestMap(testMap) {\n if (dataHolder && _.isPlainObject(testMap)) {\n dataHolder.set('testMap', testMap);\n }\n return this;\n },\n /**\n * Get the data holder\n * @returns {dataHolder}\n */\n getDataHolder() {\n if (!dataHolder) {\n if (_.isFunction(provider.loadDataHolder)) {\n dataHolder = provider.loadDataHolder.call(this);\n } else {\n dataHolder = dataHolderFactory();\n }\n }\n return dataHolder;\n },\n /**\n * Move next alias\n * @param {String|*} [scope] - the movement scope\n * @fires runner#move\n * @returns {runner} chains\n */\n next(scope) {\n if (_.isFunction(provider.next)) {\n return providerRun('next', scope);\n }\n\n //backward compat\n this.trigger('move', 'next', scope);\n return this;\n },\n /**\n * Move previous alias\n * @param {String|*} [scope] - the movement scope\n * @fires runner#move\n * @returns {runner} chains\n */\n previous(scope) {\n if (_.isFunction(provider.previous)) {\n return providerRun('previous', scope);\n }\n\n //backward compat\n this.trigger('move', 'previous', scope);\n return this;\n },\n /**\n * Move to alias\n * @param {String|Number} position - where to jump\n * @param {String|*} [scope] - the movement scope\n * @fires runner#move\n * @returns {runner} chains\n */\n jump(position, scope) {\n if (_.isFunction(provider.jump)) {\n return providerRun('jump', position, scope);\n }\n\n //backward compat\n this.trigger('move', 'jump', scope, position);\n return this;\n },\n /**\n * Skip alias\n * @param {String|*} [scope] - the movement scope\n * @param {String|*} [direction] - next/previous/jump\n * @param {Number|*} [ref] - the item ref\n * @fires runner#skip\n * @returns {runner} chains\n */\n skip(scope, direction, ref) {\n if (_.isFunction(provider.skip)) {\n return providerRun('skip', scope, direction, ref);\n }\n\n //backward compat\n this.trigger('skip', scope, direction, ref);\n return this;\n },\n /**\n * Exit the test\n * @param {String|*} [why] - reason the test is exited\n * @fires runner#exit\n * @returns {runner} chains\n */\n exit(why) {\n if (_.isFunction(provider.exit)) {\n return providerRun('exit', why);\n }\n\n //backward compat\n this.trigger('exit', why);\n return this;\n },\n /**\n * Pause the current execution\n * @fires runner#pause\n * @returns {runner} chains\n */\n pause() {\n if (_.isFunction(provider.pause)) {\n if (!this.getState('pause')) {\n this.setState('pause', true);\n return providerRun('pause');\n }\n return Promise.resolve();\n }\n\n //backward compat\n if (!this.getState('pause')) {\n this.setState('pause', true).trigger('pause');\n }\n return this;\n },\n /**\n * Resume a paused test\n * @fires runner#pause\n * @returns {runner} chains\n */\n resume() {\n if (_.isFunction(provider.resume)) {\n if (this.getState('pause')) {\n this.setState('pause', false);\n return providerRun('resume');\n }\n return Promise.resolve();\n }\n\n //backward compat\n if (this.getState('pause') === true) {\n this.setState('pause', false).trigger('resume');\n }\n return this;\n },\n /**\n * Notify a test timeout\n * @param {String} scope - The scope where the timeout occurred\n * @param {String} ref - The reference to the place where the timeout occurred\n * @param {Object} [timer] - The timer's descriptor, if any\n * @fires runner#timeout\n * @returns {runner} chains\n */\n timeout(scope, ref, timer) {\n if (_.isFunction(provider.timeout)) {\n return providerRun('timeout', scope, ref, timer);\n }\n\n //backward compat\n this.trigger('timeout', scope, ref, timer);\n return this;\n }\n });\n runner.on('move', function () {\n this.trigger(...arguments);\n }).after('destroy', function destroyCleanUp() {\n if (dataHolder) {\n dataHolder.clear();\n }\n areaBroker = null;\n proxy = null;\n probeOverseer = null;\n testStore = null;\n });\n return runner;\n }\n\n //bind the provider registration capabilities to the testRunnerFactory\n var runner = providerRegistry(testRunnerFactory, function validateProvider(provider) {\n //mandatory methods\n if (!_.isFunction(provider.loadAreaBroker)) {\n throw new TypeError('The runner provider MUST have a method that returns an areaBroker');\n }\n return true;\n });\n\n return runner;\n\n});\n\n","define('taoTests/runner/proxy',['lodash', 'async', 'core/delegator', 'core/eventifier', 'core/providerRegistry', 'core/tokenHandler', 'core/connectivity'], function (_, async, delegator, eventifier, providerRegistry, tokenHandlerFactory, connectivity) { 'use strict';\n\n _ = _ && Object.prototype.hasOwnProperty.call(_, 'default') ? _['default'] : _;\n async = async && Object.prototype.hasOwnProperty.call(async, 'default') ? async['default'] : async;\n delegator = delegator && Object.prototype.hasOwnProperty.call(delegator, 'default') ? delegator['default'] : delegator;\n eventifier = eventifier && Object.prototype.hasOwnProperty.call(eventifier, 'default') ? eventifier['default'] : eventifier;\n providerRegistry = providerRegistry && Object.prototype.hasOwnProperty.call(providerRegistry, 'default') ? providerRegistry['default'] : providerRegistry;\n tokenHandlerFactory = tokenHandlerFactory && Object.prototype.hasOwnProperty.call(tokenHandlerFactory, 'default') ? tokenHandlerFactory['default'] : tokenHandlerFactory;\n connectivity = connectivity && Object.prototype.hasOwnProperty.call(connectivity, 'default') ? connectivity['default'] : connectivity;\n\n /**\n * This program is free software; you can redistribute it and/or\n * modify it under the terms of the GNU General Public License\n * as published by the Free Software Foundation; under version 2\n * of the License (non-upgradable).\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n *\n * Copyright (c) 2016-2019 (original work) Open Assessment Technologies SA ;\n */\n var _defaults = {};\n var _slice = [].slice;\n\n /**\n * Defines a proxy bound to a particular adapter\n *\n * @param {String} proxyName - The name of the proxy adapter to use in the returned proxy instance\n * @param {Object} [config] - Some optional config depending of implementation,\n * this object will be forwarded to the proxy adapter\n * @returns {proxy} - The proxy instance, bound to the selected proxy adapter\n */\n function proxyFactory(proxyName, config) {\n var proxy, delegateProxy, communicator, communicatorPromise;\n var testDataHolder;\n var extraCallParams = {};\n var proxyAdapter = proxyFactory.getProvider(proxyName);\n var initConfig = _.defaults(config || {}, _defaults);\n var tokenHandler = tokenHandlerFactory();\n var middlewares = {};\n var initialized = false;\n var onlineStatus = connectivity.isOnline();\n\n /**\n * Gets parameters merged with extra parameters\n * @param {Object} [params]\n * @returns {Object}\n */\n function getParams(params) {\n var mergedParams = _.merge({}, params, extraCallParams);\n extraCallParams = {};\n return mergedParams;\n }\n\n /**\n * Gets the aggregated list of middlewares for a particular queue name\n * @param {String} queue - The name of the queue to get\n * @returns {Array}\n */\n function getMiddlewares(queue) {\n var list = middlewares[queue] || [];\n if (middlewares.all) {\n list = list.concat(middlewares.all);\n }\n return list;\n }\n\n /**\n * Applies the list of registered middlewares onto the received response\n * @param {Object} request - The request descriptor\n * @param {String} request.command - The name of the requested command\n * @param {Object} request.params - The map of provided parameters\n * @param {Object} response The response descriptor\n * @param {String} response.status The status of the response, can be either 'success' or 'error'\n * @param {Object} response.data The full response data\n * @returns {Promise}\n */\n function applyMiddlewares(request, response) {\n // wrap each middleware to provide parameters\n var list = _.map(getMiddlewares(request.command), function (middleware) {\n return function (next) {\n middleware(request, response, next);\n };\n });\n\n // apply each middleware in series, then resolve or reject the promise\n return new Promise(function (resolve, reject) {\n async.series(list, function (err) {\n // handle implicit error from response descriptor\n if (!err && 'error' === response.status) {\n err = response.data;\n }\n if (err) {\n reject(err);\n } else {\n proxy.trigger('receive', response.data, 'proxy');\n resolve(response.data);\n }\n });\n });\n }\n\n /**\n * Delegates the call to the proxy implementation and apply the middleware.\n *\n * @param {String} fnName - The name of the delegated method to call\n * @returns {Promise} - The delegated method must return a promise\n * @private\n * @throws Error\n */\n function delegate(fnName) {\n var request = {\n command: fnName,\n params: _slice.call(arguments, 1)\n };\n if (!initialized && !['install', 'init'].includes(fnName)) {\n return Promise.reject(new Error('Proxy is not properly initialized or has been destroyed!'));\n }\n return delegateProxy.apply(null, arguments).then(function (data) {\n // If the delegate call succeed the proxy is initialized.\n // Place this set here to avoid to wrap the init() into another promise.\n initialized = true;\n\n // handle successful request\n return applyMiddlewares(request, {\n status: 'success',\n data: data\n });\n }).catch(function (data) {\n // handle failed request\n return applyMiddlewares(request, {\n status: 'error',\n data: data\n });\n });\n }\n\n /**\n * Defines the test runner proxy\n * @typedef {proxy}\n */\n proxy = eventifier({\n /**\n * Add a middleware\n * @param {String} [command] The command queue in which add the middleware (default: 'all')\n * @param {Function...} callback - A middleware callback. Must accept 3 parameters: request, response, next.\n * @returns {proxy}\n */\n use: function use(command) {\n var queue = command && _.isString(command) ? command : 'all';\n var list = middlewares[queue] || [];\n middlewares[queue] = list;\n _.each(arguments, function (cb) {\n if (_.isFunction(cb)) {\n list.push(cb);\n }\n });\n return this;\n },\n /**\n * Install the proxy.\n * This step let's attach some features before the proxy reallys starts (before init).\n *\n * @param {Map} dataHolder - the test runner data holder\n * @returns {*}\n */\n install: function install(dataHolder) {\n if (dataHolder) {\n testDataHolder = dataHolder;\n }\n return delegate('install', initConfig);\n },\n /**\n * Initializes the proxy\n * @param {Object} [params] - An optional list of parameters\n * @returns {Promise} - Returns a promise. The proxy will be fully initialized on resolve.\n * Any error will be provided if rejected.\n * @fires init\n */\n init: function init(params) {\n /**\n * @event proxy#init\n * @param {Promise} promise\n * @param {Object} config\n * @param {Object} params\n */\n return delegate('init', initConfig, getParams(params));\n },\n /**\n * Uninstalls the proxy\n * @returns {Promise} - Returns a promise. The proxy will be fully uninstalled on resolve.\n * Any error will be provided if rejected.\n * @fires destroy\n */\n destroy: function destroy() {\n /**\n * @event proxy#destroy\n * @param {Promise} promise\n */\n return delegate('destroy').then(function () {\n // The proxy is now destroyed. A call to init() is mandatory to be able to use it again.\n initialized = false;\n\n // a communicator has been invoked and...\n if (communicatorPromise) {\n return new Promise(function (resolve, reject) {\n function destroyCommunicator() {\n communicator.destroy().then(resolve).catch(reject);\n }\n communicatorPromise\n // ... has been loaded successfully, then destroy it\n .then(function () {\n destroyCommunicator();\n })\n // ...has failed to be loaded, maybe no need to destroy it\n .catch(function () {\n if (communicator) {\n destroyCommunicator();\n } else {\n resolve();\n }\n });\n });\n }\n });\n },\n /**\n * Get the map that holds the test data\n * @returns {Map|Object} the dataHolder\n */\n getDataHolder: function getDataHolder() {\n return testDataHolder;\n },\n /**\n * Set the proxy as online\n * @returns {proxy} chains\n * @fires {proxy#reconnect}\n */\n setOnline: function setOnline() {\n if (this.isOffline()) {\n onlineStatus = true;\n this.trigger('reconnect');\n }\n return this;\n },\n /**\n * Set the proxy as offline\n * @param {String} [source] - source of the connectivity change\n * @returns {proxy} chains\n * @fires {proxy#disconnect}\n */\n setOffline: function setOffline(source) {\n if (this.isOnline()) {\n onlineStatus = false;\n this.trigger('disconnect', source);\n }\n return this;\n },\n /**\n * Are we online ?\n * @returns {Boolean}\n */\n isOnline: function isOnline() {\n return onlineStatus;\n },\n /**\n * Are we offline\n * @returns {Boolean}\n */\n isOffline: function isOffline() {\n return !onlineStatus;\n },\n /**\n * For the proxy a connection error is an error object with\n * source 'network', a 0 code and a false sent attribute.\n *\n * @param {Error|Object} err - the error to verify\n * @returns {Boolean} true if a connection error.\n */\n isConnectivityError: function isConnectivityError(err) {\n return _.isObject(err) && err.source === 'network' && err.code === 0 && err.sent === false;\n },\n /**\n * Gets the security token handler\n * @returns {tokenHandler}\n */\n getTokenHandler: function getTokenHandler() {\n return tokenHandler;\n },\n /**\n * Checks if a communication channel has been requested.\n * @returns {Boolean}\n */\n hasCommunicator: function hasCommunicator() {\n return !!communicatorPromise;\n },\n /**\n * Gets access to the communication channel, load it if not present\n * @returns {Promise} Returns a promise that will resolve the communication channel\n */\n getCommunicator: function getCommunicator() {\n var self = this;\n if (!initialized) {\n return Promise.reject(new Error('Proxy is not properly initialized or has been destroyed!'));\n }\n if (!communicatorPromise) {\n communicatorPromise = new Promise(function (resolve, reject) {\n if (_.isFunction(proxyAdapter.loadCommunicator)) {\n communicator = proxyAdapter.loadCommunicator.call(self);\n if (communicator) {\n communicator.before('error', function (e, err) {\n if (self.isConnectivityError(err)) {\n self.setOffline('communicator');\n }\n }).on('error', function (err) {\n self.trigger('error', err);\n }).on('receive', function (response) {\n self.setOnline();\n self.trigger('receive', response, 'communicator');\n }).init().then(function () {\n return communicator.open().then(function () {\n resolve(communicator);\n }).catch(reject);\n }).catch(reject);\n } else {\n reject(new Error('No communicator has been set up!'));\n }\n } else {\n reject(new Error('The proxy provider does not have a loadCommunicator method'));\n }\n });\n }\n return communicatorPromise;\n },\n /**\n * Registers a listener on a particular channel\n * @param {String} name - The name of the channel to listen\n * @param {Function} handler - The listener callback\n * @returns {proxy}\n * @throws TypeError if the name is missing or the handler is not a callback\n */\n channel: function channel(name, handler) {\n if (!_.isString(name) || name.length <= 0) {\n throw new TypeError('A channel must have a name');\n }\n if (!_.isFunction(handler)) {\n throw new TypeError('A handler must be attached to a channel');\n }\n this.getCommunicator().then(function (communicatorInstance) {\n communicatorInstance.channel(name, handler);\n })\n // just an empty catch to avoid any error to be displayed in the console when the communicator is not enabled\n .catch(_.noop);\n this.on(`channel-${name}`, handler);\n return this;\n },\n /**\n * Sends an messages through the communication implementation.\n * @param {String} channel - The name of the communication channel to use\n * @param {Object} message - The message to send\n * @returns {Promise} The delegated provider's method must return a promise\n */\n send: function send(channel, message) {\n return this.getCommunicator().then(function (communicatorInstance) {\n return communicatorInstance.send(channel, message);\n });\n },\n /**\n * Add extra parameters that will be added to the init or the next callTestAction or callItemAction\n * This enables plugins to place parameters for next calls\n * @param {Object} params - the extra parameters\n * @returns {proxy}\n */\n addCallActionParams: function addCallActionParams(params) {\n if (_.isPlainObject(params)) {\n _.merge(extraCallParams, params);\n }\n return this;\n },\n /**\n * Gets the test definition data\n * @deprecated\n *\n * @returns {Promise} - Returns a promise. The test definition data will be provided on resolve.\n * Any error will be provided if rejected.\n * @fires getTestData\n */\n getTestData: function getTestData() {\n /**\n * @event proxy#getTestData\n * @param {Promise} promise\n */\n return delegate('getTestData');\n },\n /**\n * Gets the test context\n * @returns {Promise} - Returns a promise. The context object will be provided on resolve.\n * Any error will be provided if rejected.\n */\n getTestContext: function getTestContext() {\n /**\n * @event proxy#getTestContext\n * @param {Promise} promise\n */\n return delegate('getTestContext');\n },\n /**\n * Gets the test map\n * @returns {Promise} - Returns a promise. The test map object will be provided on resolve.\n * Any error will be provided if rejected.\n */\n getTestMap: function getTestMap() {\n /**\n * @event proxy#getTestMap\n * @param {Promise} promise\n */\n return delegate('getTestMap');\n },\n /**\n * Sends the test variables\n * @param {Object} variables\n * @param {Boolean} deferred whether action can be scheduled (put into queue) to be sent in a bunch of actions later (default: false).\n * @returns {Promise} - Returns a promise. The result of the request will be provided on resolve.\n * Any error will be provided if rejected.\n * @fires sendVariables\n */\n sendVariables: function sendVariables(variables, deferred) {\n /**\n * @event proxy#sendVariables\n * @param {Promise} promise\n */\n return delegate('sendVariables', variables, deferred);\n },\n /**\n * Calls an action related to the test\n * @param {String} action - The name of the action to call\n * @param {Object} [params] - Some optional parameters to join to the call\n * @param {Boolean} deferred whether action can be scheduled (put into queue) to be sent in a bunch of actions later.\n * @returns {Promise} - Returns a promise. The result of the request will be provided on resolve.\n * Any error will be provided if rejected.\n * @fires callTestAction\n */\n callTestAction: function callTestAction(action, params, deferred) {\n /**\n * @event proxy#callTestAction\n * @param {Promise} promise\n * @param {String} action\n * @param {Object} params\n */\n return delegate('callTestAction', action, getParams(params), deferred);\n },\n /**\n * Gets an item definition by its URI, also gets its current state\n * @param {String} uri - The URI of the item to get\n * @param {Object} [params] - addtional params to be appended\n * @returns {Promise} - Returns a promise. The item data will be provided on resolve.\n * Any error will be provided if rejected.\n * @fires getItem\n */\n getItem: function getItem(uri, params) {\n /**\n * @event proxy#getItem\n * @param {Promise} promise\n * @param {String} uri\n */\n return delegate('getItem', uri, params);\n },\n /**\n * Submits the state and the response of a particular item\n * @param {String} uri - The URI of the item to update\n * @param {Object} state - The state to submit\n * @param {Object} response - The response object to submit\n * @param {Object} [params] - addtional params to be appended\n * @returns {Promise} - Returns a promise. The result of the request will be provided on resolve.\n * Any error will be provided if rejected.\n * @fires submitItem\n */\n submitItem: function submitItem(uri, state, response, params) {\n /**\n * @event proxy#submitItem\n * @param {Promise} promise\n * @param {String} uri\n * @param {Object} state\n * @param {Object} response\n */\n return delegate('submitItem', uri, state, response, getParams(params));\n },\n /**\n * Calls an action related to a particular item\n * @param {String} uri - The URI of the item for which call the action\n * @param {String} action - The name of the action to call\n * @param {Object} [params] - Some optional parameters to join to the call\n * @param {Boolean} deferred whether action can be scheduled (put into queue) to be sent in a bunch of actions later.\n * @returns {Promise} - Returns a promise. The result of the request will be provided on resolve.\n * Any error will be provided if rejected.\n * @fires callItemAction\n */\n callItemAction: function callItemAction(uri, action, params, deferred) {\n /**\n * @event proxy#callItemAction\n * @param {Promise} promise\n * @param {String} uri\n * @param {String} action\n * @param {Object} params\n */\n return delegate('callItemAction', uri, action, getParams(params), deferred);\n },\n /**\n * Sends a telemetry signal\n * @param {String} uri - The URI of the item for which sends the telemetry signal\n * @param {String} signal - The name of the signal to send\n * @param {Object} [params] - Some optional parameters to join to the signal\n * @returns {Promise} - Returns a promise. The result of the request will be provided on resolve.\n * Any error will be provided if rejected.\n * @fires telemetry\n */\n telemetry: function telemetry(uri, signal, params) {\n /**\n * @event proxy#telemetry\n * @param {Promise} promise\n * @param {String} uri\n * @param {String} signal\n * @param {Object} params\n */\n return delegate('telemetry', uri, signal, params);\n }\n });\n\n //listen for connectivty changes\n connectivity.on('offline', function () {\n proxy.setOffline('device');\n }).on('online', function () {\n proxy.setOnline();\n });\n\n // catch platform messages that come outside of the communicator component, then each is dispatched to the right channel\n proxy.on('message', function (channel, message) {\n this.trigger(`channel-${channel}`, message);\n }).use(function (request, response, next) {\n if (response.data && response.data.messages) {\n // receive server messages\n _.forEach(response.data.messages, function (msg) {\n if (msg.channel) {\n proxy.trigger('message', msg.channel, msg.message);\n } else {\n proxy.trigger('message', 'malformed', msg);\n }\n });\n }\n next();\n })\n //detect failing request and change the online status\n .use(function (request, response, next) {\n if (proxy.isConnectivityError(response.data)) {\n proxy.setOffline('request');\n } else if (response.data && response.data.sent === true) {\n proxy.setOnline();\n }\n next();\n });\n delegateProxy = delegator(proxy, proxyAdapter, {\n name: 'proxy',\n wrapper: function pluginWrapper(response) {\n return Promise.resolve(response);\n }\n });\n return proxy;\n }\n var proxy = providerRegistry(proxyFactory);\n\n return proxy;\n\n});\n\n","define('taoTests/runner/providerLoader',['core/logger', 'core/providerLoader', 'core/pluginLoader', 'core/communicator', 'taoTests/runner/runner', 'taoTests/runner/proxy', 'taoItems/runner/api/itemRunner'], function (loggerFactory, providerLoader, pluginLoader, communicator, runner, proxy, itemRunner) { 'use strict';\n\n loggerFactory = loggerFactory && Object.prototype.hasOwnProperty.call(loggerFactory, 'default') ? loggerFactory['default'] : loggerFactory;\n providerLoader = providerLoader && Object.prototype.hasOwnProperty.call(providerLoader, 'default') ? providerLoader['default'] : providerLoader;\n pluginLoader = pluginLoader && Object.prototype.hasOwnProperty.call(pluginLoader, 'default') ? pluginLoader['default'] : pluginLoader;\n communicator = communicator && Object.prototype.hasOwnProperty.call(communicator, 'default') ? communicator['default'] : communicator;\n runner = runner && Object.prototype.hasOwnProperty.call(runner, 'default') ? runner['default'] : runner;\n proxy = proxy && Object.prototype.hasOwnProperty.call(proxy, 'default') ? proxy['default'] : proxy;\n itemRunner = itemRunner && Object.prototype.hasOwnProperty.call(itemRunner, 'default') ? itemRunner['default'] : itemRunner;\n\n /**\n * This program is free software; you can redistribute it and/or\n * modify it under the terms of the GNU General Public License\n * as published by the Free Software Foundation; under version 2\n * of the License (non-upgradable).\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n *\n * Copyright (c) 2019 Open Assessment Technologies SA ;\n */\n const logger = loggerFactory('taoTests/runner/loader');\n\n /**\n * @typedef {Object} provider - A provider is an object exposing a list of methods with respect to the API managed by the target.\n * @property {String} name - The name of the provider. It should be unique among all.\n * @property {Function} init - Each provider much expose at least a method `init()`\n * @property {Function} ... - Any other method the target is expecting\n */\n\n /**\n * Load the providers that match the registration\n * @param {Object} providers\n * @param {provider|provider[]} providers.runner\n * @param {provider|provider[]} [providers.proxy]\n * @param {provider|provider[]} [providers.communicator]\n * @param {provider|provider[]} [providers.plugins]\n * @param {Boolean} loadFromBundle - does the loader load the modules from the sources (dev mode) or the bundles\n * @returns {Promise} resolves with the loaded providers per provider type\n */\n function loadTestRunnerProviders() {\n let providers = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n let loadFromBundle = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;\n /**\n * Default way to load the modules and register the providers\n * @param {Object[]} providersToLoad - the list of providers\n * @param {Object} target - a provider target (an object that use the providers), it needs to expose registerProvider\n * @returns {Promise} resolves with the target\n * @throws {TypeError} if the target is not a provider target\n */\n const loadAndRegisterProvider = function () {\n let providersToLoad = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];\n let target = arguments.length > 1 ? arguments[1] : undefined;\n if (!target || typeof target.registerProvider !== 'function') {\n throw new TypeError('Trying to register providers on a target that is not a provider API');\n }\n return providerLoader().addList(providersToLoad).load(loadFromBundle).then(loadedProviders => {\n loadedProviders.forEach(provider => target.registerProvider(provider.name, provider));\n return target;\n });\n };\n\n /**\n * Available provider registration\n */\n const registration = {\n runner() {\n let runnerProviders = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];\n return loadAndRegisterProvider(runnerProviders, runner);\n },\n itemRunner() {\n let itemRunnerProviders = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];\n return providerLoader().addList(itemRunnerProviders).load(loadFromBundle).then(loadedProviders => {\n loadedProviders.forEach(provider => itemRunner.register(provider.name, provider));\n return itemRunner;\n });\n },\n communicator() {\n let communicatorProviders = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];\n return loadAndRegisterProvider(communicatorProviders, communicator);\n },\n proxy() {\n let proxyProviders = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];\n return loadAndRegisterProvider(proxyProviders, proxy);\n },\n plugins() {\n let plugins = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];\n return pluginLoader().addList(plugins).load(loadFromBundle);\n }\n };\n if (!loadFromBundle) {\n logger.warn('All modules will be loaded from sources');\n }\n return Promise.all(Object.keys(providers).map(providerType => {\n if (typeof registration[providerType] === 'function') {\n logger.debug(`Start to load and register the '${providerType}' providers`);\n const providersToLoad = Array.isArray(providers[providerType]) ? providers[providerType] : [providers[providerType]];\n return registration[providerType](providersToLoad).then(loaded => {\n logger.debug(`'${providerType}' providers are loaded and registered`);\n return {\n [providerType]: loaded\n };\n });\n } else {\n logger.warn(`Ignoring the '${providerType}' providers loading, no registration method found`);\n }\n })).then(results => results.reduce((acc, value) => Object.assign(acc, value), {})).catch(err => {\n logger.error(`Error in test runner providers and plugins loading : ${err.message}`);\n throw err;\n });\n }\n\n return loadTestRunnerProviders;\n\n});\n\n","define('taoTests/runner/proxy/sample',[],function () { 'use strict';\n\n /**\n * This program is free software; you can redistribute it and/or\n * modify it under the terms of the GNU General Public License\n * as published by the Free Software Foundation; under version 2\n * of the License (non-upgradable).\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n *\n * Copyright (c) 2016-2019 (original work) Open Assessment Technologies SA ;\n */\n /**\n * @author Jean-Sébastien Conan \n */\n\n /**\n * Sample proxy definition\n * @type {Object}\n */\n var sampleProxy = {\n /**\n * Initializes the proxy\n * @returns {Promise} - Returns a promise. The proxy will be fully initialized on resolve.\n * Any error will be provided if rejected.\n */\n init: function init() {\n // the method must return a promise\n return new Promise(function (resolve) {\n // do initialisation\n // once the proxy has been fully initialized notify the success by resolving the promise\n resolve();\n\n // you can also notify error by rejecting the promise\n // reject(error);\n });\n },\n\n /**\n * Uninstalls the proxy\n * @returns {Promise} - Returns a promise. The proxy will be fully uninstalled on resolve.\n * Any error will be provided if rejected.\n */\n destroy: function destroy() {\n // the method must return a promise\n return new Promise(function (resolve) {\n // do uninstall actions\n // once the proxy has been fully uninstalled notify the success by resolving the promise\n resolve();\n\n // you can also notify error by rejecting the promise\n // reject(error);\n });\n },\n\n /**\n * Gets the test definition data\n * @param {Object} config - The config provided to the proxy factory\n * @returns {Promise} - Returns a promise. The test definition data will be provided on resolve.\n * Any error will be provided if rejected.\n */\n getTestData: function getTestData() {\n // the method must return a promise\n return new Promise(function (resolve) {\n // get the test definition data\n\n // once the action has been processed notify the success by resolving the promise\n resolve( /* the test definition data */);\n\n // you can also notify error by rejecting the promise\n // reject(error);\n });\n },\n\n /**\n * Gets the test context\n * @returns {Promise} - Returns a promise. The context object will be provided on resolve.\n * Any error will be provided if rejected.\n */\n getTestContext: function getTestContext() {\n // the method must return a promise\n return new Promise(function (resolve) {\n // get the test context object\n\n // once the action has been processed notify the success by resolving the promise\n resolve( /* the test context object */);\n\n // you can also notify error by rejecting the promise\n // reject(error);\n });\n },\n\n /**\n * Calls an action related to the test\n * @param {String} action - The name of the action to call\n * @param {Object} [params] - Some optional parameters to join to the call\n * @returns {Promise} - Returns a promise. The result of the request will be provided on resolve.\n * Any error will be provided if rejected.\n */\n callTestAction: function callTestAction() {\n // the method must return a promise\n return new Promise(function (resolve) {\n // call the action\n\n // once the action has been processed notify the success by resolving the promise\n resolve( /* the action response */);\n\n // you can also notify error by rejecting the promise\n // reject(error);\n });\n },\n\n /**\n * Gets an item definition by its URI, also gets its current state\n * @param {String} uri - The URI of the item to get\n * @returns {Promise} - Returns a promise. The item data will be provided on resolve.\n * Any error will be provided if rejected.\n * @fires getItem\n */\n getItem: function getItem() {\n // the method must return a promise\n return new Promise(function (resolve) {\n // get the definition data and the state of the item\n // once the item data is loaded provide the data by resolving the promise\n resolve( /* the item data */);\n\n // you can also notify error by rejecting the promise\n // reject(error);\n });\n },\n\n /**\n * Submits the state and the response of a particular item\n * @param {String} uri - The URI of the item to update\n * @param {Object} state - The state to submit\n * @param {Object} response - The response object to submit\n * @returns {Promise} - Returns a promise. The result of the request will be provided on resolve.\n * Any error will be provided if rejected.\n * @fires submitItem\n */\n submitItem: function submitItem() {\n // the method must return a promise\n return new Promise(function (resolve) {\n // submit the state and the response of the item\n\n // once the data has been processed notify the success by resolving the promise\n resolve( /* the action response */);\n\n // you can also notify error by rejecting the promise\n // reject(error);\n });\n },\n\n /**\n * Calls an action related to a particular item\n * @param {String} uri - The URI of the item for which call the action\n * @param {String} action - The name of the action to call\n * @param {Object} [params] - Some optional parameters to join to the call\n * @returns {Promise} - Returns a promise. The result of the request will be provided on resolve.\n * Any error will be provided if rejected.\n */\n callItemAction: function callItemAction() {\n // the method must return a promise\n return new Promise(function (resolve) {\n // call the action\n\n // once the action has been processed notify the success by resolving the promise\n resolve( /* the action response */);\n\n // you can also notify error by rejecting the promise\n // reject(error);\n });\n },\n\n /**\n * Sends a telemetry signal\n * @param {String} uri - The URI of the item for which sends the telemetry signal\n * @param {String} signal - The name of the signal to send\n * @param {Object} [params] - Some optional parameters to join to the signal\n * @returns {Promise} - Returns a promise. The result of the request will be provided on resolve.\n * Any error will be provided if rejected.\n * @fires telemetry\n */\n telemetry: function telemetry() {\n // the method must return a promise\n return new Promise(function (resolve) {\n // send the signal\n\n // once the signal has been processed notify the success by resolving the promise\n resolve( /* the signal response */);\n\n // you can also notify error by rejecting the promise\n // reject(error);\n });\n }\n };\n\n return sampleProxy;\n\n});\n\n","define('taoTests/runner/runnerComponent',['lodash', 'ui/component', 'taoTests/runner/runner', 'taoTests/runner/providerLoader', 'handlebars'], function (_, component, runnerFactory, providerLoader, Handlebars) { 'use strict';\n\n _ = _ && Object.prototype.hasOwnProperty.call(_, 'default') ? _['default'] : _;\n component = component && Object.prototype.hasOwnProperty.call(component, 'default') ? component['default'] : component;\n runnerFactory = runnerFactory && Object.prototype.hasOwnProperty.call(runnerFactory, 'default') ? runnerFactory['default'] : runnerFactory;\n providerLoader = providerLoader && Object.prototype.hasOwnProperty.call(providerLoader, 'default') ? providerLoader['default'] : providerLoader;\n Handlebars = Handlebars && Object.prototype.hasOwnProperty.call(Handlebars, 'default') ? Handlebars['default'] : Handlebars;\n\n var Template = Handlebars.template(function (Handlebars,depth0,helpers,partials,data) {\n this.compilerInfo = [4,'>= 1.0.0'];\n helpers = this.merge(helpers, Handlebars.helpers); \n\n\n return \"
\\n\";\n });\n function runnerComponentTpl(data, options, asString) {\n var html = Template(data, options);\n return (asString || true) ? html : $(html);\n }\n\n /**\n * This program is free software; you can redistribute it and/or\n * modify it under the terms of the GNU General Public License\n * as published by the Free Software Foundation; under version 2\n * of the License (non-upgradable).\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n *\n * Copyright (c) 2017-2019 (original work) Open Assessment Technologies SA ;\n */\n\n /**\n * Validate required options from the configuration\n * @param {Object} config\n * @returns {Boolean} true if valid\n * @throws {TypeError} in case of validation failure\n */\n function validateTestRunnerConfiguration() {\n let config = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n const requiredProperties = ['providers', 'options', 'serviceCallId'];\n if (typeof config !== 'object') {\n throw new TypeError(`The runner configuration must be an object, '${typeof config}' received`);\n }\n if (requiredProperties.some(property => typeof config[property] === 'undefined')) {\n throw new TypeError(`The runner configuration must contains at least the following properties : ${requiredProperties.join(',')}`);\n }\n return true;\n }\n\n /**\n * Get the selected provider if set or infer it from the providers list\n * @param {String} type - the type of provider (runner, communicator, proxy, etc.)\n * @param {Object} config\n * @returns {String} the selected provider for the given type\n */\n function getSelectedProvider() {\n let type = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'runner';\n let config = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n if (config.provider && config.provider[type]) {\n return config.provider[type];\n }\n if (config.providers && config.providers[type]) {\n const typeProviders = config.providers[type];\n if (typeof typeProviders === 'object' && (typeProviders.id || typeProviders.name)) {\n return typeProviders.id || typeProviders.name;\n }\n if (Array.isArray(typeProviders) && typeProviders.length > 0) {\n return typeProviders[0].id || typeProviders[0].name;\n }\n }\n return false;\n }\n\n /**\n * Wraps a test runner into a component\n * @param {jQuery|HTMLElement|String} container - The container in which renders the component\n * @param {Object} config - The component configuration options\n * @param {String} config.serviceCallId - The identifier of the test session\n * @param {Object} config.providers\n * @param {Object} config.options\n * @param {Boolean} [config.loadFromBundle=false] - do we load the modules from the bundles\n * @param {Boolean} [config.replace] - When the component is appended to its container, clears the place before\n * @param {Number|String} [config.width] - The width in pixels, or 'auto' to use the container's width\n * @param {Number|String} [config.height] - The height in pixels, or 'auto' to use the container's height\n * @param {Function} [template] - An optional template for the component\n * @returns {runnerComponent}\n */\n function runnerComponentFactory() {\n let container = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;\n let config = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n let template = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : runnerComponentTpl;\n let runner = null;\n let plugins = [];\n if (!container) {\n throw new TypeError('A container element must be defined to contain the runnerComponent');\n }\n validateTestRunnerConfiguration(config);\n\n /**\n * @typedef {runner} runnerComponent\n */\n const runnerComponent = component({\n /**\n * Gets the option's value\n * @param {String} name - the option key\n * @returns {*}\n */\n getOption(name) {\n return this.config.options[name];\n },\n /**\n * Gets the test runner\n * @returns {runner}\n */\n getRunner() {\n return runner;\n }\n }).setTemplate(template).on('init', function () {\n //load the defined providers for the runner, the proxy, the communicator, the plugins, etc.\n return providerLoader(config.providers, config.loadFromBundle).then(results => {\n if (results && results.plugins) {\n plugins = results.plugins;\n }\n this.render(container);\n this.hide();\n }).catch(err => this.trigger('error', err));\n }).on('render', function () {\n const runnerConfig = Object.assign(_.omit(this.config, ['providers']), {\n renderTo: this.getElement()\n });\n runnerConfig.provider = Object.keys(this.config.providers).reduce((acc, providerType) => {\n if (!acc[providerType] && providerType !== 'plugins') {\n acc[providerType] = getSelectedProvider(providerType, this.config);\n }\n return acc;\n }, runnerConfig.provider || {});\n runner = runnerFactory(runnerConfig.provider.runner, plugins, runnerConfig).on('ready', () => {\n _.defer(() => {\n this.setState('ready').trigger('ready', runner).show();\n });\n }).on('destroy', () => runner = null).spread(this, 'error').init();\n }).on('destroy', function () {\n var destroying = runner && runner.destroy();\n runner = null;\n return destroying;\n }).after('destroy', function () {\n this.removeAllListeners();\n });\n return runnerComponent.init(config);\n }\n\n return runnerComponentFactory;\n\n});\n\n","define('taoTests/runner/runnerComponentSimple',['lodash', 'core/eventifier', 'taoTests/runner/runner', 'taoTests/runner/providerLoader'], function (_, eventifier, runnerFactory, providerLoader) { 'use strict';\n\n _ = _ && Object.prototype.hasOwnProperty.call(_, 'default') ? _['default'] : _;\n eventifier = eventifier && Object.prototype.hasOwnProperty.call(eventifier, 'default') ? eventifier['default'] : eventifier;\n runnerFactory = runnerFactory && Object.prototype.hasOwnProperty.call(runnerFactory, 'default') ? runnerFactory['default'] : runnerFactory;\n providerLoader = providerLoader && Object.prototype.hasOwnProperty.call(providerLoader, 'default') ? providerLoader['default'] : providerLoader;\n\n /**\n * This program is free software; you can redistribute it and/or\n * modify it under the terms of the GNU General Public License\n * as published by the Free Software Foundation; under version 2\n * of the License (non-upgradable).\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n *\n * Copyright (c) 2017-2023 (original work) Open Assessment Technologies SA ;\n */\n\n /**\n * Validate required options from the configuration\n * @param {Object} config\n * @returns {Boolean} true if valid\n * @throws {TypeError} in case of validation failure\n */\n function validateTestRunnerConfiguration() {\n let config = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n const requiredProperties = ['providers', 'options', 'serviceCallId'];\n if (typeof config !== 'object') {\n throw new TypeError(`The runner configuration must be an object, '${typeof config}' received`);\n }\n if (requiredProperties.some(property => typeof config[property] === 'undefined')) {\n throw new TypeError(`The runner configuration must contains at least the following properties : ${requiredProperties.join(',')}`);\n }\n return true;\n }\n\n /**\n * Get the selected provider if set or infer it from the providers list\n * @param {String} type - the type of provider (runner, communicator, proxy, etc.)\n * @param {Object} config\n * @returns {String} the selected provider for the given type\n */\n function getSelectedProvider() {\n let type = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'runner';\n let config = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n if (config.provider && config.provider[type]) {\n return config.provider[type];\n }\n if (config.providers && config.providers[type]) {\n const typeProviders = config.providers[type];\n if (typeof typeProviders === 'object' && (typeProviders.id || typeProviders.name)) {\n return typeProviders.id || typeProviders.name;\n }\n if (Array.isArray(typeProviders) && typeProviders.length > 0) {\n return typeProviders[0].id || typeProviders[0].name;\n }\n }\n return false;\n }\n\n /**\n * Wraps a test runner into a component\n * @param {jQuery|HTMLElement|String} container - The container in which renders the component\n * @param {Object} config - The component configuration options\n * @param {String} config.serviceCallId - The identifier of the test session\n * @param {Object} config.providers\n * @param {Object} config.options\n * @param {Boolean} [config.loadFromBundle=false] - do we load the modules from the bundles\n * @param {Boolean} [config.replace] - When the component is appended to its container, clears the place before\n * @param {Number|String} [config.width] - The width in pixels, or 'auto' to use the container's width\n * @param {Number|String} [config.height] - The height in pixels, or 'auto' to use the container's height\n * @returns {runnerComponent}\n */\n function runnerComponentFactory() {\n let container = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;\n let config = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n let runner = null;\n let plugins = [];\n if (!container) {\n throw new TypeError('A container element must be defined to contain the runnerComponent');\n }\n validateTestRunnerConfiguration(config);\n const runnerComponentApi = {\n /**\n * Initializes the component\n * @param {Object} configuration\n * @returns {runner}\n * @fires runner#init\n */\n init: function init(configuration) {\n this.config = _(configuration || {}).omit(function (value) {\n return value === null || typeof value === 'undefined';\n }).value();\n this.trigger('init');\n return this;\n },\n /**\n * Uninstalls the component\n * @returns {runner}\n * @fires component#destroy\n */\n destroy: function destroy() {\n this.trigger('destroy');\n return this;\n },\n /**\n * Renders the component\n * @returns {runner}\n * @fires runner#render\n */\n render: function render() {\n this.trigger('render');\n return this;\n },\n /**\n * Shows the component\n * @returns {runner}\n * @fires runner#show\n */\n show: function show() {\n this.trigger('show', this);\n return this;\n },\n /**\n * Hides the component\n * @returns {runner}\n * @fires runner#hide\n */\n hide: function hide() {\n this.trigger('hide', this);\n return this;\n },\n /**\n * Get the component's configuration\n * @returns {Object}\n */\n getConfig: function getConfig() {\n return this.config || {};\n },\n /**\n * Gets the test runner\n * @returns {runner}\n */\n getRunner() {\n return runner;\n }\n };\n const runnerComponent = eventifier(runnerComponentApi);\n runnerComponent.on('init', function () {\n //load the defined providers for the runner, the proxy, the communicator, the plugins, etc.\n return providerLoader(config.providers, config.loadFromBundle).then(results => {\n if (results && results.plugins) {\n plugins = results.plugins;\n }\n this.render(container);\n this.hide();\n }).catch(err => this.trigger('error', err));\n }).on('render', function () {\n this.component = document.createElement('div');\n this.component.classList.add('runner-component');\n container.append(this.component);\n const runnerConfig = Object.assign(_.omit(this.config, ['providers']), {\n renderTo: this.component\n });\n runnerConfig.provider = Object.keys(this.config.providers).reduce((acc, providerType) => {\n if (!acc[providerType] && providerType !== 'plugins') {\n acc[providerType] = getSelectedProvider(providerType, this.config);\n }\n return acc;\n }, runnerConfig.provider || {});\n runner = runnerFactory(runnerConfig.provider.runner, plugins, runnerConfig).on('ready', () => {\n _.defer(() => {\n this.trigger('ready', runner).show();\n });\n }).on('destroy', () => runner = null).spread(this, 'error').init();\n }).on('hide', function () {\n if (this.component) {\n this.component.classList.add('hidden');\n }\n }).on('show', function () {\n if (this.component) {\n this.component.classList.remove('hidden');\n }\n }).on('destroy', function () {\n var destroying = runner && runner.destroy();\n runner = null;\n if (this.component) {\n this.component.remove();\n }\n return destroying;\n }).after('destroy', function () {\n this.removeAllListeners();\n });\n return runnerComponent.init(config);\n }\n\n return runnerComponentFactory;\n\n});\n\n","define('taoTests/runner/testStore',['lodash', 'core/store', 'core/logger'], function (_, store, loggerFactory) { 'use strict';\n\n _ = _ && Object.prototype.hasOwnProperty.call(_, 'default') ? _['default'] : _;\n store = store && Object.prototype.hasOwnProperty.call(store, 'default') ? store['default'] : store;\n loggerFactory = loggerFactory && Object.prototype.hasOwnProperty.call(loggerFactory, 'default') ? loggerFactory['default'] : loggerFactory;\n\n /*\n * This program is free software; you can redistribute it and/or\n * modify it under the terms of the GNU General Public License\n * as published by the Free Software Foundation; under version 2\n * of the License (non-upgradable).\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n *\n * Copyright (c) 2017-2019 (original work) Open Assessment Technologies SA\n *\n */\n\n /**\n * The test store logger\n * @type {core/logger}\n */\n var logger = loggerFactory('taoQtiTest/runner/provider/testStore');\n\n /**\n * Database name prefix (suffixed by the test identifier)\n * to check if we use the fragmented mode\n * or the unified mode.\n * @type {String[]}\n */\n var legacyPrefixes = ['actions-', 'duration-', 'test-probe', 'timer-'];\n\n /**\n * List the available modes\n */\n var modes = {\n unified: 'unified',\n //one db per test, new mode\n fragmented: 'fragmented' //mutliple dbs per test, legacy mode\n };\n\n /**\n * Check and select the store mode.\n * If any of the \"legacyPrefixes\" store is found, we used the fragmented mode\n * otherwise we'll use the unified mode.\n * @param {String} testId\n * @param {Object} [preselectedBackend] - the storage backend\n * @returns {Promise} resolves with the mode of the current test\n */\n var selectStoreMode = function selectStoreMode(testId, preselectedBackend) {\n return store.getAll(function validate(storeName) {\n return _.some(legacyPrefixes, function (prefix) {\n return !_.isEmpty(storeName) && prefix + testId === storeName;\n });\n }, preselectedBackend).then(function (foundStores) {\n if (_.isArray(foundStores) && foundStores.length > 0) {\n return modes.fragmented;\n }\n return modes.unified;\n });\n };\n\n /**\n * Get the store for the given test\n *\n * @param {String} testId - unique test instance id\n * @returns {testStore} a 'wrapped' store instance\n * @param {Object} [preselectedBackend] - the storage backend (automatically selected by default)\n * @throws {TypeError} without a testId\n */\n function testStoreLoader(testId, preselectedBackend) {\n var volatiles = [];\n var changeTracking = {};\n var testMode;\n\n /**\n * Is the test using a unified store mode ?\n * @returns {Promise} true if unified\n */\n var isStoreModeUnified = function isStoreModeUnified() {\n if (_.isUndefined(testMode)) {\n return selectStoreMode(testId, preselectedBackend).then(function (result) {\n if (result && typeof modes[result] !== 'undefined') {\n testMode = result;\n } else {\n //use the unified mode by default\n testMode = modes.unified;\n }\n logger.debug(`Test store mode ${result} for ${testId}`);\n return result === modes.unified;\n });\n }\n return Promise.resolve(testMode === modes.unified);\n };\n if (_.isEmpty(testId)) {\n throw new TypeError('The store must be identified with a unique test identifier');\n }\n\n /**\n * Wraps a store and add the support of \"volatile\" storages\n * @typedef {Object} testStore\n */\n return {\n /**\n * Get a wrapped store instance, that let's you use multiple stores inside one store...\n * (or in multiple stores if the test is in legacy mode)\n * @param {String} storeName - the name of the sub store\n * @returns {Promise}\n */\n getStore: function getStore(storeName) {\n //call when the current storge has been changed\n //only if the store is set to track changes\n var trackChange = function trackChange() {\n if (_.isBoolean(changeTracking[storeName])) {\n changeTracking[storeName] = true;\n }\n };\n if (_.isEmpty(storeName)) {\n throw new TypeError('A store name must be provided to get the store');\n }\n return isStoreModeUnified().then(function (isUnified) {\n var loadStore;\n if (isUnified) {\n loadStore = store(testId, preselectedBackend);\n } else {\n loadStore = store(`${storeName}-${testId}`, preselectedBackend);\n }\n return loadStore.then(function (loadedStore) {\n var keyPattern = new RegExp(`^${storeName}__`);\n var storeKey = function storeKey(key) {\n return isUnified ? `${storeName}__${key}` : key;\n };\n\n /**\n * The wrapped storage\n * @type {Object}\n */\n return {\n /**\n * Get an item with the given key\n * @param {String} key\n * @returns {Promise<*>} with the result in resolve, undefined if nothing\n */\n getItem: function getItem(key) {\n return loadedStore.getItem(storeKey(key));\n },\n /**\n * Get all store items\n * @returns {Promise} with a collection of items\n */\n getItems: function getItems() {\n if (isUnified) {\n return loadedStore.getItems().then(function (entries) {\n return _.transform(entries, function (acc, entry, key) {\n if (keyPattern.test(key)) {\n acc[key.replace(keyPattern, '')] = entry;\n }\n return acc;\n }, {});\n });\n } else {\n return loadedStore.getItems();\n }\n },\n /**\n * Set an item with the given key\n * @param {String} key - the item key\n * @param {*} value - the item value\n * @returns {Promise} with true in resolve if added/updated\n */\n setItem: function setItem(key, value) {\n trackChange();\n return loadedStore.setItem(storeKey(key), value);\n },\n /**\n * Remove an item with the given key\n * @param {String} key - the item key\n * @returns {Promise} with true in resolve if removed\n */\n removeItem: function removeItem(key) {\n trackChange();\n return loadedStore.removeItem(storeKey(key));\n },\n /**\n * Clear the current store\n * @returns {Promise} with true in resolve once cleared\n */\n clear: function clear() {\n trackChange();\n if (isUnified) {\n return loadedStore.getItems().then(function (entries) {\n _.forEach(entries, function (entry, key) {\n if (keyPattern.test(key)) {\n loadedStore.removeItem(key);\n }\n });\n });\n } else {\n return loadedStore.clear();\n }\n }\n };\n });\n });\n },\n /**\n * Define the given store as \"volatile\".\n * It means the store data can be revoked\n * if the user change browser for example\n * @param {String} storeName - the name of the store to set as volatile\n * @returns {testStore} chains\n */\n setVolatile: function setVolatile(storeName) {\n if (!volatiles.includes(storeName)) {\n volatiles.push(storeName);\n }\n return this;\n },\n /**\n * Check the given storeId. If different from the current stored identifier\n * we initiate the invalidation of the volatile data.\n * @param {String} storeId - the id to check\n * @returns {Promise} true if cleared\n */\n clearVolatileIfStoreChange: function clearVolatileIfStoreChange(storeId) {\n var self = this;\n var shouldClear = false;\n return store.getIdentifier(preselectedBackend).then(function (savedStoreId) {\n if (!_.isEmpty(storeId) && !_.isEmpty(savedStoreId) && savedStoreId !== storeId) {\n logger.info(`Storage change detected (${savedStoreId} != ${storeId}) => volatiles data wipe out !`);\n shouldClear = true;\n }\n return shouldClear;\n }).then(function (clear) {\n if (clear) {\n return self.clearVolatileStores();\n }\n return false;\n });\n },\n /**\n * Clear the storages marked as volatile\n * @returns {Promise} true if cleared\n */\n clearVolatileStores: function clearVolatileStores() {\n var self = this;\n var clearing = volatiles.map(function (storeName) {\n return self.getStore(storeName).then(function (storeInstance) {\n return storeInstance.clear();\n });\n });\n return Promise.all(clearing).then(function (results) {\n return results && results.length === volatiles.length;\n });\n },\n /**\n * Observe changes on the given store\n *\n * @param {String} storeName - the name of the store to observe\n * @returns {testStore} chains\n */\n startChangeTracking: function startChangeTracking(storeName) {\n changeTracking[storeName] = false;\n return this;\n },\n /**\n * Has the store some changes\n *\n * @param {String} storeName - the name of the store to set as volatile\n * @returns {Boolean} true if the given store has some changes\n */\n hasChanges: function hasChanges(storeName) {\n return changeTracking[storeName] === true;\n },\n /**\n * Reset the change listening\n *\n * @param {String} storeName - the name of the store\n * @returns {testStore} chains\n */\n resetChanges: function resetChanges(storeName) {\n if (_.isBoolean(changeTracking[storeName])) {\n changeTracking[storeName] = false;\n }\n return this;\n },\n /**\n * Remove the whole store\n * @returns {Promise} true if done\n */\n remove: function remove() {\n var legacyStoreExp = new RegExp(`-${testId}$`);\n return isStoreModeUnified().then(function (isUnified) {\n if (isUnified) {\n return store(testId, preselectedBackend).then(function (storeInstance) {\n return storeInstance.removeStore();\n });\n }\n return store.removeAll(function (storeName) {\n return legacyStoreExp.test(storeName);\n }, preselectedBackend);\n });\n },\n /**\n * Wraps the identifier retrieval\n * @returns {Promise} the current store id\n */\n getStorageIdentifier: function getStorageIdentifier() {\n return store.getIdentifier(preselectedBackend);\n }\n };\n }\n\n return testStoreLoader;\n\n});\n\n","\ndefine(\"taoTests/loader/taoTestsRunner.bundle\", function(){});\n","define(\"taoTests/loader/taoTestsRunner.min\", [\"taoItems/loader/taoItems.min\"], function(){});\n"],"mappings":"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"} \ No newline at end of file