Relie le score/statut des quêtes aux indicateurs SCORM
Les quêtes/quiz mettaient à jour l'état local (statut, score) sans jamais toucher gameData.scoring, que scorm-api.js interroge déjà pour reporter Completion/Success/Score au LMS. Ajoute forgeSyncQuizScoreToScorm, forgeSyncQuestStartedToScorm et forgeSyncAllQuestsCompletionToScorm, appelées lors d'un bon score, de l'acceptation d'une quête et de la complétion de toutes les quêtes. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
55c6bb330b
commit
413685e871
@@ -12,6 +12,7 @@ const {
|
||||
forgeQuestById, forgeShowDialogueBox, forgeDialogueBoxAdvance,
|
||||
forgeDialogueBoxAcceptQuest, forgeDialogueBoxDeclineQuest,
|
||||
forgeQuizBoxAnswer, forgeUpdateAllScoreWidgets,
|
||||
forgeAddQuizScore, forgeSyncAllQuestsCompletionToScorm,
|
||||
} = require('../dialogue-box-controller.js');
|
||||
|
||||
function fakeWidget(objectId) {
|
||||
@@ -321,3 +322,75 @@ test('forgeUpdateAllScoreWidgets — met à jour tous les widgets "🏆 Score" a
|
||||
assert.equal(values[1].textContent, 42);
|
||||
} finally { global.document = previousDoc; }
|
||||
});
|
||||
|
||||
// ---------- Pont vers SCORM (gameData.scoring, voir static/js/play/offline/scorm-api.js) ----------
|
||||
// Bug signalé : "les indicateurs qu'on utilise pour les quêtes devraient
|
||||
// aussi servir aux indicateurs SCORM, or ce n'est pas le cas" — un jeu
|
||||
// construit uniquement avec des quêtes/quiz ne touchait jamais
|
||||
// gameData.scoring, laissant Score/Completion perpétuellement "unknown"
|
||||
// dans le LMS même après avoir fini le jeu.
|
||||
|
||||
test('forgeAddQuizScore alimente aussi gameData.scoring (score + statut "en_cours")', () => {
|
||||
global.gameData.scoring = undefined;
|
||||
window.forgeQuizScore = 0;
|
||||
const previousDoc = global.document;
|
||||
global.document = { querySelectorAll: () => [] };
|
||||
try {
|
||||
forgeAddQuizScore(5);
|
||||
assert.equal(gameData.scoring.score, 5);
|
||||
assert.equal(gameData.scoring.status, 'en_cours');
|
||||
|
||||
forgeAddQuizScore(3);
|
||||
assert.equal(gameData.scoring.score, 8); // cumulé, jamais écrasé
|
||||
assert.equal(gameData.scoring.status, 'en_cours'); // déjà "en_cours", pas rétrogradé
|
||||
} finally { global.document = previousDoc; }
|
||||
});
|
||||
|
||||
test('forgeAddQuizScore ne rétrograde jamais un statut déjà plus avancé que "non_commence"', () => {
|
||||
global.gameData.scoring = { score: 0, status: 'termine' };
|
||||
window.forgeQuizScore = 0;
|
||||
const previousDoc = global.document;
|
||||
global.document = { querySelectorAll: () => [] };
|
||||
try {
|
||||
forgeAddQuizScore(2);
|
||||
assert.equal(gameData.scoring.status, 'termine');
|
||||
} finally { global.document = previousDoc; }
|
||||
});
|
||||
|
||||
test('accepter une quête fait passer gameData.scoring.status à "en_cours" (la partie a commencé)', () => {
|
||||
const widget = fakeWidget(42);
|
||||
global.gameData.scoring = undefined;
|
||||
const previousDoc = global.document;
|
||||
global.document = { querySelector: () => widget };
|
||||
try {
|
||||
forgeDialogueBoxAcceptQuest(5, 42);
|
||||
assert.equal(gameData.scoring.status, 'en_cours');
|
||||
} finally { global.document = previousDoc; }
|
||||
});
|
||||
|
||||
test('forgeSyncAllQuestsCompletionToScorm — passe "termine" seulement quand TOUTES les quêtes sont "terminee"', () => {
|
||||
global.gameData.quests = [{ id: 1, status: 'terminee' }, { id: 2, status: 'en_cours' }];
|
||||
global.gameData.scoring = { score: 0, status: 'en_cours' };
|
||||
forgeSyncAllQuestsCompletionToScorm();
|
||||
assert.equal(gameData.scoring.status, 'en_cours'); // pas encore toutes finies
|
||||
|
||||
gameData.quests[1].status = 'terminee';
|
||||
forgeSyncAllQuestsCompletionToScorm();
|
||||
assert.equal(gameData.scoring.status, 'termine');
|
||||
});
|
||||
|
||||
test('la dernière ligne d\'un dialogue "en_cours" propage la complétion à gameData.scoring si c\'est la seule quête', () => {
|
||||
const widget = fakeWidget(42);
|
||||
global.gameData.quests = [
|
||||
{ id: 20, status: 'en_cours', dialogues: { nouvelle: [], en_cours: [{ speaker: 'PNJ', text: 'Bravo !' }], terminee: [] } },
|
||||
];
|
||||
global.gameData.scoring = { score: 0, status: 'en_cours' };
|
||||
const previousDoc = global.document;
|
||||
global.document = { querySelector: sel => (sel.indexOf('data-object-id="42"') !== -1 ? widget : (sel.indexOf('dialogueBoxWidget') !== -1 ? widget : null)) };
|
||||
try {
|
||||
forgeShowDialogueBox(20);
|
||||
forgeDialogueBoxAdvance(42); // dernière (et unique) ligne consommée -> quête "terminee"
|
||||
assert.equal(forgeQuestById(20).status, 'terminee');
|
||||
assert.equal(gameData.scoring.status, 'termine');
|
||||
} finally { global.document = previousDoc; }
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user