451 lines
17 KiB
PHP
451 lines
17 KiB
PHP
|
<?php
|
||
|
|
||
|
/**
|
||
|
* This program is free software; you can redistribute it and/or
|
||
|
* modify it under the terms of the GNU General Public License
|
||
|
* as published by the Free Software Foundation; under version 2
|
||
|
* of the License (non-upgradable).
|
||
|
*
|
||
|
* This program is distributed in the hope that it will be useful,
|
||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
* GNU General Public License for more details.
|
||
|
*
|
||
|
* You should have received a copy of the GNU General Public License
|
||
|
* along with this program; if not, write to the Free Software
|
||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||
|
*
|
||
|
* Copyright (c) 2017 (original work) Open Assessment Technologies SA (under the project TAO-PRODUCT);
|
||
|
*
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* @author Christophe Noël <christophe@taotesting.com>
|
||
|
*/
|
||
|
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;
|
||
|
}
|
||
|
}
|