Skip to content

Commit

Permalink
Test: Add Missing Copy of Test Pages
Browse files Browse the repository at this point in the history
  • Loading branch information
kergomard committed Nov 13, 2024
1 parent b5b3054 commit 75d1b50
Show file tree
Hide file tree
Showing 4 changed files with 277 additions and 16 deletions.
37 changes: 36 additions & 1 deletion components/ILIAS/Test/classes/class.ilObjTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -701,16 +701,42 @@ public function getIntroduction(): string
return $this->getMainSettings()->getIntroductionSettings()->getIntroductionText();
}

private function cloneIntroduction(): ?int
{
$page_id = $this->getMainSettings()->getIntroductionSettings()->getIntroductionPageId();
if ($page_id === null) {
return null;
}
return $this->clonePage($page_id);
}

public function getFinalStatement(): string
{
$page_id = $this->getMainSettings()->getFinishingSettings()->getConcludingRemarksPageId();
if ($page_id !== null) {
return (new ilTestPageGUI('tst', $page_id))->showPage();
}

return $this->getMainSettings()->getFinishingSettings()->getConcludingRemarksText();
}

private function cloneConcludingRemarks(): ?int
{
$page_id = $this->getMainSettings()->getFinishingSettings()->getConcludingRemarksPageId();
if ($page_id === null) {
return null;
}
return $this->clonePage($page_id);
}

private function clonePage(int $source_page_id): int
{
$page_object = new ilTestPage();
$page_object->setParentId($this->getId());
$new_page_id = $page_object->createPageWithNextId();
(new ilTestPage($source_page_id))->copy($new_page_id);
return $new_page_id;
}

