From e679f5eaff2a65c6d3691704389cdb343f745eea Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Sun, 21 Apr 2019 16:17:25 +0200 Subject: [PATCH] ActionNotification --- .../actions/ActionNotification.java | 90 ++++++++++ .../dialogs/ChooseActionDialog.java | 2 + .../automation/elements/InputString.java | 56 +++++++ .../overview/notifications/Notification.java | 1 + .../main/res/layout/automation_fragment.xml | 5 +- app/src/main/res/values/strings.xml | 4 + app/src/test/java/info/AAPSMocker.java | 1 + .../actions/ActionNotificationTest.java | 93 +++++++++++ .../automation/elements/InputStringTest.java | 154 ++++++++++++++++++ 9 files changed, 404 insertions(+), 2 deletions(-) create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionNotification.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/InputString.java create mode 100644 app/src/test/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionNotificationTest.java create mode 100644 app/src/test/java/info/nightscout/androidaps/plugins/general/automation/elements/InputStringTest.java diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionNotification.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionNotification.java new file mode 100644 index 0000000000..2f8b233574 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionNotification.java @@ -0,0 +1,90 @@ +package info.nightscout.androidaps.plugins.general.automation.actions; + +import android.widget.LinearLayout; + +import com.google.common.base.Optional; + +import org.json.JSONException; +import org.json.JSONObject; + +import info.nightscout.androidaps.MainApp; +import info.nightscout.androidaps.R; +import info.nightscout.androidaps.data.PumpEnactResult; +import info.nightscout.androidaps.events.EventRefreshOverview; +import info.nightscout.androidaps.plugins.general.automation.elements.InputString; +import info.nightscout.androidaps.plugins.general.automation.elements.Label; +import info.nightscout.androidaps.plugins.general.automation.elements.LayoutBuilder; +import info.nightscout.androidaps.plugins.general.nsclient.NSUpload; +import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification; +import info.nightscout.androidaps.plugins.general.overview.notifications.Notification; +import info.nightscout.androidaps.queue.Callback; +import info.nightscout.androidaps.utils.JsonHelper; + +public class ActionNotification extends Action { + public InputString text = new InputString(); + + @Override + public int friendlyName() { + return R.string.notification; + } + + @Override + public String shortDescription() { + return MainApp.gs(R.string.notification_message, text.getValue()); + } + + @Override + public void doAction(Callback callback) { + Notification notification = new Notification(Notification.USERMESSAGE, text.getValue(), Notification.URGENT); + MainApp.bus().post(new EventNewNotification(notification)); + NSUpload.uploadError(text.getValue()); + MainApp.bus().post(new EventRefreshOverview("ActionNotification")); + if (callback != null) + callback.result(new PumpEnactResult().success(true).comment(R.string.ok)).run(); + + } + + @Override + public Optional icon() { + return Optional.of(R.drawable.remove); + } + + @Override + public String toJSON() { + JSONObject o = new JSONObject(); + JSONObject data = new JSONObject(); + try { + data.put("text", text.getValue()); + o.put("type", this.getClass().getName()); + o.put("data", data); + } catch (JSONException e) { + e.printStackTrace(); + } + return o.toString(); + } + + @Override + public Action fromJSON(String data) { + try { + JSONObject o = new JSONObject(data); + text.setValue(JsonHelper.safeGetString(o, "text")); + } catch (JSONException e) { + e.printStackTrace(); + } + return this; + } + + @Override + public boolean hasDialog() { + return true; + } + + @Override + public void generateDialog(LinearLayout root) { + + new LayoutBuilder() + .add(new Label(MainApp.gs(R.string.message_short), "", text)) + .build(root); + } + +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/dialogs/ChooseActionDialog.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/dialogs/ChooseActionDialog.java index 601b8265e3..351adf34f8 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/dialogs/ChooseActionDialog.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/dialogs/ChooseActionDialog.java @@ -22,6 +22,7 @@ import info.nightscout.androidaps.plugins.general.automation.actions.ActionLoopD import info.nightscout.androidaps.plugins.general.automation.actions.ActionLoopEnable; import info.nightscout.androidaps.plugins.general.automation.actions.ActionLoopResume; import info.nightscout.androidaps.plugins.general.automation.actions.ActionLoopSuspend; +import info.nightscout.androidaps.plugins.general.automation.actions.ActionNotification; import info.nightscout.androidaps.plugins.general.automation.actions.ActionStartTempTarget; import info.nightscout.androidaps.plugins.general.automation.actions.ActionStopTempTarget; @@ -40,6 +41,7 @@ public class ChooseActionDialog extends DialogFragment { add(new ActionLoopSuspend()); add(new ActionStartTempTarget()); add(new ActionStopTempTarget()); + add(new ActionNotification()); }}; private Unbinder mUnbinder; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/InputString.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/InputString.java new file mode 100644 index 0000000000..75ddb4b61a --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/InputString.java @@ -0,0 +1,56 @@ +package info.nightscout.androidaps.plugins.general.automation.elements; + +import android.text.Editable; +import android.text.TextWatcher; +import android.view.ViewGroup; +import android.widget.EditText; +import android.widget.LinearLayout; + +public class InputString extends Element { + + TextWatcher textWatcher = new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence s, int start, int count, int after) { + } + + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) { + } + + @Override + public void afterTextChanged(Editable s) { + value = s.toString(); + } + }; + + private String value = ""; + + public InputString() { + super(); + } + + public InputString(InputString another) { + super(); + value = another.getValue(); + } + + + @Override + public void addToLayout(LinearLayout root) { + EditText editText = new EditText(root.getContext()); + editText.setText(value); + editText.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)); + editText.addTextChangedListener(textWatcher); + root.addView(editText); + } + + public InputString setValue(String value) { + this.value = value; + return this; + } + + public String getValue() { + return value; + } + +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/notifications/Notification.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/notifications/Notification.java index f7a4c32360..26b81ce6de 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/notifications/Notification.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/notifications/Notification.java @@ -75,6 +75,7 @@ public class Notification { public static final int DST_IN_24H = 50; public static final int DISKFULL = 51; public static final int OLDVERSION = 52; + public static final int USERMESSAGE = 53; public int id; diff --git a/app/src/main/res/layout/automation_fragment.xml b/app/src/main/res/layout/automation_fragment.xml index e12d8008f3..56e84808d7 100644 --- a/app/src/main/res/layout/automation_fragment.xml +++ b/app/src/main/res/layout/automation_fragment.xml @@ -1,5 +1,6 @@ + android:src="@drawable/ic_add_black_24dp" + app:backgroundTint="@color/defaulttext" /> very old version New version for at least %1$d days available! Fallback to LGS after 60 days, loop will be disabled after 90 days + Notification + Notification: %1$s + Msg: + %1$d day %1$d days diff --git a/app/src/test/java/info/AAPSMocker.java b/app/src/test/java/info/AAPSMocker.java index c3788fc2f9..fd2661f6eb 100644 --- a/app/src/test/java/info/AAPSMocker.java +++ b/app/src/test/java/info/AAPSMocker.java @@ -39,6 +39,7 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; diff --git a/app/src/test/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionNotificationTest.java b/app/src/test/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionNotificationTest.java new file mode 100644 index 0000000000..6813a26b36 --- /dev/null +++ b/app/src/test/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionNotificationTest.java @@ -0,0 +1,93 @@ +package info.nightscout.androidaps.plugins.general.automation.actions; + +import com.google.common.base.Optional; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import info.AAPSMocker; +import info.nightscout.androidaps.Constants; +import info.nightscout.androidaps.MainApp; +import info.nightscout.androidaps.R; +import info.nightscout.androidaps.db.TempTarget; +import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions; +import info.nightscout.androidaps.plugins.general.automation.elements.InputBg; +import info.nightscout.androidaps.plugins.general.automation.elements.InputDuration; +import info.nightscout.androidaps.plugins.general.automation.elements.InputString; +import info.nightscout.androidaps.plugins.general.nsclient.NSUpload; +import info.nightscout.androidaps.plugins.general.overview.OverviewPlugin; +import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin; +import info.nightscout.androidaps.queue.Callback; +import info.nightscout.androidaps.utils.SP; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.when; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({MainApp.class, SP.class, NSUpload.class}) +public class ActionNotificationTest { + private ActionNotification actionNotification; + + @Test + public void friendlyNameTest() { + Assert.assertEquals(R.string.notification, actionNotification.friendlyName()); + } + + @Test + public void shortDescriptionTest() { + actionNotification = new ActionNotification(); + actionNotification.text = new InputString().setValue("Asd"); + Assert.assertEquals(null, actionNotification.shortDescription()); // not mocked + } + + @Test + public void iconTest() { + Assert.assertEquals(Optional.of(R.drawable.remove), actionNotification.icon()); + } + + @Test + public void doActionTest() { + actionNotification.doAction(new Callback() { + @Override + public void run() { + Assert.assertTrue(result.success); + } + }); + } + + @Test + public void hasDialogTest() { + Assert.assertTrue(actionNotification.hasDialog()); + } + + @Test + public void toJSONTest() { + actionNotification = new ActionNotification(); + actionNotification.text = new InputString().setValue("Asd"); + Assert.assertEquals("{\"data\":{\"text\":\"Asd\"},\"type\":\"info.nightscout.androidaps.plugins.general.automation.actions.ActionNotification\"}", actionNotification.toJSON()); + } + + @Test + public void fromJSONTest() { + actionNotification = new ActionNotification(); + actionNotification.fromJSON("{\"text\":\"Asd\"}"); + Assert.assertEquals("Asd", actionNotification.text.getValue()); + } + + @Before + public void prepareTest() { + AAPSMocker.mockMainApp(); + AAPSMocker.mockSP(); + AAPSMocker.mockStrings(); + AAPSMocker.mockBus(); + AAPSMocker.mockNSUpload(); + + actionNotification = new ActionNotification(); + } +} diff --git a/app/src/test/java/info/nightscout/androidaps/plugins/general/automation/elements/InputStringTest.java b/app/src/test/java/info/nightscout/androidaps/plugins/general/automation/elements/InputStringTest.java new file mode 100644 index 0000000000..a29c17578c --- /dev/null +++ b/app/src/test/java/info/nightscout/androidaps/plugins/general/automation/elements/InputStringTest.java @@ -0,0 +1,154 @@ +package info.nightscout.androidaps.plugins.general.automation.elements; + +import android.support.annotation.NonNull; +import android.text.Editable; +import android.text.InputFilter; + +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import info.nightscout.androidaps.MainApp; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({MainApp.class}) +public class InputStringTest { + + @Test + public void textWatcherTest() { + InputString t = new InputString().setValue("asd"); + t.textWatcher.beforeTextChanged(null, 0, 0, 0); + t.textWatcher.onTextChanged(null, 0, 0, 0); + t.textWatcher.afterTextChanged(new Editable() { + @Override + public Editable replace(int st, int en, CharSequence source, int start, int end) { + return null; + } + + @Override + public Editable replace(int st, int en, CharSequence text) { + return null; + } + + @Override + public Editable insert(int where, CharSequence text, int start, int end) { + return null; + } + + @Override + public Editable insert(int where, CharSequence text) { + return null; + } + + @Override + public Editable delete(int st, int en) { + return null; + } + + @Override + public Editable append(CharSequence text) { + return null; + } + + @Override + public Editable append(CharSequence text, int start, int end) { + return null; + } + + @Override + public Editable append(char text) { + return null; + } + + @Override + public void clear() { + + } + + @Override + public void clearSpans() { + + } + + @Override + public void setFilters(InputFilter[] filters) { + + } + + @Override + public InputFilter[] getFilters() { + return new InputFilter[0]; + } + + @Override + public void getChars(int start, int end, char[] dest, int destoff) { + + } + + @Override + public void setSpan(Object what, int start, int end, int flags) { + + } + + @Override + public void removeSpan(Object what) { + + } + + @Override + public T[] getSpans(int start, int end, Class type) { + return null; + } + + @Override + public int getSpanStart(Object tag) { + return 0; + } + + @Override + public int getSpanEnd(Object tag) { + return 0; + } + + @Override + public int getSpanFlags(Object tag) { + return 0; + } + + @Override + public int nextSpanTransition(int start, int limit, Class type) { + return 0; + } + + @Override + public int length() { + return 0; + } + + @Override + public char charAt(int index) { + return 0; + } + + @Override + public CharSequence subSequence(int start, int end) { + return null; + } + + @NonNull + @Override + public String toString() { + return "qwerty"; + } + }); + Assert.assertEquals("qwerty", t.getValue()); + } + + @Test + public void getSetValueTest() { + InputString i = new InputString().setValue("asd"); + Assert.assertEquals("asd", i.getValue()); + } +} \ No newline at end of file