[FIX] orphaned data causing errors

Set titles now stored in progress & incorrect answer records
This commit is contained in:
2021-10-23 16:42:52 +01:00
parent 87a0f612ae
commit c80905dba9
4 changed files with 108 additions and 82 deletions

View File

@@ -172,7 +172,7 @@ exports.createProgress = functions.https.onCall((data, context) => {
return db.runTransaction(async (transaction) => { return db.runTransaction(async (transaction) => {
const setsId = db.collection("sets"); const setsId = db.collection("sets");
let allSetTitles = []; let setTitlesDict = {};
let allVocab = []; let allVocab = [];
await Promise.all(data.sets.map((setId) => { await Promise.all(data.sets.map((setId) => {
@@ -192,7 +192,7 @@ exports.createProgress = functions.https.onCall((data, context) => {
throw new functions.https.HttpsError("failed-precondition", "Set must have at least one term/definition pair"); throw new functions.https.HttpsError("failed-precondition", "Set must have at least one term/definition pair");
} }
allSetTitles.push(setDoc.data().title); setTitlesDict[setId] = setDoc.data().title;
return setVocab.docs.map((vocabDoc) => { return setVocab.docs.map((vocabDoc) => {
let newVocabData = vocabDoc; let newVocabData = vocabDoc;
@@ -209,7 +209,18 @@ exports.createProgress = functions.https.onCall((data, context) => {
const progressDocId = db const progressDocId = db
.collection("progress").doc(); .collection("progress").doc();
const setTitle = allSetTitles.sort().slice(0, -1).join(", ") + (allSetTitles.length > 1 ? " & " : "") + allSetTitles.sort().slice(-1); const allSetTitles = [...Object.values(setTitlesDict)].sort();
const setTitle = allSetTitles.slice(0, -1).join(", ") + (allSetTitles.length > 1 ? " & " : "") + allSetTitles.slice(-1);
const setIds = data.sets.sort((a, b) => {
if (a < b) {
return -1;
}
if (a > b) {
return 1;
}
return 0;
});
let dataToSet = { let dataToSet = {
questions: [], questions: [],
@@ -223,15 +234,8 @@ exports.createProgress = functions.https.onCall((data, context) => {
switch_language: switchLanguage, switch_language: switchLanguage,
duration: null, duration: null,
mode: mode, mode: mode,
setIds: data.sets.sort((a, b) => { setIds: setIds,
if (a < b) { set_titles: setIds.map((setId) => setTitlesDict[setId]),
return -1;
}
if (a > b) {
return 1;
}
return 0;
}),
typo: false, typo: false,
} }
@@ -648,6 +652,7 @@ exports.processAnswer = functions.https.onCall((data, context) => {
answer: inputAnswer.trim(), answer: inputAnswer.trim(),
switch_language: progressDoc.data().switch_language, switch_language: progressDoc.data().switch_language,
setIds: progressDoc.data().setIds, setIds: progressDoc.data().setIds,
set_titles: progressDoc.data().set_titles,
}); });
const totalPercentage = completedProgressDoc.data().total_percentage + (docData.correct.length / docData.questions.length * 100); const totalPercentage = completedProgressDoc.data().total_percentage + (docData.correct.length / docData.questions.length * 100);
@@ -661,12 +666,7 @@ exports.processAnswer = functions.https.onCall((data, context) => {
transaction.set(progressDocId, docData); transaction.set(progressDocId, docData);
return returnData; return returnData;
}).catch(async (error) => { }).catch(async (error) => {
const allSetTitles = await Promise.all(progressDoc.data().setIds.map((setId) => const allSetTitles = progressDoc.data().set_titles;
transaction.get(db.collection("sets")
.doc(setId))
.then((setDoc) => setDoc.data().title)
.catch((error) => ""))
);
const setTitle = allSetTitles.slice(0, -1).join(", ") + (allSetTitles.length > 1 ? " & " : "") + allSetTitles.sort().slice(-1); const setTitle = allSetTitles.slice(0, -1).join(", ") + (allSetTitles.length > 1 ? " & " : "") + allSetTitles.sort().slice(-1);
if (!isCorrectAnswer) transaction.set(incorrectAnswerDoc, { if (!isCorrectAnswer) transaction.set(incorrectAnswerDoc, {
uid: uid, uid: uid,
@@ -676,6 +676,7 @@ exports.processAnswer = functions.https.onCall((data, context) => {
answer: inputAnswer.trim(), answer: inputAnswer.trim(),
switch_language: progressDoc.data().switch_language, switch_language: progressDoc.data().switch_language,
setIds: progressDoc.data().setIds, setIds: progressDoc.data().setIds,
set_titles: progressDoc.data().set_titles,
}); });
const totalPercentage = docData.correct.length / docData.questions.length * 100; const totalPercentage = docData.correct.length / docData.questions.length * 100;
@@ -706,6 +707,7 @@ exports.processAnswer = functions.https.onCall((data, context) => {
answer: inputAnswer.trim(), answer: inputAnswer.trim(),
switch_language: progressDoc.data().switch_language, switch_language: progressDoc.data().switch_language,
setIds: progressDoc.data().setIds, setIds: progressDoc.data().setIds,
set_titles: progressDoc.data().set_titles,
}); });
returnData.nextPrompt = { returnData.nextPrompt = {
@@ -729,6 +731,7 @@ exports.processAnswer = functions.https.onCall((data, context) => {
answer: inputAnswer.trim(), answer: inputAnswer.trim(),
switch_language: progressDoc.data().switch_language, switch_language: progressDoc.data().switch_language,
setIds: progressDoc.data().setIds, setIds: progressDoc.data().setIds,
set_titles: progressDoc.data().set_titles,
}); });
const sound = promptDoc.data().sound; const sound = promptDoc.data().sound;

View File

@@ -56,7 +56,6 @@ export default withRouter(class GroupStats extends Component {
} }
async componentDidMount() { async componentDidMount() {
let promises = [];
let newState = { let newState = {
sets: {}, sets: {},
setsWithHistory: {}, setsWithHistory: {},
@@ -77,40 +76,39 @@ export default withRouter(class GroupStats extends Component {
}); });
if (newState.role === "owner") { if (newState.role === "owner") {
promises.push( await this.state.db
this.state.db .collection("groups")
.collection("groups") .doc(this.props.match.params.groupId)
.doc(this.props.match.params.groupId) .get()
.get() .then(async (groupDoc) => {
.then(async (groupDoc) => { document.title = `Stats | ${groupDoc.data().display_name} | Parandum`;
document.title = `Stats | ${groupDoc.data().display_name} | Parandum`; newState.groupName = groupDoc.data().display_name;
newState.groupName = groupDoc.data().display_name;
return Promise.all(groupDoc.data().sets.map((setId) => {
return Promise.all(groupDoc.data().sets.map((setId) => { return this.state.db.collection("sets")
return this.state.db.collection("sets") .doc(setId)
.doc(setId) .get()
.get() .then((doc) => {
.then((doc) => { newState.sets[setId] = {
newState.sets[setId] = { title: doc.data().title,
title: doc.data().title, };
}; });
}); }));
})); }).catch((error) => {
}).catch((error) => { console.log(`Can't access group: ${error}`);
console.log(`Can't access group: ${error}`); newState.groupName = "";
newState.groupName = ""; document.title = "Stats | Parandum";
document.title = "Stats | Parandum"; });
})
);
promises.push( const groupSetIds = Object.keys(newState.sets);
this.state.db.collection("incorrect_answers") if (groupSetIds.length > 0) await this.state.db.collection("incorrect_answers")
.where("groups", "array-contains", this.props.match.params.groupId) .where("groups", "array-contains", this.props.match.params.groupId)
.orderBy("term", "asc") .orderBy("term", "asc")
.get() .get()
.then((querySnapshot) => { .then((querySnapshot) => {
let incorrectAnswers = []; let incorrectAnswers = [];
querySnapshot.docs.map((doc, index, array) => { querySnapshot.docs.map((doc, index, array) => {
if (doc.data().setIds.some(item => groupSetIds.includes(item))) {
if (index === 0 || doc.data().term !== array[index - 1].data().term || doc.data().definition !== array[index - 1].data().definition) { if (index === 0 || doc.data().term !== array[index - 1].data().term || doc.data().definition !== array[index - 1].data().definition) {
incorrectAnswers.push({ incorrectAnswers.push({
term: doc.data().term, term: doc.data().term,
@@ -145,19 +143,18 @@ export default withRouter(class GroupStats extends Component {
doc.data().setIds.map((setId) => newState.setsWithHistory[setId] = true); doc.data().setIds.map((setId) => newState.setsWithHistory[setId] = true);
return true; return true;
}); }
newState.incorrectAnswers = incorrectAnswers.sort((a, b) => b.count + b.switchedCount - a.count - a.switchedCount); return false;
newState.filteredIncorrectAnswers = newState.incorrectAnswers; });
newState.totalIncorrect = querySnapshot.docs.length; newState.incorrectAnswers = incorrectAnswers.sort((a, b) => b.count + b.switchedCount - a.count - a.switchedCount);
}) newState.filteredIncorrectAnswers = newState.incorrectAnswers;
.catch((error) => { newState.totalIncorrect = querySnapshot.docs.length;
newState.incorrectAnswers = []; })
newState.totalIncorrect = 0; .catch((error) => {
console.log(`Couldn't get group progress: ${error}`); newState.incorrectAnswers = [];
}) newState.totalIncorrect = 0;
); console.log(`Couldn't get group progress: ${error}`);
});
await Promise.all(promises);
} }
this.setState(newState); this.setState(newState);

View File

@@ -132,14 +132,17 @@ export default class IncorrectHistory extends Component {
} }
} }
doc.data().setIds.map((setId) => subPromises.push( // doc.data().setIds.map((setId) => subPromises.push(
this.state.db.collection("sets") // this.state.db.collection("sets")
.doc(setId) // .doc(setId)
.get() // .get()
.then((doc) => // .then((doc) =>
newState.setsWithHistory[setId] = doc.data().title // newState.setsWithHistory[setId] = doc.data().title
) // )
)); // ));
doc.data().setIds.map((setId, setIndex) =>
newState.setsWithHistory[setId] = doc.data().set_titles[setIndex]
);
return true; return true;
}); });
@@ -166,7 +169,6 @@ export default class IncorrectHistory extends Component {
setIds: doc.data().setIds, setIds: doc.data().setIds,
}) })
); );
console.log(newState.progressHistory);
newState.totalTests = newState.progressHistory.length; newState.totalTests = newState.progressHistory.length;
}) })
); );
@@ -230,14 +232,6 @@ export default class IncorrectHistory extends Component {
return newVocabItem; return newVocabItem;
}); });
console.log(this.state.progressHistory
.filter((progressItem) =>
this.arraysHaveSameMembers(progressItem.setIds, [selectedSet.value]) ||
(
this.state.includeCompoundTests &&
progressItem.setIds.includes(selectedSet.value)
)
));
this.setState({ this.setState({
filteredIncorrectAnswers: filteredIncorrectAnswers, filteredIncorrectAnswers: filteredIncorrectAnswers,
selectedSet: selectedSet, selectedSet: selectedSet,

View File

@@ -147,6 +147,7 @@ describe("Parandum Cloud Functions", function () {
assert.strictEqual(snapAfter.progress, 0); assert.strictEqual(snapAfter.progress, 0);
assert.deepStrictEqual(snapAfter.setIds, [setOne]); assert.deepStrictEqual(snapAfter.setIds, [setOne]);
assert.strictEqual(snapAfter.set_title, setOne); assert.strictEqual(snapAfter.set_title, setOne);
assert.deepStrictEqual(snapAfter.set_titles, [setOne]);
assert.notStrictEqual(snapAfter.start_time, null); assert.notStrictEqual(snapAfter.start_time, null);
assert.strictEqual(snapAfter.switch_language, false); assert.strictEqual(snapAfter.switch_language, false);
assert.strictEqual(snapAfter.uid, userOne); assert.strictEqual(snapAfter.uid, userOne);
@@ -232,6 +233,7 @@ describe("Parandum Cloud Functions", function () {
assert.strictEqual(snapAfter.progress, 0); assert.strictEqual(snapAfter.progress, 0);
assert.deepStrictEqual(snapAfter.setIds, [setOne, setTwo]); assert.deepStrictEqual(snapAfter.setIds, [setOne, setTwo]);
assert.strictEqual(snapAfter.set_title, `${setOne} & ${setTwo}`); assert.strictEqual(snapAfter.set_title, `${setOne} & ${setTwo}`);
assert.deepStrictEqual(snapAfter.set_titles, [setOne, setTwo]);
assert.notStrictEqual(snapAfter.start_time, null); assert.notStrictEqual(snapAfter.start_time, null);
assert.strictEqual(snapAfter.switch_language, false); assert.strictEqual(snapAfter.switch_language, false);
assert.strictEqual(snapAfter.uid, userOne); assert.strictEqual(snapAfter.uid, userOne);
@@ -287,6 +289,7 @@ describe("Parandum Cloud Functions", function () {
assert.strictEqual(snapAfter.progress, 0); assert.strictEqual(snapAfter.progress, 0);
assert.deepStrictEqual(snapAfter.setIds, [setOne]); assert.deepStrictEqual(snapAfter.setIds, [setOne]);
assert.strictEqual(snapAfter.set_title, setOne); assert.strictEqual(snapAfter.set_title, setOne);
assert.deepStrictEqual(snapAfter.set_titles, [setOne]);
assert.notStrictEqual(snapAfter.start_time, null); assert.notStrictEqual(snapAfter.start_time, null);
assert.strictEqual(snapAfter.switch_language, false); assert.strictEqual(snapAfter.switch_language, false);
assert.strictEqual(snapAfter.uid, userOne); assert.strictEqual(snapAfter.uid, userOne);
@@ -379,6 +382,7 @@ describe("Parandum Cloud Functions", function () {
progressVocabTwo progressVocabTwo
], ],
set_title: setOne, set_title: setOne,
set_titles: [setOne],
start_time: 1627308670962, start_time: 1627308670962,
switch_language: false, switch_language: false,
uid: userOne, uid: userOne,
@@ -483,6 +487,7 @@ describe("Parandum Cloud Functions", function () {
progressVocabTwo progressVocabTwo
], ],
set_title: setOne, set_title: setOne,
set_titles: [setOne],
start_time: 1627308670962, start_time: 1627308670962,
switch_language: false, switch_language: false,
uid: userOne, uid: userOne,
@@ -502,6 +507,7 @@ describe("Parandum Cloud Functions", function () {
progressVocabOne progressVocabOne
], ],
set_title: setOne, set_title: setOne,
set_titles: [setOne],
start_time: 1627308670962, start_time: 1627308670962,
switch_language: false, switch_language: false,
uid: userOne, uid: userOne,
@@ -534,6 +540,7 @@ describe("Parandum Cloud Functions", function () {
assert.notStrictEqual(snapAfterCorrectData.duration, null); assert.notStrictEqual(snapAfterCorrectData.duration, null);
assert.strictEqual(snapAfterCorrectData.progress, 3); assert.strictEqual(snapAfterCorrectData.progress, 3);
assert.strictEqual(snapAfterCorrectData.set_title, setOne); assert.strictEqual(snapAfterCorrectData.set_title, setOne);
assert.deepStrictEqual(snapAfterCorrectData.set_titles, [setOne]);
assert.strictEqual(snapAfterCorrectData.start_time, 1627308670962); assert.strictEqual(snapAfterCorrectData.start_time, 1627308670962);
assert.strictEqual(snapAfterCorrectData.switch_language, false); assert.strictEqual(snapAfterCorrectData.switch_language, false);
assert.strictEqual(snapAfterCorrectData.uid, userOne); assert.strictEqual(snapAfterCorrectData.uid, userOne);
@@ -554,6 +561,7 @@ describe("Parandum Cloud Functions", function () {
progressVocabOne progressVocabOne
], ],
set_title: setOne, set_title: setOne,
set_titles: [setOne],
start_time: 1627308670962, start_time: 1627308670962,
switch_language: false, switch_language: false,
uid: userOne, uid: userOne,
@@ -638,6 +646,7 @@ describe("Parandum Cloud Functions", function () {
progressVocabTwo progressVocabTwo
], ],
set_title: setOne, set_title: setOne,
set_titles: [setOne],
start_time: 1627308670962, start_time: 1627308670962,
switch_language: false, switch_language: false,
uid: userOne, uid: userOne,
@@ -725,6 +734,7 @@ describe("Parandum Cloud Functions", function () {
progressVocabTwo progressVocabTwo
], ],
set_title: setOne, set_title: setOne,
set_titles: [setOne],
start_time: 1627308670962, start_time: 1627308670962,
switch_language: false, switch_language: false,
uid: userOne, uid: userOne,
@@ -750,6 +760,7 @@ describe("Parandum Cloud Functions", function () {
progressVocabTwo progressVocabTwo
], ],
set_title: setOne, set_title: setOne,
set_titles: [setOne],
start_time: 1627308670962, start_time: 1627308670962,
switch_language: false, switch_language: false,
uid: userOne, uid: userOne,
@@ -769,6 +780,7 @@ describe("Parandum Cloud Functions", function () {
progressVocabOne progressVocabOne
], ],
set_title: setOne, set_title: setOne,
set_titles: [setOne],
start_time: 1627308670962, start_time: 1627308670962,
switch_language: false, switch_language: false,
uid: userOne, uid: userOne,
@@ -805,6 +817,7 @@ describe("Parandum Cloud Functions", function () {
assert.notStrictEqual(snapAfterCorrectData.duration, null); assert.notStrictEqual(snapAfterCorrectData.duration, null);
assert.strictEqual(snapAfterCorrectData.progress, 3); assert.strictEqual(snapAfterCorrectData.progress, 3);
assert.strictEqual(snapAfterCorrectData.set_title, setOne); assert.strictEqual(snapAfterCorrectData.set_title, setOne);
assert.deepStrictEqual(snapAfterCorrectData.set_titles, [setOne]);
assert.strictEqual(snapAfterCorrectData.start_time, 1627308670962); assert.strictEqual(snapAfterCorrectData.start_time, 1627308670962);
assert.strictEqual(snapAfterCorrectData.switch_language, false); assert.strictEqual(snapAfterCorrectData.switch_language, false);
assert.strictEqual(snapAfterCorrectData.uid, userOne); assert.strictEqual(snapAfterCorrectData.uid, userOne);
@@ -826,6 +839,7 @@ describe("Parandum Cloud Functions", function () {
progressVocabTwo progressVocabTwo
], ],
set_title: setOne, set_title: setOne,
set_titles: [setOne],
start_time: 1627308670962, start_time: 1627308670962,
switch_language: false, switch_language: false,
uid: userOne, uid: userOne,
@@ -886,6 +900,7 @@ describe("Parandum Cloud Functions", function () {
progressVocabOne progressVocabOne
], ],
set_title: setOne, set_title: setOne,
set_titles: [setOne],
start_time: 1627308670962, start_time: 1627308670962,
switch_language: false, switch_language: false,
uid: userOne, uid: userOne,
@@ -936,6 +951,7 @@ describe("Parandum Cloud Functions", function () {
progressVocabOne progressVocabOne
], ],
set_title: setOne, set_title: setOne,
set_titles: [setOne],
start_time: 1627308670962, start_time: 1627308670962,
switch_language: false, switch_language: false,
uid: userOne, uid: userOne,
@@ -984,6 +1000,7 @@ describe("Parandum Cloud Functions", function () {
progressVocabOne progressVocabOne
], ],
set_title: setOne, set_title: setOne,
set_titles: [setOne],
start_time: 1627308670962, start_time: 1627308670962,
switch_language: false, switch_language: false,
uid: userOne, uid: userOne,
@@ -1034,6 +1051,7 @@ describe("Parandum Cloud Functions", function () {
progressVocabOne progressVocabOne
], ],
set_title: setOne, set_title: setOne,
set_titles: [setOne],
start_time: 1627308670962, start_time: 1627308670962,
switch_language: false, switch_language: false,
uid: userOne, uid: userOne,
@@ -1084,6 +1102,7 @@ describe("Parandum Cloud Functions", function () {
progressVocabOne progressVocabOne
], ],
set_title: setOne, set_title: setOne,
set_titles: [setOne],
start_time: 1627308670962, start_time: 1627308670962,
switch_language: false, switch_language: false,
uid: userOne, uid: userOne,
@@ -1134,6 +1153,7 @@ describe("Parandum Cloud Functions", function () {
progressVocabOne progressVocabOne
], ],
set_title: setOne, set_title: setOne,
set_titles: [setOne],
start_time: 1627308670962, start_time: 1627308670962,
switch_language: false, switch_language: false,
uid: userOne, uid: userOne,
@@ -1182,6 +1202,7 @@ describe("Parandum Cloud Functions", function () {
progressVocabOne progressVocabOne
], ],
set_title: setOne, set_title: setOne,
set_titles: [setOne],
start_time: 1627308670962, start_time: 1627308670962,
switch_language: false, switch_language: false,
uid: userOne, uid: userOne,
@@ -1232,6 +1253,7 @@ describe("Parandum Cloud Functions", function () {
progressVocabOne progressVocabOne
], ],
set_title: setOne, set_title: setOne,
set_titles: [setOne],
start_time: 1627308670962, start_time: 1627308670962,
switch_language: false, switch_language: false,
uid: userOne, uid: userOne,
@@ -1282,6 +1304,7 @@ describe("Parandum Cloud Functions", function () {
progressVocabOne progressVocabOne
], ],
set_title: setOne, set_title: setOne,
set_titles: [setOne],
start_time: 1627308670962, start_time: 1627308670962,
switch_language: false, switch_language: false,
uid: userOne, uid: userOne,
@@ -1334,6 +1357,7 @@ describe("Parandum Cloud Functions", function () {
progressVocabOne progressVocabOne
], ],
set_title: setOne, set_title: setOne,
set_titles: [setOne],
start_time: 1627308670962, start_time: 1627308670962,
switch_language: false, switch_language: false,
uid: userOne, uid: userOne,
@@ -1390,6 +1414,7 @@ describe("Parandum Cloud Functions", function () {
progressVocabOne progressVocabOne
], ],
set_title: `${setOne}__${setTwo}`, set_title: `${setOne}__${setTwo}`,
set_titles: [setOne, setTwo],
start_time: 1627308670962, start_time: 1627308670962,
switch_language: false, switch_language: false,
uid: userOne, uid: userOne,
@@ -1449,6 +1474,7 @@ describe("Parandum Cloud Functions", function () {
progressVocabOne progressVocabOne
], ],
set_title: `${setOne}__${setTwo}`, set_title: `${setOne}__${setTwo}`,
set_titles: [setOne, setTwo],
start_time: 1627308670962, start_time: 1627308670962,
switch_language: false, switch_language: false,
uid: userOne, uid: userOne,
@@ -1521,6 +1547,7 @@ describe("Parandum Cloud Functions", function () {
progressVocabOne progressVocabOne
], ],
set_title: setOne, set_title: setOne,
set_titles: [setOne],
start_time: 1627308670962, start_time: 1627308670962,
switch_language: false, switch_language: false,
uid: userOne, uid: userOne,
@@ -1563,6 +1590,7 @@ describe("Parandum Cloud Functions", function () {
switch_language: false, switch_language: false,
answer: incorrectAnswer, answer: incorrectAnswer,
setIds: [setOne], setIds: [setOne],
set_titles: [setOne],
}); });
}); });
@@ -1590,6 +1618,7 @@ describe("Parandum Cloud Functions", function () {
progressVocabOne progressVocabOne
], ],
set_title: setOne, set_title: setOne,
set_titles: [setOne],
start_time: 1627308670962, start_time: 1627308670962,
switch_language: false, switch_language: false,
uid: userOne, uid: userOne,
@@ -1641,6 +1670,7 @@ describe("Parandum Cloud Functions", function () {
switch_language: false, switch_language: false,
answer: incorrectAnswer, answer: incorrectAnswer,
setIds: [setOne], setIds: [setOne],
set_titles: [setOne],
}); });
}); });
@@ -1663,6 +1693,7 @@ describe("Parandum Cloud Functions", function () {
progressVocabOne progressVocabOne
], ],
set_title: setOne, set_title: setOne,
set_titles: [setOne],
start_time: 1627308670962, start_time: 1627308670962,
switch_language: false, switch_language: false,
uid: userOne, uid: userOne,
@@ -1719,6 +1750,7 @@ describe("Parandum Cloud Functions", function () {
progressVocabOne progressVocabOne
], ],
set_title: setOne, set_title: setOne,
set_titles: [setOne],
start_time: 1627308670962, start_time: 1627308670962,
switch_language: false, switch_language: false,
uid: userOne, uid: userOne,