From aa2fad344ae6dea1877eb07fb6b68ed7fba86c19 Mon Sep 17 00:00:00 2001
From: Arnaud Vergnet <vergnet@etud.insa-toulouse.fr>
Date: Thu, 30 Apr 2020 22:38:33 +0200
Subject: [PATCH] Improved notification activation on corner cases

---
 __tests__/utils/Proxiwash.test.js        | 22 +++++++++++++------
 src/screens/Proxiwash/ProxiwashScreen.js | 26 ++++++++++-------------
 src/utils/Notifications.js               |  2 +-
 src/utils/Proxiwash.js                   | 27 ++++++++++++++++++------
 4 files changed, 47 insertions(+), 30 deletions(-)

diff --git a/__tests__/utils/Proxiwash.test.js b/__tests__/utils/Proxiwash.test.js
index 26f8329..4aca8e7 100644
--- a/__tests__/utils/Proxiwash.test.js
+++ b/__tests__/utils/Proxiwash.test.js
@@ -4,21 +4,29 @@ import {getCleanedMachineWatched, getMachineEndDate, getMachineOfId, isMachineWa
 test('getMachineEndDate', () => {
     jest.spyOn(Date, 'now')
         .mockImplementation(() =>
-            new Date('2020-01-14T00:00:00.000Z').getTime()
+            new Date('2020-01-14T15:00:00.000Z').getTime()
         );
-    let expectDate = new Date('2020-01-14T00:00:00.000Z');
+    let expectDate = new Date('2020-01-14T15:00:00.000Z');
     expectDate.setHours(23);
     expectDate.setMinutes(10);
     expect(getMachineEndDate({endTime: "23:10"}).getTime()).toBe(expectDate.getTime());
 
-    expectDate.setHours(15);
+    expectDate.setHours(16);
     expectDate.setMinutes(30);
-    expect(getMachineEndDate({endTime: "15:30"}).getTime()).toBe(expectDate.getTime());
+    expect(getMachineEndDate({endTime: "16:30"}).getTime()).toBe(expectDate.getTime());
 
+    expect(getMachineEndDate({endTime: "15:30"})).toBeNull();
+
+    expect(getMachineEndDate({endTime: "13:10"})).toBeNull();
+
+    jest.spyOn(Date, 'now')
+        .mockImplementation(() =>
+            new Date('2020-01-14T23:00:00.000Z').getTime()
+        );
+    expectDate = new Date('2020-01-14T23:00:00.000Z');
     expectDate.setHours(0);
-    expectDate.setMinutes(10);
-    expectDate.setDate(expectDate.getDate() + 1);
-    expect(getMachineEndDate({endTime: "00:10"}).getTime()).toBe(expectDate.getTime());
+    expectDate.setMinutes(30);
+    expect(getMachineEndDate({endTime: "00:30"}).getTime()).toBe(expectDate.getTime());
 });
 
 test('isMachineWatched', () => {
diff --git a/src/screens/Proxiwash/ProxiwashScreen.js b/src/screens/Proxiwash/ProxiwashScreen.js
index c5ead79..bd5217c 100644
--- a/src/screens/Proxiwash/ProxiwashScreen.js
+++ b/src/screens/Proxiwash/ProxiwashScreen.js
@@ -18,6 +18,7 @@ import type {CustomTheme} from "../../managers/ThemeManager";
 import {Collapsible} from "react-navigation-collapsible";
 import {StackNavigationProp} from "@react-navigation/stack";
 import {getCleanedMachineWatched, getMachineEndDate, isMachineWatched} from "../../utils/Proxiwash";
+import {Modalize} from "react-native-modalize";
 
 const DATA_URL = "https://etud.insa-toulouse.fr/~amicale_app/washinsa/washinsa.json";
 
@@ -55,9 +56,12 @@ type State = {
  */
 class ProxiwashScreen extends React.Component<Props, State> {
 
-    modalRef: Object;
+    modalRef: null | Modalize;
 
-    fetchedData: Object;
+    fetchedData: {
+        dryers: Array<Machine>,
+        washers: Array<Machine>,
+    };
 
     state = {
         refreshing: false,
@@ -95,7 +99,10 @@ class ProxiwashScreen extends React.Component<Props, State> {
      */
     componentDidMount() {
         this.props.navigation.setOptions({
-            headerRight: this.getAboutButton,
+            headerRight:
+                <MaterialHeaderButtons>
+                    <Item title="information" iconName="information" onPress={this.onAboutPress}/>
+                </MaterialHeaderButtons>,
         });
     }
 
@@ -105,16 +112,6 @@ class ProxiwashScreen extends React.Component<Props, State> {
      */
     onAboutPress = () => this.props.navigation.navigate('proxiwash-about');
 
-    /**
-     * Gets the about header button
-     *
-     * @return {*}
-     */
-    getAboutButton = () =>
-        <MaterialHeaderButtons>
-            <Item title="information" iconName="information" onPress={this.onAboutPress}/>
-        </MaterialHeaderButtons>;
-
     /**
      * Extracts the key for the given item
      *
@@ -123,7 +120,6 @@ class ProxiwashScreen extends React.Component<Props, State> {
      */
     getKeyExtractor = (item: Machine) => item.number;
 
-
     /**
      * Setups notifications for the machine with the given ID.
      * One notification will be sent at the end of the program.
@@ -141,7 +137,7 @@ class ProxiwashScreen extends React.Component<Props, State> {
                     this.showNotificationsDisabledWarning();
                 });
         } else {
-            Notifications.setupMachineNotification(machine.number, false)
+            Notifications.setupMachineNotification(machine.number, false, null)
                 .then(() => {
                     this.removeNotificationFromState(machine);
                 });
diff --git a/src/utils/Notifications.js b/src/utils/Notifications.js
index 6203056..bc5d274 100644
--- a/src/utils/Notifications.js
+++ b/src/utils/Notifications.js
@@ -62,7 +62,7 @@ function createNotifications(machineID: string, date: Date) {
  * @param isEnabled True to enable notifications, false to disable
  * @param endDate
  */
-export async function setupMachineNotification(machineID: string, isEnabled: boolean, endDate?: Date) {
+export async function setupMachineNotification(machineID: string, isEnabled: boolean, endDate: Date | null) {
     return new Promise((resolve, reject) => {
         if (isEnabled && endDate != null) {
             askPermissions()
diff --git a/src/utils/Proxiwash.js b/src/utils/Proxiwash.js
index 0814e25..a891fd4 100644
--- a/src/utils/Proxiwash.js
+++ b/src/utils/Proxiwash.js
@@ -4,18 +4,31 @@ import type {Machine} from "../screens/Proxiwash/ProxiwashScreen";
 
 /**
  * Gets the machine end Date object.
- * If the time is before the current time, it will be considered as tomorrow
+ * If the end time is at least 12 hours before the current time,
+ * it will be considered as happening the day after.
+ * If it is before but less than 12 hours, it will be considered invalid (to fix proxiwash delay)
  *
  * @param machine The machine to get the date from
  * @returns {Date} The date object representing the end time.
  */
-export function getMachineEndDate(machine: Machine) {
+export function getMachineEndDate(machine: Machine): Date | null {
     const array = machine.endTime.split(":");
-    let date = new Date(Date.now());
-    date.setHours(parseInt(array[0]), parseInt(array[1]));
-    if (date < new Date(Date.now()))
-        date.setDate(date.getDate() + 1);
-    return date;
+    let endDate = new Date(Date.now());
+    endDate.setHours(parseInt(array[0]), parseInt(array[1]));
+
+    let limit = new Date(Date.now());
+    if (endDate < limit) {
+        if (limit.getHours() > 12) {
+            limit.setHours(limit.getHours() - 12);
+            if (endDate < limit)
+                endDate.setDate(endDate.getDate() + 1);
+            else
+                endDate = null;
+        } else
+            endDate = null;
+    }
+
+    return endDate;
 }
 
 /**