From b09de916d509d130f1820afa1cb266db944b3732 Mon Sep 17 00:00:00 2001 From: Laurent Bossavit Date: Fri, 20 Oct 2017 00:47:49 +0200 Subject: [PATCH] :bug: Termine de corriger le bug du double unfold --- source/reducers.js | 14 +++++++++++--- test/reducers.test.js | 42 +++++++++++++++++++++++++++++++++++++++--- 2 files changed, 50 insertions(+), 6 deletions(-) diff --git a/source/reducers.js b/source/reducers.js index 6df518dd8..7c605280f 100644 --- a/source/reducers.js +++ b/source/reducers.js @@ -96,15 +96,23 @@ export let reduceSteps = (tracker, flatRules, answerSource) => (state, action) = if (action.type == STEP_ACTION && action.name == 'unfold') { tracker.push(['trackEvent', 'unfold', action.step]); + // The logic here is a bit hard to follow (TODO: refactor), + // it guarantees that (foldedSteps+unfoldedSteps) as a set is invariant + // foldedSteps should only have questions that have been answered + // unfoldedSteps is all the questions that must still be answered let stepFinder = R.propEq('name', action.step), previous = R.head(state.unfoldedSteps), - foldedSteps = R.reject(stepFinder)(R.concat(state.foldedSteps, previous ? [previous] : [])), - unfolded = R.find(stepFinder)(R.concat(state.foldedSteps, state.extraSteps)) + prevFinder = R.propEq('name', previous && previous.name), + answered = previous && (answerSource(state)(previous.name) != undefined), + foldable = answered ? [previous] : [], + foldedSteps = R.reject(stepFinder)(R.concat(state.foldedSteps, foldable)), + unfolded = R.find(stepFinder)(R.concat(state.foldedSteps, state.extraSteps)), + unfoldedSteps = R.concat([unfolded], answered ? R.reject(prevFinder)(state.unfoldedSteps) : state.unfoldedSteps) return { ...newState, foldedSteps, - unfoldedSteps: R.concat([unfolded], state.unfoldedSteps) + unfoldedSteps } } } diff --git a/test/reducers.test.js b/test/reducers.test.js index b4094fd6b..a5d535db6 100644 --- a/test/reducers.test.js +++ b/test/reducers.test.js @@ -61,12 +61,48 @@ describe('fold', function() { let result = step5 expect(result).to.have.property('unfoldedSteps') - expect(result.unfoldedSteps).to.have.lengthOf(3) + expect(result.unfoldedSteps).to.have.lengthOf(2) expect(result.unfoldedSteps[0]).to.have.deep.property("name","top . bb") + expect(result.unfoldedSteps[1]).to.have.deep.property("name","top . cc") + expect(result).to.have.property('foldedSteps') + expect(result.foldedSteps).to.have.lengthOf(1) + expect(result.foldedSteps[0]).to.have.deep.property("name","top . aa") + }); + + it('should not list the same question in folded and unfolded', function() { + let fakeState = {} + let stateSelector = state => name => fakeState[name] + + let rawRules = [ + // TODO - this won't work without the indirection, figure out why + {nom: "startHere", formule: {somme: ["a","b","c"]}, espace: "top"}, + {nom: "a", espace: "top", formule: "aa"}, + {nom: "b", espace: "top", formule: "bb"}, + {nom: "c", espace: "top", formule: "cc"}, + {nom: "aa", question: "?", titre: "a", espace: "top"}, + {nom: "bb", question: "?", titre: "b", espace: "top"}, + {nom: "cc", question: "?", titre: "c", espace: "top"}], + rules = rawRules.map(enrichRule), + reducer = reduceSteps(tracker, rules, stateSelector) + + var step1 = reducer({},{type:'START_CONVERSATION', rootVariable: 'startHere'}) + fakeState['top . aa'] = 1 + var step2 = reducer(step1,{type:'STEP_ACTION', name: 'fold', step: 'top . aa'}) + fakeState['top . bb'] = 1 + var step3 = reducer(step2,{type:'STEP_ACTION', name: 'fold', step: 'top . bb'}) + var step4 = reducer(step3,{type:'STEP_ACTION', name: 'unfold', step: 'top . aa'}) + var step5 = reducer(step4,{type:'STEP_ACTION', name: 'unfold', step: 'top . bb'}) + var step6 = reducer(step5,{type:'STEP_ACTION', name: 'fold', step: 'top . bb'}) + + let result = step6 + + expect(result).to.have.property('unfoldedSteps') + expect(result.unfoldedSteps).to.have.lengthOf(1) + expect(result.unfoldedSteps[0]).to.have.deep.property("name","top . cc") expect(result).to.have.property('foldedSteps') expect(result.foldedSteps).to.have.lengthOf(2) - expect(result.foldedSteps[0]).to.have.deep.property("name","top . cc") - expect(result.foldedSteps[1]).to.have.deep.property("name","top . aa") + expect(result.foldedSteps[0]).to.have.deep.property("name","top . aa") + expect(result.foldedSteps[1]).to.have.deep.property("name","top . bb") }); });