Skip to content

[BUG] Restriktionspfade vorheriger Nodes werden in nachfolgende Nodes übernommen #500

Description

@ralferlebach

Problem

Bei der Neuberechnung eines Lernpfads können Restriktionsinformationen einer vorherigen Node in nachfolgende Nodes hineinlaufen.

In classes/relation_update.php werden innerhalb der Node-Schleife unter anderem zurückgesetzt:

$restrictionnodepaths = [];
$singlerestrictionnode = [];

Die Variable

$restrictionnodepathsall

wird dagegen nicht am Beginn jeder Node-Iteration initialisiert.

Später wird fortlaufend ergänzt:

$restrictionnodepathsall[] = $allconditions;

und für die aktuelle Node gespeichert:

$userpath->json['user_path_relation'][$node['id']]['restrictionnode']
    = $restrictionnodepathsall ?? [];

Ursache

$restrictionnodepathsall besitzt eine Lebensdauer über die gesamte foreach-Schleife aller Nodes, obwohl der Inhalt fachlich nur zu einer einzelnen Node gehört.

Damit enthält die zweite Node nicht nur ihre eigenen Restriktionspfade, sondern potenziell auch die Pfade der ersten Node.

Lösung

Die Variable muss am Beginn jeder Node-Iteration zurückgesetzt werden:

foreach ($userpath->json['tree']['nodes'] as &$node) {
    $restrictionnodepaths = [];
    $restrictionnodepathsall = [];
    $singlerestrictionnode = [];

    // Weitere Auswertung.
}

Zusätzlich sollten alle nodebezogenen Arbeitsvariablen explizit innerhalb der Schleife initialisiert werden. Das verhindert ähnliche Scope-Leaks bei späteren Erweiterungen.

Manuelles Testverfahren

Vorbereitung

Einen Lernpfad mit mindestens zwei Nodes erstellen:

  • Node A besitzt eine Restriktion, beispielsweise ein festes Freischaltdatum.
  • Node B besitzt entweder keine Restriktion oder eine eindeutig andere Restriktion.

Einen Studierenden dem Lernpfad zuordnen.

Testschritte

  1. Eine vollständige Lernpfadneuberechnung auslösen.
  2. Den Datensatz des Studierenden auslesen:
SELECT id, json
FROM mdl_local_adele_path_user
WHERE user_id = <USERID>
  AND status = 'active';
  1. Das JSON formatieren.
  2. Folgende Bereiche vergleichen:
user_path_relation.<NODE_A_ID>.restrictionnode
user_path_relation.<NODE_B_ID>.restrictionnode
  1. Prüfen, ob bei Node B IDs oder Labels aus der Restriktion von Node A enthalten sind.
  2. Die Reihenfolge der Nodes testweise vertauschen und erneut berechnen.

Aktuelles Ist-Verhalten

Node B kann Restriktionspfade enthalten, die ausschließlich zu Node A gehören. Das Ergebnis kann von der Reihenfolge der Nodes im JSON abhängen.

Erwartetes Soll-Verhalten

Jede Node enthält ausschließlich ihre eigenen Restriktionspfade. Die Reihenfolge anderer Nodes beeinflusst das Ergebnis nicht.

Automatisierte Tests

  • Node mit Restriktion gefolgt von Node ohne Restriktion.
  • Zwei Nodes mit unterschiedlichen Restriktionen.
  • Vertauschte Node-Reihenfolge.
  • Drei Nodes zur Prüfung einer fortlaufenden Akkumulation.
  • Vergleich der gespeicherten restrictionnode-Arrays.

Akzeptanzkriterien

  • $restrictionnodepathsall wird pro Node zurückgesetzt.
  • Keine Node enthält Restriktions-IDs einer anderen Node.
  • Das Ergebnis ist unabhängig von der Node-Reihenfolge.
  • Ein PHPUnit-Regressionstest bildet mindestens zwei aufeinanderfolgende Nodes ab.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions