diff --git a/db/index.js b/db/index.js index b8ea0028bc8a0044ed86ee038bc8b69658163e54..16f584ea827fc3c8f42229f76930a12603e93095 100644 --- a/db/index.js +++ b/db/index.js @@ -5,9 +5,10 @@ import fs from 'react-native-fs' import restart from 'react-native-restart' import schemas from './schemas' import cycleModule from '../lib/cycle' +import maybeSetNewCycleStart from '../lib/set-new-cycle-start' let db -let isMensesStart +let checkIsMensesStart let getMensesDaysRightAfter export async function openDb (hash) { @@ -50,7 +51,7 @@ export async function openDb (hash) { db = connection const cycle = cycleModule() - isMensesStart = cycle.isMensesStart + checkIsMensesStart = cycle.isMensesStart getMensesDaysRightAfter = cycle.getMensesDaysRightAfter return true } @@ -77,52 +78,21 @@ export function saveSymptom(symptom, date, val) { if (!cycleDay) cycleDay = createCycleDay(date) db.write(() => { - if (bleedingValueDeleted(symptom, val)) { - cycleDay.bleeding = val - cycleDay.isCycleStart = false - maybeSetNewCycleStart(cycleDay, val) - } else if (bleedingValueAddedOrChanged(symptom, val)) { - cycleDay.bleeding = val - cycleDay.isCycleStart = isMensesStart(cycleDay) - maybeClearOldCycleStarts(cycleDay) + if (symptom === 'bleeding') { + const mensesDaysAfter = getMensesDaysRightAfter(cycleDay) + maybeSetNewCycleStart({ + val, cycleDay, mensesDaysAfter, checkIsMensesStart + }) } else { cycleDay[symptom] = val } }) - - function bleedingValueDeleted(symptom, val) { - return symptom === 'bleeding' && !val - } - - function bleedingValueAddedOrChanged(symptom, val) { - return symptom === 'bleeding' && val - } - - function maybeSetNewCycleStart(dayWithDeletedBleeding) { - // if a bleeding value is deleted, we need to check if - // there are any following bleeding days and if the - // next one of them is now a cycle start - const mensesDaysAfter = getMensesDaysRightAfter(dayWithDeletedBleeding) - if (!mensesDaysAfter.length) return - const nextOne = mensesDaysAfter[mensesDaysAfter.length - 1] - if (isMensesStart(nextOne)) { - nextOne.isCycleStart = true - } - } - - function maybeClearOldCycleStarts(cycleDay) { - // if we have a new bleeding day, we need to clear the - // menses start marker from all following days of this - // menses that may have been marked as start before - const mensesDaysAfter = getMensesDaysRightAfter(cycleDay) - mensesDaysAfter.forEach(day => day.isCycleStart = false) - } } export function updateCycleStartsForAllCycleDays() { db.write(() => { getBleedingDaysSortedByDate().forEach(day => { - if (isMensesStart(day)) { + if (checkIsMensesStart(day)) { day.isCycleStart = true } }) diff --git a/lib/set-new-cycle-start.js b/lib/set-new-cycle-start.js new file mode 100644 index 0000000000000000000000000000000000000000..34b5a696c4f74ddefd9ca49488489be68f874254 --- /dev/null +++ b/lib/set-new-cycle-start.js @@ -0,0 +1,34 @@ +export default function ({ + val, cycleDay, mensesDaysAfter, checkIsMensesStart +}) { + + cycleDay.bleeding = val + + // if a bleeding value is deleted or excluded, we need to check if there are + // any following bleeding days and if the next one of them is now a cycle + // start + if (bleedingValueDeletedOrExluded(val)) { + cycleDay.isCycleStart = false + if (!mensesDaysAfter.length) return + const nextOne = mensesDaysAfter[mensesDaysAfter.length - 1] + if (checkIsMensesStart(nextOne)) { + nextOne.isCycleStart = true + } + } else { + cycleDay.isCycleStart = checkIsMensesStart(cycleDay) + maybeClearOldCycleStarts(cycleDay) + } + + function bleedingValueDeletedOrExluded(val) { + const bleedingDeleted = !val + const bleedingExcluded = val && val.exclude + return bleedingDeleted || bleedingExcluded + } + + function maybeClearOldCycleStarts() { + // if we have a new bleeding day, we need to clear the + // menses start marker from all following days of this + // menses that may have been marked as start before + mensesDaysAfter.forEach(day => day.isCycleStart = false) + } +} \ No newline at end of file diff --git a/test/set-new-cycle-start.spec.js b/test/set-new-cycle-start.spec.js new file mode 100644 index 0000000000000000000000000000000000000000..f7975104f89d489a650e50c06478b8f8d098f031 --- /dev/null +++ b/test/set-new-cycle-start.spec.js @@ -0,0 +1,151 @@ +import chai from 'chai' +import dirtyChai from 'dirty-chai' +import maybeSetNewCycleStart from '../lib/set-new-cycle-start' + +const expect = chai.expect +chai.use(dirtyChai) + +describe('maybeSetNewCycleStart', () => { + const deletedBleedingValue = null + + const excludedBleedingValue = { + value: 2, + exclude: true + } + + + function getFixtures() { + const cycleStartDay = { + date: '2020-01-01', + isCycleStart: true, + bleeding: { + value: 2, + exclude: false + } + } + + const mensesDaysAfter = [ + { + date: '2020-01-04', + isCycleStart: false, + value: { + bleeding: { + value: 2, + exclude: false + } + } + }, + { + date: '2020-01-03', + isCycleStart: false, + value: { + bleeding: { + value: 2, + exclude: false + } + } + }, + { + date: '2020-01-02', + isCycleStart: false, + value: { + bleeding: { + value: 2, + exclude: false + } + } + } + ] + + const notCycleStartDay = { + date: '2020-01-02', + isCycleStart: false, + bleeding: { + value: 2, + exclude: false + } + } + + return [cycleStartDay, mensesDaysAfter, notCycleStartDay] + } + + const checkIsMensesStart = cycleDay => { + if (cycleDay.date === '2020-01-02') return true + } + + it('sets new cycle start when first day of period deleted', () => { + const [cycleStartDay, mensesDaysAfter] = getFixtures() + + maybeSetNewCycleStart({ + val: deletedBleedingValue, + cycleDay: cycleStartDay, + mensesDaysAfter, + checkIsMensesStart + }) + expect(cycleStartDay.isCycleStart).to.be.false() + expect(cycleStartDay.bleeding).to.be.null() + expect(mensesDaysAfter[2].isCycleStart).to.be.true() + }) + + it('sets new cycle start when first day of period excluded', () => { + const [cycleStartDay, mensesDaysAfter] = getFixtures() + + maybeSetNewCycleStart({ + val: excludedBleedingValue, + cycleDay: cycleStartDay, + mensesDaysAfter, + checkIsMensesStart + }) + + expect(cycleStartDay.isCycleStart).to.be.false() + expect(cycleStartDay.bleeding).to.equal(excludedBleedingValue) + expect(mensesDaysAfter[2].isCycleStart).to.be.true() + }) + + it('does not set new cycle start when other day of period deleted', () => { + const [cycleStartDay, mensesDaysAfter, notCycleStartDay] = getFixtures() + + maybeSetNewCycleStart({ + val: deletedBleedingValue, + cycleDay: notCycleStartDay, + mensesDaysAfter, + checkIsMensesStart + }) + + expect(cycleStartDay.isCycleStart).to.be.true() + expect(notCycleStartDay.isCycleStart).to.be.false() + expect(notCycleStartDay.bleeding).to.equal(deletedBleedingValue) + }) + it('does not set new cycle start when other day of period excluded', () => { + const excludedBleedingValue = { + value: 2, + exclude: true + } + + const [cycleStartDay, mensesDaysAfter, notCycleStartDay] = getFixtures() + + maybeSetNewCycleStart({ + val: excludedBleedingValue, + cycleDay: notCycleStartDay, + mensesDaysAfter, + checkIsMensesStart + }) + + expect(cycleStartDay.isCycleStart).to.be.true() + expect(notCycleStartDay.isCycleStart).to.be.false() + expect(notCycleStartDay.bleeding).to.equal(excludedBleedingValue) + }) + it('works when there are no following bleeding days', () => { + const [cycleStartDay] = getFixtures() + + maybeSetNewCycleStart({ + val: deletedBleedingValue, + cycleDay: cycleStartDay, + mensesDaysAfter: [], + checkIsMensesStart + }) + + expect(cycleStartDay.isCycleStart).to.be.false() + expect(cycleStartDay.bleeding).to.equal(deletedBleedingValue) + }) +}) \ No newline at end of file