/**
* Gets the database id of the additional test data
*/
Expand Down Expand Up @@ -4253,6 +4279,15 @@ public function cloneObject(int $target_id, int $copy_id = 0, bool $omit_tree =
$new_obj->addToNewsOnOnline(false, $new_obj->getObjectProperties()->getPropertyIsOnline()->getIsOnline());
$this->getMainSettingsRepository()->store(
$this->getMainSettings()->withTestId($new_obj->getTestId())
->withIntroductionSettings(
$this->getMainSettings()->getIntroductionSettings()->withIntroductionPageId(
$this->cloneIntroduction()
)->withTestId($new_obj->getTestId())
)->withFinishingSettings(
$this->getMainSettings()->getFinishingSettings()->withConcludingRemarksPageId(
$this->cloneConcludingRemarks()
)->withTestId($new_obj->getTestId())
)
);
$this->getScoreSettingsRepository()->store(
$this->getScoreSettings()->withTestId($new_obj->getTestId())
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,221 @@
<?php

/**
* This file is part of ILIAS, a powerful learning management system
* published by ILIAS open source e-Learning e.V.
*
* ILIAS is licensed with the GPL-3.0,
* see https://www.gnu.org/licenses/gpl-3.0.en.html
* You should have received a copy of said license along with the
* source code, too.
*
* If this is not the case or you just want to try ILIAS, you'll find
* us at:
* https://www.ilias.de
* https://github.com/ILIAS-eLearning
*
*********************************************************************/

declare(strict_types=1);

namespace ILIAS\Test\Setup;

use ILIAS\Setup;
use ILIAS\Setup\Environment;
use ILIAS\Setup\Migration;

class CloneIntroductionAndClosingRemarksMigration implements Migration
{
private const TESTS_PER_STEP = 100;

private \ilDBInterface $db;

public function getLabel(): string
{
return 'Fix missing clones for Introduction and Concluding Remarks.';
}

public function getDefaultAmountOfStepsPerRun(): int
{
return 1;
}

public function getPreconditions(Environment $environment): array
{
return [
new \ilDatabaseInitializedObjective()
];
}

public function prepare(Environment $environment): void
{
$this->db = $environment->getResource(Setup\Environment::RESOURCE_DATABASE);
}

public function step(Environment $environment): void
{
$select_page_statement = $this->db->prepare(
'SELECT * FROM page_object WHERE parent_type = "tst" AND page_id = ?',
[\ilDBConstants::T_INTEGER]
);

$max_steps = $this->migrateIntroductions($select_page_statement);
$this->migrateConcludingRemarks($select_page_statement, $max_steps);

$this->db->free($select_page_statement);
}

public function getRemainingAmountOfSteps(): int
{
$result_intro = $this->db->query('
SELECT COUNT(test_id) as cnt
FROM tst_tests
WHERE NOT introduction_page_id IS NULL
AND introduction_page_id IN
(SELECT introduction_page_id FROM tst_tests GROUP BY introduction_page_id HAVING COUNT(introduction_page_id) > 1)
');
$row_intro = $this->db->fetchObject($result_intro);

$result_conclusion = $this->db->query('
SELECT COUNT(test_id) as cnt
FROM tst_tests
WHERE NOT concluding_remarks_page_id IS NULL
AND concluding_remarks_page_id in
(SELECT concluding_remarks_page_id FROM tst_tests GROUP BY concluding_remarks_page_id HAVING COUNT(concluding_remarks_page_id) > 1)
');
$row_conclusion = $this->db->fetchObject($result_conclusion);

return (int) ceil(($row_intro->cnt + $row_conclusion->cnt) / self::TESTS_PER_STEP);
}

private function migrateIntroductions(\ilDBStatement $select_page_statement): int
{
$result = $this->db->query(
'
SELECT test_id, obj_fi, introduction_page_id
FROM tst_tests
WHERE NOT introduction_page_id IS NULL
AND introduction_page_id IN
(SELECT introduction_page_id FROM tst_tests GROUP BY introduction_page_id HAVING COUNT(introduction_page_id) > 1)
ORDER BY introduction_page_id
LIMIT ' . self::TESTS_PER_STEP
);

$first_row = $this->db->fetchObject($result);
if ($first_row === null) {
return self::TESTS_PER_STEP;
}

$introduction_to_clone = $this->db->fetchObject(
$this->db->execute(
$select_page_statement,
[$first_row->introduction_page_id]
)
);
while (($row = $this->db->fetchObject($result)) !== null) {
if ($row->introduction_page_id !== $introduction_to_clone?->page_id) {
$introduction_to_clone = $this->db->fetchObject(
$this->db->execute(
$select_page_statement,
[$row->introduction_page_id]
)
);
continue;
}

$new_page_id = $this->createPageWithNextId($row->obj_fi, $introduction_to_clone);
$this->db->update(
'tst_tests',
[
'introduction_page_id' => [\ilDBConstants::T_INTEGER, $new_page_id]
],
[
'test_id' => [\ilDBConstants::T_INTEGER, $row->test_id]
]
);
}

return self::TESTS_PER_STEP - $result->numRows();
}

private function migrateConcludingRemarks(\ilDBStatement $select_page_statement, int $max_steps): void
{
$result = $this->db->query(
'
SELECT test_id, obj_fi, concluding_remarks_page_id
FROM tst_tests
WHERE NOT concluding_remarks_page_id IS NULL
AND concluding_remarks_page_id IN
(SELECT concluding_remarks_page_id FROM tst_tests GROUP BY concluding_remarks_page_id HAVING COUNT(concluding_remarks_page_id) > 1)
ORDER BY concluding_remarks_page_id
LIMIT ' . $max_steps
);

$first_row = $this->db->fetchObject($result);
if ($first_row === null) {
return;
}

$concluding_remarks_to_clone = $this->db->fetchObject(
$this->db->execute(
$select_page_statement,
[$first_row->concluding_remarks_page_id]
)
);
while (($row = $this->db->fetchObject($result)) !== null) {
if ($row->concluding_remarks_page_id !== $concluding_remarks_to_clone?->page_id) {
$concluding_remarks_to_clone = $this->db->fetchObject(
$this->db->execute(
$select_page_statement,
[$row->concluding_remarks_page_id]
)
);
continue;
}

$new_page_id = $this->createPageWithNextId($row->obj_fi, $concluding_remarks_to_clone);
$this->db->update(
'tst_tests',
[
'concluding_remarks_page_id' => [\ilDBConstants::T_INTEGER, $new_page_id]
],
[
'test_id' => [\ilDBConstants::T_INTEGER, $row->test_id]
]
);
}
}

private function createPageWithNextId(int $test_obj_id, \stdClass $row): int
{
$query = $this->db->query('SELECT max(page_id) as last_id FROM page_object WHERE parent_type="tst"');
$last_row = $this->db->fetchObject($query);
try {
$this->db->insert(
'page_object',
[
'page_id' => ['integer', $last_row->last_id + 1],
'parent_id' => ['integer', $test_obj_id],
'lang' => ['text', $row->lang],
'content' => ['clob', $row->content],
'parent_type' => ['text', $row->parent_type],
'create_user' => ['integer', $row->create_user],
'last_change_user' => ['integer', $row->last_change_user],
'active' => ['integer', $row->active],
'activation_start' => ['timestamp', $row->activation_start],
'activation_end' => ['timestamp', $row->activation_end],
'show_activation_info' => ['integer', $row->show_activation_info],
'inactive_elements' => ['integer', $row->inactive_elements],
'int_links' => ['integer', $row->int_links],
'created' => ['timestamp', \ilUtil::now()],
'last_change' => ['timestamp', \ilUtil::now()],
'is_empty' => ['integer', $row->is_empty]
]
);
} catch (ilDatabaseException $e) {
$this->createPageWithNextId($row);
}

return $last_row->last_id + 1;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,60 +18,63 @@

declare(strict_types=1);

use ILIAS\Setup;
namespace ILIAS\Test\Setup;

use ILIAS\Setup\Environment;
use ILIAS\Setup\Metrics\Metric;
use ILIAS\DI;
use ILIAS\Setup\Metrics\Storage;
use ILIAS\Setup\Metrics\CollectedObjective;

class ilTestDatabaseInconsistencyMetricsCollectedObjective extends Setup\Metrics\CollectedObjective
class DatabaseInconsistencyMetricsCollectedObjective extends CollectedObjective
{
/**
* @return array<\ilDatabaseInitializedObjective|\ilIniFilesLoadedObjective>
*/
protected function getTentativePreconditions(Setup\Environment $environment): array
protected function getTentativePreconditions(Environment $environment): array
{
return [
new \ilDatabaseInitializedObjective()
];
}

protected function collectFrom(Setup\Environment $environment, Setup\Metrics\Storage $storage): void
protected function collectFrom(Environment $environment, Storage $storage): void
{
$db = $environment->getResource(Setup\Environment::RESOURCE_DATABASE);
$db = $environment->getResource(Environment::RESOURCE_DATABASE);
$metrics = [
"database_available" => new Metric(
'database_available' => new Metric(
Metric::STABILITY_VOLATILE,
Metric::TYPE_BOOL,
!is_null($db),
"This metric is a canary to check for the general existence of this collection."
'This metric is a canary to check for the general existence of this collection.'
)
];

if ($db) {
$this->collectMantis37759($metrics, $db);
}

$storage->store("database_inconsistencies", new Metric(
$storage->store('database_inconsistencies', new Metric(
Metric::STABILITY_MIXED,
Metric::TYPE_COLLECTION,
$metrics,
"These metrics collect information about inconsistencies in the database of the T&A."
'These metrics collect information about inconsistencies in the database of the T&A.'
));
}

protected function collectMantis37759(array &$metrics, \ilDBInterface $db)
{
$result = $db->query("
$result = $db->query('
SELECT COUNT(*) as cnt
FROM tst_active
LEFT JOIN object_data ON tst_active.test_fi = object_data.obj_id
WHERE object_data.obj_id IS NULL
");
');

$metrics["mantis_37759"] = new Metric(
Metric::STABILITY_VOLATILE,
Metric::TYPE_GAUGE,
$db->fetchAssoc($result)["cnt"],
"Measures active tests runs where the corresponding Test object does not exist anymore."
$db->fetchAssoc($result)['cnt'],
'Measures active tests runs where the corresponding Test object does not exist anymore.'
);
}
}
4 changes: 3 additions & 1 deletion components/ILIAS/Test/src/Setup/TestSetupAgent.php
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,8 @@ public function getBuildObjective(): Objective

public function getMigrations(): array
{
return [];
return [
new CloneIntroductionAndClosingRemarksMigration()
];
}
}

0 comments on commit 75d1b50

Please sign in to comment.