isClosedLoopAllowed & isLoopInvokationAllowed tests
This commit is contained in:
parent
3a85a6f319
commit
f6fdef7986
4 changed files with 189 additions and 30 deletions
|
@ -3,9 +3,9 @@ package info.nightscout.androidaps.data;
|
|||
import java.util.ArrayList;
|
||||
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.interfaces.Constraint;
|
||||
import info.nightscout.androidaps.interfaces.ConstraintsInterface;
|
||||
import info.nightscout.androidaps.interfaces.PluginBase;
|
||||
import info.nightscout.androidaps.interfaces.Constraint;
|
||||
import info.nightscout.utils.SP;
|
||||
|
||||
/**
|
||||
|
|
|
@ -15,9 +15,9 @@ import info.nightscout.androidaps.MainApp;
|
|||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.db.DatabaseHelper;
|
||||
import info.nightscout.androidaps.interfaces.APSInterface;
|
||||
import info.nightscout.androidaps.interfaces.Constraint;
|
||||
import info.nightscout.androidaps.interfaces.ConstraintsInterface;
|
||||
import info.nightscout.androidaps.interfaces.PluginBase;
|
||||
import info.nightscout.androidaps.interfaces.Constraint;
|
||||
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
||||
import info.nightscout.androidaps.plugins.ConstraintsSafety.SafetyPlugin;
|
||||
import info.nightscout.androidaps.plugins.Loop.LoopPlugin;
|
||||
|
@ -67,7 +67,7 @@ public class ObjectivesPlugin implements PluginBase, ConstraintsInterface {
|
|||
|
||||
@Override
|
||||
public String getNameShort() {
|
||||
String name = MainApp.sResources.getString(R.string.objectives_shortname);
|
||||
String name = MainApp.gs(R.string.objectives_shortname);
|
||||
if (!name.trim().isEmpty()) {
|
||||
//only if translation exists
|
||||
return name;
|
||||
|
@ -115,7 +115,7 @@ public class ObjectivesPlugin implements PluginBase, ConstraintsInterface {
|
|||
return -1;
|
||||
}
|
||||
|
||||
class Objective {
|
||||
public class Objective {
|
||||
Integer num;
|
||||
String objective;
|
||||
String gate;
|
||||
|
@ -131,6 +131,10 @@ public class ObjectivesPlugin implements PluginBase, ConstraintsInterface {
|
|||
this.durationInDays = durationInDays;
|
||||
this.accomplished = accomplished;
|
||||
}
|
||||
|
||||
public void setStarted(Date started) {
|
||||
this.started = started;
|
||||
}
|
||||
}
|
||||
|
||||
// Objective 0
|
||||
|
@ -169,27 +173,27 @@ public class ObjectivesPlugin implements PluginBase, ConstraintsInterface {
|
|||
apsEnabled = true;
|
||||
|
||||
return new RequirementResult(hasBGData && bgIsAvailableInNS && pumpStatusIsAvailableInNS && NSClientInternalPlugin.getPlugin().hasWritePermission() && LoopPlugin.getPlugin().isEnabled(PluginBase.LOOP) && apsEnabled && vpUploadNeeded,
|
||||
MainApp.sResources.getString(R.string.objectives_bgavailableinns) + ": " + yesOrNo(bgIsAvailableInNS)
|
||||
+ "\n" + MainApp.sResources.getString(R.string.nsclienthaswritepermission) + ": " + yesOrNo(NSClientInternalPlugin.getPlugin().hasWritePermission())
|
||||
+ (isVirtualPump ? "\n" + MainApp.sResources.getString(R.string.virtualpump_uploadstatus_title) + ": " + yesOrNo(vpUploadEnabled) : "")
|
||||
+ "\n" + MainApp.sResources.getString(R.string.objectives_pumpstatusavailableinns) + ": " + yesOrNo(pumpStatusIsAvailableInNS)
|
||||
+ "\n" + MainApp.sResources.getString(R.string.hasbgdata) + ": " + yesOrNo(hasBGData)
|
||||
+ "\n" + MainApp.sResources.getString(R.string.loopenabled) + ": " + yesOrNo(LoopPlugin.getPlugin().isEnabled(PluginBase.LOOP))
|
||||
+ "\n" + MainApp.sResources.getString(R.string.apsselected) + ": " + yesOrNo(apsEnabled)
|
||||
MainApp.gs(R.string.objectives_bgavailableinns) + ": " + yesOrNo(bgIsAvailableInNS)
|
||||
+ "\n" + MainApp.gs(R.string.nsclienthaswritepermission) + ": " + yesOrNo(NSClientInternalPlugin.getPlugin().hasWritePermission())
|
||||
+ (isVirtualPump ? "\n" + MainApp.gs(R.string.virtualpump_uploadstatus_title) + ": " + yesOrNo(vpUploadEnabled) : "")
|
||||
+ "\n" + MainApp.gs(R.string.objectives_pumpstatusavailableinns) + ": " + yesOrNo(pumpStatusIsAvailableInNS)
|
||||
+ "\n" + MainApp.gs(R.string.hasbgdata) + ": " + yesOrNo(hasBGData)
|
||||
+ "\n" + MainApp.gs(R.string.loopenabled) + ": " + yesOrNo(LoopPlugin.getPlugin().isEnabled(PluginBase.LOOP))
|
||||
+ "\n" + MainApp.gs(R.string.apsselected) + ": " + yesOrNo(apsEnabled)
|
||||
);
|
||||
case 1:
|
||||
return new RequirementResult(manualEnacts >= manualEnactsNeeded,
|
||||
MainApp.sResources.getString(R.string.objectives_manualenacts) + ": " + manualEnacts + "/" + manualEnactsNeeded);
|
||||
MainApp.gs(R.string.objectives_manualenacts) + ": " + manualEnacts + "/" + manualEnactsNeeded);
|
||||
case 2:
|
||||
return new RequirementResult(true, "");
|
||||
case 3:
|
||||
Constraint<Boolean> closedLoopEnabled = new Constraint<>(true);
|
||||
SafetyPlugin.getPlugin().isClosedLoopAllowed(closedLoopEnabled);
|
||||
return new RequirementResult(closedLoopEnabled.get(), MainApp.sResources.getString(R.string.closedmodeenabled) + ": " + yesOrNo(closedLoopEnabled.get()));
|
||||
return new RequirementResult(closedLoopEnabled.get(), MainApp.gs(R.string.closedmodeenabled) + ": " + yesOrNo(closedLoopEnabled.get()));
|
||||
case 4:
|
||||
double maxIOB = MainApp.getConstraintChecker().applyMaxIOBConstraints(1000d);
|
||||
boolean maxIobSet = maxIOB > 0;
|
||||
return new RequirementResult(maxIobSet, MainApp.sResources.getString(R.string.maxiobset) + ": " + yesOrNo(maxIobSet));
|
||||
return new RequirementResult(maxIobSet, MainApp.gs(R.string.maxiobset) + ": " + yesOrNo(maxIobSet));
|
||||
default:
|
||||
return new RequirementResult(true, "");
|
||||
}
|
||||
|
@ -203,49 +207,49 @@ public class ObjectivesPlugin implements PluginBase, ConstraintsInterface {
|
|||
|
||||
objectives = new ArrayList<>();
|
||||
objectives.add(new Objective(0,
|
||||
MainApp.sResources.getString(R.string.objectives_0_objective),
|
||||
MainApp.sResources.getString(R.string.objectives_0_gate),
|
||||
MainApp.gs(R.string.objectives_0_objective),
|
||||
MainApp.gs(R.string.objectives_0_gate),
|
||||
new Date(0),
|
||||
0, // 0 day
|
||||
new Date(0)));
|
||||
objectives.add(new Objective(1,
|
||||
MainApp.sResources.getString(R.string.objectives_1_objective),
|
||||
MainApp.sResources.getString(R.string.objectives_1_gate),
|
||||
MainApp.gs(R.string.objectives_1_objective),
|
||||
MainApp.gs(R.string.objectives_1_gate),
|
||||
new Date(0),
|
||||
7, // 7 days
|
||||
new Date(0)));
|
||||
objectives.add(new Objective(2,
|
||||
MainApp.sResources.getString(R.string.objectives_2_objective),
|
||||
MainApp.sResources.getString(R.string.objectives_2_gate),
|
||||
MainApp.gs(R.string.objectives_2_objective),
|
||||
MainApp.gs(R.string.objectives_2_gate),
|
||||
new Date(0),
|
||||
0, // 0 days
|
||||
new Date(0)));
|
||||
objectives.add(new Objective(3,
|
||||
MainApp.sResources.getString(R.string.objectives_3_objective),
|
||||
MainApp.sResources.getString(R.string.objectives_3_gate),
|
||||
MainApp.gs(R.string.objectives_3_objective),
|
||||
MainApp.gs(R.string.objectives_3_gate),
|
||||
new Date(0),
|
||||
5, // 5 days
|
||||
new Date(0)));
|
||||
objectives.add(new Objective(4,
|
||||
MainApp.sResources.getString(R.string.objectives_4_objective),
|
||||
MainApp.sResources.getString(R.string.objectives_4_gate),
|
||||
MainApp.gs(R.string.objectives_4_objective),
|
||||
MainApp.gs(R.string.objectives_4_gate),
|
||||
new Date(0),
|
||||
1,
|
||||
new Date(0)));
|
||||
objectives.add(new Objective(5,
|
||||
MainApp.sResources.getString(R.string.objectives_5_objective),
|
||||
MainApp.sResources.getString(R.string.objectives_5_gate),
|
||||
MainApp.gs(R.string.objectives_5_objective),
|
||||
MainApp.gs(R.string.objectives_5_gate),
|
||||
new Date(0),
|
||||
7,
|
||||
new Date(0)));
|
||||
objectives.add(new Objective(6,
|
||||
MainApp.sResources.getString(R.string.objectives_6_objective),
|
||||
MainApp.gs(R.string.objectives_6_objective),
|
||||
"",
|
||||
new Date(0),
|
||||
28,
|
||||
new Date(0)));
|
||||
objectives.add(new Objective(7,
|
||||
MainApp.sResources.getString(R.string.objectives_7_objective),
|
||||
MainApp.gs(R.string.objectives_7_objective),
|
||||
"",
|
||||
new Date(0),
|
||||
28,
|
||||
|
|
|
@ -424,7 +424,7 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf
|
|||
return;
|
||||
}
|
||||
pump.basalProfile = readBasalResult.basalProfile;
|
||||
validBasalRateProfileSelectedOnPump = true;
|
||||
setValidBasalRateProfileSelectedOnPump(true);
|
||||
|
||||
pump.initialized = true;
|
||||
MainApp.bus().post(new EventInitializationChanged());
|
||||
|
@ -925,7 +925,7 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf
|
|||
if (commandResult.success) {
|
||||
pump.lastSuccessfulCmdTime = System.currentTimeMillis();
|
||||
if (validBasalRateProfileSelectedOnPump && commandResult.state.unsafeUsageDetected == PumpState.UNSUPPORTED_BASAL_RATE_PROFILE) {
|
||||
validBasalRateProfileSelectedOnPump = false;
|
||||
setValidBasalRateProfileSelectedOnPump(false);
|
||||
Notification n = new Notification(Notification.COMBO_PUMP_ALARM,
|
||||
MainApp.gs(R.string.combo_force_disabled_notification),
|
||||
Notification.URGENT);
|
||||
|
@ -945,6 +945,10 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf
|
|||
return commandResult;
|
||||
}
|
||||
|
||||
public void setValidBasalRateProfileSelectedOnPump(boolean value) {
|
||||
validBasalRateProfileSelectedOnPump = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the command result of running ReadPumpState if it wasn't successful, indicating
|
||||
* an error condition. Returns null otherwise.
|
||||
|
|
|
@ -0,0 +1,151 @@
|
|||
package info.nightscout.androidaps.interfaces;
|
||||
|
||||
import com.squareup.otto.Bus;
|
||||
|
||||
import junit.framework.Assert;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.powermock.api.mockito.PowerMockito;
|
||||
import org.powermock.core.classloader.annotations.PrepareForTest;
|
||||
import org.powermock.modules.junit4.PowerMockRunner;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.data.ConstraintChecker;
|
||||
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
||||
import info.nightscout.androidaps.plugins.ConstraintsObjectives.ObjectivesPlugin;
|
||||
import info.nightscout.androidaps.plugins.ConstraintsSafety.SafetyPlugin;
|
||||
import info.nightscout.androidaps.plugins.PumpCombo.ComboPlugin;
|
||||
import info.nightscout.androidaps.plugins.PumpVirtual.VirtualPumpPlugin;
|
||||
import info.nightscout.utils.FabricPrivacy;
|
||||
import info.nightscout.utils.SP;
|
||||
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
* Created by mike on 18.03.2018.
|
||||
*/
|
||||
@RunWith(PowerMockRunner.class)
|
||||
@PrepareForTest({MainApp.class, ConfigBuilderPlugin.class, FabricPrivacy.class, SP.class})
|
||||
public class ConstraintsCheckerTest {
|
||||
|
||||
PumpInterface pump = new VirtualPumpPlugin();
|
||||
ConstraintChecker constraintChecker;
|
||||
|
||||
ConfigBuilderPlugin configBuilderPlugin = mock(ConfigBuilderPlugin.class);
|
||||
MainApp mainApp = mock(MainApp.class);
|
||||
MockedBus bus = new MockedBus();
|
||||
//PumpDescription pumpDescription = new PumpDescription();
|
||||
|
||||
SafetyPlugin safetyPlugin;
|
||||
ObjectivesPlugin objectivesPlugin;
|
||||
ComboPlugin comboPlugin;
|
||||
|
||||
boolean notificationSent = false;
|
||||
|
||||
// isLoopInvokationAllowed tests
|
||||
@Test
|
||||
public void pumpDescriptionShouldLimitLoopInvokation() throws Exception {
|
||||
pump.getPumpDescription().isTempBasalCapable = false;
|
||||
|
||||
Constraint<Boolean> c = constraintChecker.isLoopInvokationAllowed();
|
||||
Assert.assertEquals(true, c.getReasons().contains("Pump is not temp basal capable"));
|
||||
Assert.assertEquals(Boolean.FALSE, c.get());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void notStartedObjectivesShouldLimitLoopInvokation() throws Exception {
|
||||
objectivesPlugin.objectives.get(0).setStarted(new Date(0));
|
||||
|
||||
Constraint<Boolean> c = constraintChecker.isLoopInvokationAllowed();
|
||||
Assert.assertEquals(true, c.getReasons().contains("Objective 1 not started"));
|
||||
Assert.assertEquals(Boolean.FALSE, c.get());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void invalidBasalRateOnComboPumpShouldLimitLoopInvokation() throws Exception {
|
||||
comboPlugin.setFragmentEnabled(PluginBase.PUMP, true);
|
||||
comboPlugin.setValidBasalRateProfileSelectedOnPump(false);
|
||||
|
||||
Constraint<Boolean> c = constraintChecker.isLoopInvokationAllowed();
|
||||
Assert.assertEquals(true, c.getReasons().contains("No valid basal rate read from pump"));
|
||||
Assert.assertEquals(Boolean.FALSE, c.get());
|
||||
}
|
||||
|
||||
// isClosedLoopAllowed tests
|
||||
@Test
|
||||
public void disabledEngineeringModeShouldLimitClosedLoop() throws Exception {
|
||||
when(SP.getString("aps_mode", "open")).thenReturn("closed");
|
||||
when(MainApp.isEngineeringModeOrRelease()).thenReturn(false);
|
||||
|
||||
Constraint<Boolean> c = constraintChecker.isClosedLoopAllowed();
|
||||
Assert.assertEquals(true, c.getReasons().contains("Running dev version. Closed loop is disabled."));
|
||||
Assert.assertEquals(Boolean.FALSE, c.get());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setOpenLoopInPreferencesShouldLimitClosedLoop() throws Exception {
|
||||
when(SP.getString("aps_mode", "open")).thenReturn("open");
|
||||
|
||||
Constraint<Boolean> c = constraintChecker.isClosedLoopAllowed();
|
||||
Assert.assertEquals(true, c.getReasons().contains("Closed loop mode disabled in preferences"));
|
||||
Assert.assertEquals(Boolean.FALSE, c.get());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void notStartedObjective4ShouldLimitClosedLoop() throws Exception {
|
||||
when(SP.getString("aps_mode", "open")).thenReturn("closed");
|
||||
objectivesPlugin.objectives.get(3).setStarted(new Date(0));
|
||||
|
||||
Constraint<Boolean> c = constraintChecker.isClosedLoopAllowed();
|
||||
Assert.assertEquals(true, c.getReasons().contains("Objective 4 not started"));
|
||||
Assert.assertEquals(Boolean.FALSE, c.get());
|
||||
}
|
||||
|
||||
@Before
|
||||
public void prepareMock() throws Exception {
|
||||
PowerMockito.mockStatic(ConfigBuilderPlugin.class);
|
||||
|
||||
PowerMockito.mockStatic(MainApp.class);
|
||||
when(MainApp.instance()).thenReturn(mainApp);
|
||||
when(MainApp.getConfigBuilder()).thenReturn(configBuilderPlugin);
|
||||
when(MainApp.getConfigBuilder().getActivePump()).thenReturn(pump);
|
||||
|
||||
constraintChecker = new ConstraintChecker(mainApp);
|
||||
|
||||
PowerMockito.mockStatic(FabricPrivacy.class);
|
||||
|
||||
when(MainApp.bus()).thenReturn(bus);
|
||||
|
||||
when(MainApp.gs(R.string.pumpisnottempbasalcapable)).thenReturn("Pump is not temp basal capable");
|
||||
when(MainApp.gs(R.string.closed_loop_disabled_on_dev_branch)).thenReturn("Running dev version. Closed loop is disabled.");
|
||||
when(MainApp.gs(R.string.closedmodedisabledinpreferences)).thenReturn("Closed loop mode disabled in preferences");
|
||||
when(MainApp.gs(R.string.objectivenotstarted)).thenReturn("Objective %d not started");
|
||||
when(MainApp.gs(R.string.novalidbasalrate)).thenReturn("No valid basal rate read from pump");
|
||||
|
||||
safetyPlugin = SafetyPlugin.getPlugin();
|
||||
objectivesPlugin = ObjectivesPlugin.getPlugin();
|
||||
comboPlugin = ComboPlugin.getPlugin();
|
||||
ArrayList<PluginBase> constraintsPluginsList = new ArrayList<>();
|
||||
constraintsPluginsList.add(safetyPlugin);
|
||||
constraintsPluginsList.add(objectivesPlugin);
|
||||
constraintsPluginsList.add(comboPlugin);
|
||||
when(mainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class)).thenReturn(constraintsPluginsList);
|
||||
|
||||
PowerMockito.mockStatic(SP.class);
|
||||
}
|
||||
|
||||
class MockedBus extends Bus {
|
||||
@Override
|
||||
public void post(Object event) {
|
||||
notificationSent = true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in a new issue