Skip to content

Commit

Permalink
fix: restoring ticket may create inconsistency in DB
Browse files Browse the repository at this point in the history
  • Loading branch information
btry committed Oct 10, 2023
1 parent bda43df commit 3cf3e4e
Show file tree
Hide file tree
Showing 2 changed files with 180 additions and 2 deletions.
12 changes: 10 additions & 2 deletions hook.php
Original file line number Diff line number Diff line change
Expand Up @@ -527,7 +527,8 @@ function plugin_formcreator_hook_delete_ticket(CommonDBTM $item) {
}
}

// Delete the issue
// Delete the issue associated to the ticlet
// (when a form generated one and only one ticket)
// TODO: add is_deleted column to issue ?
$issue = new PluginFormcreatorIssue();
$issue->deleteByCriteria([
Expand All @@ -539,7 +540,14 @@ function plugin_formcreator_hook_delete_ticket(CommonDBTM $item) {
function plugin_formcreator_hook_restore_ticket(CommonDBTM $item) {
$formAnswer = new PluginFormcreatorFormAnswer();
if ($formAnswer->getFromDbByTicket($item)) {
$formAnswer->createIssue();
$relations = (new Item_Ticket())->find([
'itemtype' => $formAnswer->getType(),
'items_id' => $formAnswer->getID(),
]);
if (count($relations) === 1) {
// Recreate the issue when one and only one ticket has been created by the form
$formAnswer->createIssue();
}
$minimalStatus = $formAnswer->getAggregatedStatus();
if ($minimalStatus !== null) {
$formAnswer->updateStatus($minimalStatus);
Expand Down
170 changes: 170 additions & 0 deletions tests/2-integration/PluginFormcreatorFormAnswer.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,10 @@
namespace tests\units;
use GlpiPlugin\Formcreator\Tests\CommonTestCase;
use PluginFormcreatorForm_Validator;
use PluginFormcreatorIssue;
use Search;
use TicketValidation;
use Ticket;

/**
* The methods conflict when running in parallel
Expand Down Expand Up @@ -304,4 +306,172 @@ public function testGetMyLastAnswersAsValidator() {
$this->boolean(in_array($id, $formAnswers))->isTrue();
}
}

/**
* Undocumented function
*
* @return void
*/
public function testDeleteTicket() {
$form = $this->getForm();

$targetTicket1 = $this->getTargetTicket([
$form::getForeignKeyField() => $form->getID(),
]);
$formAnswer = $this->newTestedInstance();
$formAnswer->add([
'plugin_formcreator_forms_id' => $form->getID(),
]);
$this->boolean($formAnswer->isNewItem())->isFalse();
$this->array($formAnswer->targetList)->hasSize(1);
/** @var Ticket */
$ticket = $formAnswer->targetList[0];
$issue = new PluginFormcreatorIssue();
$issue->getFromDbByCrit([
'itemtype' => $ticket::getType(),
'items_id' => $ticket->getID(),
]);
$this->boolean($issue->isNewItem())->isFalse();

$ticket->delete([
'id' => $ticket->getID(),
]);

// Test the issue has been deleted
$issue = new PluginFormcreatorIssue();
$issue->getFromDbByCrit([
'itemtype' => $ticket::getType(),
'items_id' => $ticket->getID(),
]);
$this->boolean($issue->isNewItem())->isTrue();

// Add a 2nd ttarget ticket to the form
$targetTicket2 = $this->getTargetTicket([
$form::getForeignKeyField() => $form->getID(),
]);

$formAnswer = $this->newTestedInstance();
$formAnswer->add([
'plugin_formcreator_forms_id' => $form->getID(),
]);
$this->boolean($formAnswer->isNewItem())->isFalse();
$this->array($formAnswer->targetList)->hasSize(2);
$ticket = $formAnswer->targetList[0];
$issue = new PluginFormcreatorIssue();
$issue->getFromDbByCrit([
'itemtype' => $formAnswer::getType(),
'items_id' => $formAnswer->getID(),
]);
$this->boolean($issue->isNewItem())->isFalse();

$ticket->delete([
'id' => $ticket->getID(),
]);

// Test the issue still exists
$issue = new PluginFormcreatorIssue();
$issue->getFromDbByCrit([
'itemtype' => $formAnswer::getType(),
'items_id' => $formAnswer->getID(),
]);
$this->boolean($issue->isNewItem())->isFalse();
}

/**
* Undocumented function
*
* @return void
*/
public function testRestoreTicket() {
$form = $this->getForm();

$targetTicket = $this->getTargetTicket([
$form::getForeignKeyField() => $form->getID(),
]);
$formAnswer = $this->newTestedInstance();
$formAnswer->add([
'plugin_formcreator_forms_id' => $form->getID(),
]);
$this->boolean($formAnswer->isNewItem())->isFalse();
$this->array($formAnswer->targetList)->hasSize(1);
/** @var Ticket */
$ticket = $formAnswer->targetList[0];
$issue = new PluginFormcreatorIssue();
$issue->getFromDbByCrit([
'itemtype' => $ticket::getType(),
'items_id' => $ticket->getID(),
]);
$this->boolean($issue->isNewItem())->isFalse();

$ticket->delete([
'id' => $ticket->getID(),
]);

// Test the issue has been deleted
$issue = new PluginFormcreatorIssue();
$issue->getFromDbByCrit([
'itemtype' => $ticket::getType(),
'items_id' => $ticket->getID(),
]);
$this->boolean($issue->isNewItem())->isTrue();

// Restore the ticket (triggers plugin's hook)
$ticket->restore([
'id' => $ticket->getID(),
]);

// Test the issue has been recreated
$issue = new PluginFormcreatorIssue();
$issue->getFromDbByCrit([
'itemtype' => $ticket::getType(),
'items_id' => $ticket->getID(),
]);
$this->boolean($issue->isNewItem())->isFalse();

// Add a 2nd ttarget ticket to the form
$targetTicket2 = $this->getTargetTicket([
$form::getForeignKeyField() => $form->getID(),
]);

$formAnswer = $this->newTestedInstance();
$formAnswer->add([
'plugin_formcreator_forms_id' => $form->getID(),
]);
$this->boolean($formAnswer->isNewItem())->isFalse();
$this->array($formAnswer->targetList)->hasSize(2);
$ticket = $formAnswer->targetList[0];
$issue = new PluginFormcreatorIssue();
$issue->getFromDbByCrit([
'itemtype' => $formAnswer::getType(),
'items_id' => $formAnswer->getID(),
]);
$this->boolean($issue->isNewItem())->isFalse();

$ticket->delete([
'id' => $ticket->getID(),
]);

// Test the issue still exists
$issue = new PluginFormcreatorIssue();
$issue->getFromDbByCrit([
'itemtype' => $formAnswer::getType(),
'items_id' => $formAnswer->getID(),
]);
$this->boolean($issue->isNewItem())->isFalse();

// Restore the ticket (triggers plugin's hook)
$ticket->restore([
'id' => $ticket->getID(),
]);

// Test there is still only 1 issue
$issue = new PluginFormcreatorIssue();
$issue->getFromDbByCrit([
'itemtype' => $formAnswer::getType(),
'items_id' => $formAnswer->getID(),
]);
// If no issue or several issues matches the previous request,
// then the issue is not populated from DB
$this->boolean($issue->isNewItem())->isFalse();
}
}

0 comments on commit 3cf3e4e

Please sign in to comment.