*/ namespace oat\taoQtiTest\test\unit; use oat\generis\test\TestCase; use oat\tao\model\plugins\PluginModule; use oat\taoQtiTest\models\TestCategoryPreset; use oat\taoQtiTest\models\TestCategoryPresetProvider; use oat\taoTests\models\runner\plugins\TestPluginService; use Prophecy\Argument; use RuntimeException; class TestCategoryPresetProviderTest extends TestCase { /** * @param bool $keepGroupKeys * * @testWith [false] * [true] */ public function testSort(bool $keepGroupKeys): void { $allPresets = [ 'group3' => [ 'groupId' => 'group3', 'groupLabel' => __('group1'), 'groupOrder' => 3, 'presets' => [ TestCategoryPreset::fromArray([ 'id' => 'preset45', 'label' => __('preset45'), 'qtiCategory' => 'x-tao-option-preset45', 'order' => 45 ]), TestCategoryPreset::fromArray([ 'id' => 'preset137', 'label' => __('preset137'), 'qtiCategory' => 'x-tao-option-preset137', 'order' => 137 ]), TestCategoryPreset::fromArray([ 'id' => 'preset8', 'label' => __('preset8'), 'qtiCategory' => 'x-tao-option-preset8', 'order' => 8 ]), TestCategoryPreset::fromArray([ 'id' => 'preset1', 'label' => __('preset1'), 'qtiCategory' => 'x-tao-option-preset1', 'order' => 1 ]), TestCategoryPreset::fromArray([ 'id' => 'preset23', 'label' => __('preset23'), 'qtiCategory' => 'x-tao-option-preset23', 'order' => 23 ]) ] ], 'group1' => [ 'groupId' => 'group1', 'groupLabel' => __('group1'), 'groupOrder' => 1, 'presets' => [ TestCategoryPreset::fromArray([ 'id' => 'presetX', 'label' => __('presetX'), 'qtiCategory' => 'x-tao-option-presetx', 'order' => 1 ]) ] ], 'group5' => [ 'groupId' => 'group5', 'groupLabel' => __('group5'), 'groupOrder' => 5, 'presets' => [ TestCategoryPreset::fromArray([ 'id' => 'presetX', 'label' => __('presetX'), 'qtiCategory' => 'x-tao-option-presetx', 'order' => 1 ]) ] ], 'group2' => [ 'groupId' => 'group2', 'groupLabel' => __('group2'), 'groupOrder' => 2, 'presets' => [ TestCategoryPreset::fromArray([ 'id' => 'presetX', 'label' => __('presetX'), 'qtiCategory' => 'x-tao-option-presetx', 'order' => 1 ]) ] ] ]; $pluginService = $this->prophesize(TestPluginService::class); $presetProvider = new TestCategoryPresetProvider([], $allPresets); $presetProvider->setServiceLocator($this->getServiceLocatorMock([ TestPluginService::SERVICE_ID => $pluginService->reveal() ])); $sortedPresetGroups = $presetProvider->getPresets($keepGroupKeys); $this->assertCount(4, $sortedPresetGroups, 'sortedPresetGroups have the right number of preset groups'); $previousOrder = 0; foreach ($sortedPresetGroups as $group) { $this->assertTrue($group['groupOrder'] > $previousOrder, 'current group is sorted correctly'); $previousOrder = $group['groupOrder']; } $expectedPresetGroupKeys = $keepGroupKeys ? array_keys($allPresets) : range(0, count($allPresets) - 1); $this->assertEmpty(array_diff_key($sortedPresetGroups, array_flip($expectedPresetGroupKeys))); foreach ($sortedPresetGroups as $sortedPresets) { $previousOrder = 0; foreach ($sortedPresets['presets'] as $preset) { $this->assertTrue( $preset->getOrder() > $previousOrder, "preset {$preset->getId()} has a sort order > as previous order {$previousOrder}" ); $previousOrder = $preset->getOrder(); } } } public function testFilterByInactivePlugins(): void { $allPresets = [ // group with presets: will stay 'group1' => [ 'groupId' => 'group1', 'groupLabel' => __('group1'), 'groupOrder' => 1, 'presets' => [ // related plugin is active: will stay TestCategoryPreset::fromArray([ 'id' => 'preset1', 'label' => __('preset1'), 'qtiCategory' => 'x-tao-option-preset1', 'order' => 1, 'pluginId' => 'plugin1' ]), // related plugin is NOT active: will be removed TestCategoryPreset::fromArray([ 'id' => 'preset2', 'label' => __('preset2'), 'qtiCategory' => 'x-tao-option-preset2', 'order' => 2, 'pluginId' => 'plugin2' ]), // related plugin does not exist or is not registered: will be removed TestCategoryPreset::fromArray([ 'id' => 'preset3', 'label' => __('preset3'), 'qtiCategory' => 'x-tao-option-preset3', 'order' => 3, 'pluginId' => 'plugin3' ]), // no related plugin: will stay TestCategoryPreset::fromArray([ 'id' => 'preset4', 'label' => __('preset4'), 'qtiCategory' => 'x-tao-option-preset4', 'order' => 4 ]) ] ], // group with a preset related to an inactive plugin: will be removed 'group2' => [ 'groupId' => 'group2', 'groupLabel' => __('group2'), 'groupOrder' => 2, 'presets' => [ // will be removed because plugin is inactive TestCategoryPreset::fromArray([ 'id' => 'preset10', 'label' => __('preset10'), 'qtiCategory' => 'x-tao-option-preset10', 'order' => 1, 'pluginId' => 'plugin10' ]) ] ], // group without preset: will be removed 'group3' => [ 'groupId' => 'group3', 'groupLabel' => __('group3'), 'groupOrder' => 3, 'presets' => [] ] ]; $pluginService = $this->prophesize(TestPluginService::class); $pluginService->getPlugin('plugin1')->willReturn(PluginModule::fromArray([ 'id' => 'plugin1', 'module' => 'test/plugin1', 'category' => 'plugins', 'active' => true ])); $pluginService->getPlugin('plugin2')->willReturn(PluginModule::fromArray([ 'id' => 'plugin2', 'module' => 'test/plugin2', 'category' => 'plugins', 'active' => false ])); $pluginService->getPlugin('plugin3')->willReturn(null); $pluginService->getPlugin('plugin10')->willReturn(PluginModule::fromArray([ 'id' => 'plugin10', 'module' => 'test/plugin10', 'category' => 'plugins', 'active' => false ])); $presetProvider = new TestCategoryPresetProvider([], $allPresets); $presetProvider->setServiceLocator($this->getServiceLocatorMock([ TestPluginService::SERVICE_ID => $pluginService->reveal() ])); $filteredPresetGroups = $presetProvider->getPresets(); $this->assertCount(1, $filteredPresetGroups, 'filteredPresetGroups have the right number of preset groups'); $filteredPresets = $filteredPresetGroups[0]['presets']; $this->assertCount(2, $filteredPresets, '$filteredPresets have the right number of presets'); $this->assertEquals('preset1', $filteredPresets[0]->getId(), 'first remaining preset is the expected one'); $this->assertEquals('preset4', $filteredPresets[1]->getId(), 'second remaining preset is the expected one'); } /** * Provides data sets to test the "getAvailablePresets" method * @return array the list of data sets */ public function presetsConfigDataProvider(): array { $preset1 = TestCategoryPreset::fromArray([ 'id' => 'preset1', 'label' => 'preset1', 'qtiCategory' => 'x-tao-option-preset1', 'order' => 1, 'pluginId' => 'plugin1' ]); $preset2 = TestCategoryPreset::fromArray([ 'id' => 'preset2', 'label' => 'preset2', 'qtiCategory' => 'x-tao-option-preset2', 'order' => 2, 'pluginId' => 'plugin2', 'featureFlag' => 'enable-option-2' ]); $preset3 = TestCategoryPreset::fromArray([ 'id' => 'preset3', 'label' => __('preset3'), 'qtiCategory' => 'x-tao-option-preset3', 'order' => 3, 'pluginId' => 'plugin3', 'featureFlag' => 'enable-option-3' ]); $preset10 = TestCategoryPreset::fromArray([ 'id' => 'preset10', 'label' => __('preset10'), 'qtiCategory' => 'x-tao-option-preset10', 'order' => 1, 'pluginId' => 'plugin10', 'featureFlag' => 'enable-option-10' ]); $allPresets = [ 'group1' => [ 'groupId' => 'group1', 'groupLabel' => 'group1', 'groupOrder' => 1, 'presets' => [ $preset1, $preset2, $preset3 ] ], 'group2' => [ 'groupId' => 'group2', 'groupLabel' => 'group2', 'groupOrder' => 2, 'presets' => [ $preset10 ] ] ]; return [ [ //no config, all presets are available 'allPresets' => $allPresets, 'config' => [], 'result' => [[ 'groupId' => 'group1', 'groupLabel' => 'group1', 'groupOrder' => 1, 'presets' => [ $preset1, $preset2, $preset3 ] ], [ 'groupId' => 'group2', 'groupLabel' => 'group2', 'groupOrder' => 2, 'presets' => [ $preset10 ] ]], ], [ // all options are defined 'allPresets' => $allPresets, 'config' => [ 'enable-option-2' => true, 'enable-option-3' => false, 'enable-option-10' => true ], 'result' => [[ 'groupId' => 'group1', 'groupLabel' => 'group1', 'groupOrder' => 1, 'presets' => [ $preset1, $preset2 ] ], [ 'groupId' => 'group2', 'groupLabel' => 'group2', 'groupOrder' => 2, 'presets' => [ $preset10 ] ]], ], [ //missing option 2 and empty group 2 'allPresets' => $allPresets, 'config' => [ 'enable-option-3' => true, 'enable-option-10' => false ], 'result' => [[ 'groupId' => 'group1', 'groupLabel' => 'group1', 'groupOrder' => 1, 'presets' => [ $preset1, $preset2, $preset3 ] ]] ] ]; } /** * Test the method "getAvailablePresets" * * @dataProvider presetsConfigDataProvider */ public function testGetAvailablePresets(array $allPresets, array $config, array $result): void { $plugin = $this->prophesize(PluginModule::class); $plugin->isActive()->willReturn(true); $pluginService = $this->prophesize(TestPluginService::class); $pluginService->getPlugin(Argument::type('string'))->willReturn($plugin->reveal()); $presetProvider = new TestCategoryPresetProvider([], $allPresets); $presetProvider->setServiceLocator($this->getServiceLocatorMock([ TestPluginService::SERVICE_ID => $pluginService->reveal() ])); $availablePresets = $presetProvider->getAvailablePresets($config); $this->assertSame($result, $availablePresets, 'The available presets match the given configuration'); } public function testFindPresetGroup(): void { $sut = $this->createSut(['group1', 'group2']); $presetGroups = $sut->getPresets(); foreach ($presetGroups as $presetGroup) { $this->assertSame($presetGroup, $sut->findPresetGroupOrFail($presetGroup['groupId'])); } } public function testFailOnFindNonexistentPresetGroup(): void { $this->expectException(RuntimeException::class); $sut = $this->createSut(['group1']); $sut->findPresetGroupOrFail('group2'); } public function testFailOnFindEmptyPresetGroup(): void { $this->expectException(RuntimeException::class); $sut = $this->createSut(['group1'], false); $sut->findPresetGroupOrFail('group1'); } private function createSut(array $groupIds, bool $hasPresets = true): TestCategoryPresetProvider { $preset = TestCategoryPreset::fromArray( [ 'id' => 'preset', 'label' => 'preset', 'qtiCategory' => 'x-tao-option-preset', 'order' => 1, ] ); $presetGroups = []; foreach ($groupIds as $groupId) { $presetGroups[$groupId] = [ 'groupId' => $groupId, 'groupLabel' => $groupId, 'groupOrder' => 1, 'presets' => $hasPresets ? [$preset] : [], ]; } $sut = new TestCategoryPresetProvider([], $presetGroups); $pluginService = $this->prophesize(TestPluginService::class); $sut->setServiceLocator( $this->getServiceLocatorMock( [ TestPluginService::SERVICE_ID => $pluginService->reveal(), ] ) ); return $sut; } }