From 2f8054c1fac7c53b6533bf4a0283d45c01b6f8e8 Mon Sep 17 00:00:00 2001
From: Julia Friesel <julia.friesel@gmail.com>
Date: Tue, 3 Jul 2018 11:14:40 +0200
Subject: [PATCH] Add mucus shift detection

---
 lib/sympto/index.js       |  5 ++++
 lib/sympto/mucus.js       | 19 +++++++++++++++
 test/sympto/mucus.spec.js | 49 +++++++++++++++++++++++++++++++++++++++
 3 files changed, 73 insertions(+)
 create mode 100644 lib/sympto/mucus.js
 create mode 100644 test/sympto/mucus.spec.js

diff --git a/lib/sympto/index.js b/lib/sympto/index.js
index 92f513dd..3fd01021 100644
--- a/lib/sympto/index.js
+++ b/lib/sympto/index.js
@@ -4,4 +4,9 @@ import getMucusStatus from './mucus'
 export default function (cycleDays) {
   const temperatureStatus = getTemperatureStatus(cycleDays)
   const mucusStatus = getMucusStatus(cycleDays)
+  return {
+    assumeFertility: true,
+    temperatureStatus,
+    mucusStatus
+  }
 }
\ No newline at end of file
diff --git a/lib/sympto/mucus.js b/lib/sympto/mucus.js
new file mode 100644
index 00000000..f9c0d821
--- /dev/null
+++ b/lib/sympto/mucus.js
@@ -0,0 +1,19 @@
+export default function (cycleDays) {
+  const mucusDays = cycleDays.filter(day => day.mucus && !day.mucus.exclude)
+  const bestQuality = Math.max(...mucusDays.map(day => day.mucus.value))
+  const mucusPeak = mucusDays.find((day, i) => {
+    if (day.mucus.value !== bestQuality) return false
+
+    const threeFollowingDays = cycleDays.slice(i + 1, i + 4)
+    if (threeFollowingDays.length < 3) return false
+
+    return threeFollowingDays.every(day => day.mucus.value < bestQuality)
+  })
+
+  if (!mucusPeak) return { detected: false }
+
+  return {
+    detected: true,
+    mucusPeak
+  }
+}
diff --git a/test/sympto/mucus.spec.js b/test/sympto/mucus.spec.js
new file mode 100644
index 00000000..c0fd2da4
--- /dev/null
+++ b/test/sympto/mucus.spec.js
@@ -0,0 +1,49 @@
+import chai from 'chai'
+import getMucusStatus from '../../lib/sympto/mucus'
+
+const expect = chai.expect
+
+function turnIntoCycleDayObject(value, fakeDate) {
+  return {
+    mucus : { value },
+    date: fakeDate
+  }
+}
+
+describe('sympto', () => {
+  describe('detect mucus shift', () => {
+    describe('regular rule', () => {
+      it('detects mucus shift correctly', function () {
+        const values = [0, 0, 0, 1, 1, 2, 2, 2, 3, 3, 3, 2, 2, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0]
+          .map(turnIntoCycleDayObject)
+        const status = getMucusStatus(values)
+        expect(status).to.eql({
+          detected: true,
+          mucusPeak: {
+            date: 10,
+            mucus: { value: 3 }
+          }
+        })
+      })
+
+      it('detects no mucus shift when there are less than 3 days of lower quality', function () {
+        const values = [0, 1, 1, 2, 0, 0, 1, 2, 3, 2, 3, 3, 3, 2, 2]
+          .map(turnIntoCycleDayObject)
+        const status = getMucusStatus(values)
+        expect(status).to.eql({ detected: false })
+      })
+
+      it('detects no mucus shift when there are no mucus values', function () {
+        const status = getMucusStatus(Array(10).fill({date: 1, temperature: { value: 35}}))
+        expect(status).to.eql({ detected: false })
+      })
+
+      it('detects no mucus shift when the mucus values are all the same', function () {
+        const values = [2, 2, 2, 2, 2, 2, 2, 2]
+          .map(turnIntoCycleDayObject)
+        const status = getMucusStatus(values)
+        expect(status).to.eql({ detected: false })
+      })
+    })
+  })
+})
\ No newline at end of file
-- 
GitLab