NSClientV3PluginTest

This commit is contained in:
Milos Kozak 2023-01-04 15:41:04 +01:00
parent d190b53713
commit eb1fff54f1
7 changed files with 137 additions and 33 deletions

View file

@ -46,6 +46,6 @@ interface NsClient : Sync {
fun resetToFullSync() fun resetToFullSync()
fun dbAdd(collection: String, dataPair: DataSyncSelector.DataPair, progress: String) fun nsAdd(collection: String, dataPair: DataSyncSelector.DataPair, progress: String)
fun dbUpdate(collection: String, dataPair: DataSyncSelector.DataPair, progress: String) fun nsUpdate(collection: String, dataPair: DataSyncSelector.DataPair, progress: String)
} }

View file

@ -26,6 +26,7 @@ dependencies {
implementation project(':core:utils') implementation project(':core:utils')
implementation project(':core:validators') implementation project(':core:validators')
testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:$coroutines_version"
testImplementation "androidx.work:work-testing:$work_version" testImplementation "androidx.work:work-testing:$work_version"
testImplementation project(':implementation') testImplementation project(':implementation')
testImplementation project(':plugins:aps') testImplementation project(':plugins:aps')

View file

@ -135,14 +135,14 @@ class DataSyncSelectorImplementation @Inject constructor(
} }
// without nsId = create new // without nsId = create new
bolus.first.interfaceIDs.nightscoutId == null -> bolus.first.interfaceIDs.nightscoutId == null ->
activePlugin.activeNsClient?.dbAdd( activePlugin.activeNsClient?.nsAdd(
"treatments", "treatments",
DataSyncSelector.PairBolus(bolus.first, bolus.second.id), DataSyncSelector.PairBolus(bolus.first, bolus.second.id),
" $startId/$lastDbId" " $startId/$lastDbId"
) )
// with nsId = update if it's modified record // with nsId = update if it's modified record
bolus.first.interfaceIDs.nightscoutId != null && bolus.first.id != bolus.second.id -> bolus.first.interfaceIDs.nightscoutId != null && bolus.first.id != bolus.second.id ->
activePlugin.activeNsClient?.dbUpdate( activePlugin.activeNsClient?.nsUpdate(
"treatments", "treatments",
DataSyncSelector.PairBolus(bolus.first, bolus.second.id), DataSyncSelector.PairBolus(bolus.first, bolus.second.id),
"$startId/$lastDbId" "$startId/$lastDbId"
@ -188,10 +188,10 @@ class DataSyncSelectorImplementation @Inject constructor(
} }
// without nsId = create new // without nsId = create new
carb.first.interfaceIDs.nightscoutId == null -> carb.first.interfaceIDs.nightscoutId == null ->
activePlugin.activeNsClient?.dbAdd("treatments", DataSyncSelector.PairCarbs(carb.first, carb.second.id), "$startId/$lastDbId") activePlugin.activeNsClient?.nsAdd("treatments", DataSyncSelector.PairCarbs(carb.first, carb.second.id), "$startId/$lastDbId")
// with nsId = update if it's modified record // with nsId = update if it's modified record
carb.first.interfaceIDs.nightscoutId != null && carb.first.id != carb.second.id -> carb.first.interfaceIDs.nightscoutId != null && carb.first.id != carb.second.id ->
activePlugin.activeNsClient?.dbUpdate( activePlugin.activeNsClient?.nsUpdate(
"treatments", "treatments",
DataSyncSelector.PairCarbs(carb.first, carb.second.id), DataSyncSelector.PairCarbs(carb.first, carb.second.id),
"$startId/$lastDbId" "$startId/$lastDbId"
@ -237,14 +237,14 @@ class DataSyncSelectorImplementation @Inject constructor(
} }
// without nsId = create new // without nsId = create new
bolusCalculatorResult.first.interfaceIDs.nightscoutId == null -> bolusCalculatorResult.first.interfaceIDs.nightscoutId == null ->
activePlugin.activeNsClient?.dbAdd( activePlugin.activeNsClient?.nsAdd(
"treatments", "treatments",
DataSyncSelector.PairBolusCalculatorResult(bolusCalculatorResult.first, bolusCalculatorResult.second.id), DataSyncSelector.PairBolusCalculatorResult(bolusCalculatorResult.first, bolusCalculatorResult.second.id),
"$startId/$lastDbId" "$startId/$lastDbId"
) )
// with nsId = update if it's modified record // with nsId = update if it's modified record
bolusCalculatorResult.first.interfaceIDs.nightscoutId != null && bolusCalculatorResult.first.id != bolusCalculatorResult.second.id -> bolusCalculatorResult.first.interfaceIDs.nightscoutId != null && bolusCalculatorResult.first.id != bolusCalculatorResult.second.id ->
activePlugin.activeNsClient?.dbUpdate( activePlugin.activeNsClient?.nsUpdate(
"treatments", "treatments",
DataSyncSelector.PairBolusCalculatorResult(bolusCalculatorResult.first, bolusCalculatorResult.second.id), "$startId/$lastDbId" DataSyncSelector.PairBolusCalculatorResult(bolusCalculatorResult.first, bolusCalculatorResult.second.id), "$startId/$lastDbId"
) )
@ -289,14 +289,14 @@ class DataSyncSelectorImplementation @Inject constructor(
} }
// without nsId = create new // without nsId = create new
tt.first.interfaceIDs.nightscoutId == null -> tt.first.interfaceIDs.nightscoutId == null ->
activePlugin.activeNsClient?.dbAdd( activePlugin.activeNsClient?.nsAdd(
"treatments", "treatments",
DataSyncSelector.PairTemporaryTarget(tt.first, tt.second.id), DataSyncSelector.PairTemporaryTarget(tt.first, tt.second.id),
"$startId/$lastDbId" "$startId/$lastDbId"
) )
// existing with nsId = update // existing with nsId = update
tt.first.interfaceIDs.nightscoutId != null -> tt.first.interfaceIDs.nightscoutId != null ->
activePlugin.activeNsClient?.dbUpdate( activePlugin.activeNsClient?.nsUpdate(
"treatments", "treatments",
DataSyncSelector.PairTemporaryTarget(tt.first, tt.second.id), DataSyncSelector.PairTemporaryTarget(tt.first, tt.second.id),
"$startId/$lastDbId" "$startId/$lastDbId"
@ -342,10 +342,10 @@ class DataSyncSelectorImplementation @Inject constructor(
} }
// without nsId = create new // without nsId = create new
food.first.interfaceIDs.nightscoutId == null -> food.first.interfaceIDs.nightscoutId == null ->
activePlugin.activeNsClient?.dbAdd("food", DataSyncSelector.PairFood(food.first, food.second.id), "$startId/$lastDbId") activePlugin.activeNsClient?.nsAdd("food", DataSyncSelector.PairFood(food.first, food.second.id), "$startId/$lastDbId")
// with nsId = update // with nsId = update
food.first.interfaceIDs.nightscoutId != null -> food.first.interfaceIDs.nightscoutId != null ->
activePlugin.activeNsClient?.dbUpdate( activePlugin.activeNsClient?.nsUpdate(
"food", "food",
DataSyncSelector.PairFood(food.first, food.second.id), DataSyncSelector.PairFood(food.first, food.second.id),
"$startId/$lastDbId" "$startId/$lastDbId"
@ -392,10 +392,10 @@ class DataSyncSelectorImplementation @Inject constructor(
} }
// without nsId = create new // without nsId = create new
gv.first.interfaceIDs.nightscoutId == null -> gv.first.interfaceIDs.nightscoutId == null ->
activePlugin.activeNsClient?.dbAdd("entries", DataSyncSelector.PairGlucoseValue(gv.first, gv.second.id), "$startId/$lastDbId") activePlugin.activeNsClient?.nsAdd("entries", DataSyncSelector.PairGlucoseValue(gv.first, gv.second.id), "$startId/$lastDbId")
// with nsId = update // with nsId = update
else -> // gv.first.interfaceIDs.nightscoutId != null else -> // gv.first.interfaceIDs.nightscoutId != null
activePlugin.activeNsClient?.dbUpdate( activePlugin.activeNsClient?.nsUpdate(
"entries", "entries",
DataSyncSelector.PairGlucoseValue(gv.first, gv.second.id), DataSyncSelector.PairGlucoseValue(gv.first, gv.second.id),
"$startId/$lastDbId" "$startId/$lastDbId"
@ -445,10 +445,10 @@ class DataSyncSelectorImplementation @Inject constructor(
} }
// without nsId = create new // without nsId = create new
te.first.interfaceIDs.nightscoutId == null -> te.first.interfaceIDs.nightscoutId == null ->
activePlugin.activeNsClient?.dbAdd("treatments", DataSyncSelector.PairTherapyEvent(te.first, te.second.id), "$startId/$lastDbId") activePlugin.activeNsClient?.nsAdd("treatments", DataSyncSelector.PairTherapyEvent(te.first, te.second.id), "$startId/$lastDbId")
// nsId = update // nsId = update
te.first.interfaceIDs.nightscoutId != null -> te.first.interfaceIDs.nightscoutId != null ->
activePlugin.activeNsClient?.dbUpdate( activePlugin.activeNsClient?.nsUpdate(
"treatments", "treatments",
DataSyncSelector.PairTherapyEvent(te.first, te.second.id), DataSyncSelector.PairTherapyEvent(te.first, te.second.id),
"$startId/$lastDbId" "$startId/$lastDbId"
@ -480,7 +480,7 @@ class DataSyncSelectorImplementation @Inject constructor(
when { when {
// without nsId = create new // without nsId = create new
deviceStatus.interfaceIDs.nightscoutId == null -> deviceStatus.interfaceIDs.nightscoutId == null ->
activePlugin.activeNsClient?.dbAdd("devicestatus", DataSyncSelector.PairDeviceStatus(deviceStatus, 0), "$startId/$lastDbId") activePlugin.activeNsClient?.nsAdd("devicestatus", DataSyncSelector.PairDeviceStatus(deviceStatus, 0), "$startId/$lastDbId")
// with nsId = ignore // with nsId = ignore
deviceStatus.interfaceIDs.nightscoutId != null -> Any() deviceStatus.interfaceIDs.nightscoutId != null -> Any()
} }
@ -524,14 +524,14 @@ class DataSyncSelectorImplementation @Inject constructor(
} }
// without nsId = create new // without nsId = create new
tb.first.interfaceIDs.nightscoutId == null -> tb.first.interfaceIDs.nightscoutId == null ->
activePlugin.activeNsClient?.dbAdd( activePlugin.activeNsClient?.nsAdd(
"treatments", "treatments",
DataSyncSelector.PairTemporaryBasal(tb.first, tb.second.id), DataSyncSelector.PairTemporaryBasal(tb.first, tb.second.id),
"$startId/$lastDbId" "$startId/$lastDbId"
) )
// with nsId = update // with nsId = update
tb.first.interfaceIDs.nightscoutId != null -> tb.first.interfaceIDs.nightscoutId != null ->
activePlugin.activeNsClient?.dbUpdate( activePlugin.activeNsClient?.nsUpdate(
"treatments", "treatments",
DataSyncSelector.PairTemporaryBasal(tb.first, tb.second.id), DataSyncSelector.PairTemporaryBasal(tb.first, tb.second.id),
"$startId/$lastDbId" "$startId/$lastDbId"
@ -579,14 +579,14 @@ class DataSyncSelectorImplementation @Inject constructor(
} }
// without nsId = create new // without nsId = create new
eb.first.interfaceIDs.nightscoutId == null -> eb.first.interfaceIDs.nightscoutId == null ->
activePlugin.activeNsClient?.dbAdd( activePlugin.activeNsClient?.nsAdd(
"treatments", "treatments",
DataSyncSelector.PairExtendedBolus(eb.first, eb.second.id), DataSyncSelector.PairExtendedBolus(eb.first, eb.second.id),
"$startId/$lastDbId" "$startId/$lastDbId"
) )
// with nsId = update // with nsId = update
eb.first.interfaceIDs.nightscoutId != null -> eb.first.interfaceIDs.nightscoutId != null ->
activePlugin.activeNsClient?.dbUpdate( activePlugin.activeNsClient?.nsUpdate(
"treatments", "treatments",
DataSyncSelector.PairExtendedBolus(eb.first, eb.second.id), DataSyncSelector.PairExtendedBolus(eb.first, eb.second.id),
"$startId/$lastDbId" "$startId/$lastDbId"
@ -638,10 +638,10 @@ class DataSyncSelectorImplementation @Inject constructor(
} }
// without nsId = create new // without nsId = create new
ps.first.interfaceIDs.nightscoutId == null -> ps.first.interfaceIDs.nightscoutId == null ->
activePlugin.activeNsClient?.dbAdd("treatments", DataSyncSelector.PairProfileSwitch(ps.first, ps.second.id), "$startId/$lastDbId") activePlugin.activeNsClient?.nsAdd("treatments", DataSyncSelector.PairProfileSwitch(ps.first, ps.second.id), "$startId/$lastDbId")
// with nsId = update // with nsId = update
ps.first.interfaceIDs.nightscoutId != null -> ps.first.interfaceIDs.nightscoutId != null ->
activePlugin.activeNsClient?.dbUpdate( activePlugin.activeNsClient?.nsUpdate(
"treatments", "treatments",
DataSyncSelector.PairProfileSwitch(ps.first, ps.second.id), DataSyncSelector.PairProfileSwitch(ps.first, ps.second.id),
"$startId/$lastDbId" "$startId/$lastDbId"
@ -687,14 +687,14 @@ class DataSyncSelectorImplementation @Inject constructor(
} }
// without nsId = create new // without nsId = create new
ps.first.interfaceIDs.nightscoutId == null -> ps.first.interfaceIDs.nightscoutId == null ->
activePlugin.activeNsClient?.dbAdd( activePlugin.activeNsClient?.nsAdd(
"treatments", "treatments",
DataSyncSelector.PairEffectiveProfileSwitch(ps.first, ps.second.id), DataSyncSelector.PairEffectiveProfileSwitch(ps.first, ps.second.id),
"$startId/$lastDbId" "$startId/$lastDbId"
) )
// with nsId = update // with nsId = update
ps.first.interfaceIDs.nightscoutId != null -> ps.first.interfaceIDs.nightscoutId != null ->
activePlugin.activeNsClient?.dbUpdate( activePlugin.activeNsClient?.nsUpdate(
"treatments", "treatments",
DataSyncSelector.PairEffectiveProfileSwitch(ps.first, ps.second.id), DataSyncSelector.PairEffectiveProfileSwitch(ps.first, ps.second.id),
"$startId/$lastDbId" "$startId/$lastDbId"
@ -740,10 +740,10 @@ class DataSyncSelectorImplementation @Inject constructor(
} }
// without nsId = create new // without nsId = create new
oe.first.interfaceIDs.nightscoutId == null -> oe.first.interfaceIDs.nightscoutId == null ->
activePlugin.activeNsClient?.dbAdd("treatments", DataSyncSelector.PairOfflineEvent(oe.first, oe.second.id), "$startId/$lastDbId") activePlugin.activeNsClient?.nsAdd("treatments", DataSyncSelector.PairOfflineEvent(oe.first, oe.second.id), "$startId/$lastDbId")
// existing with nsId = update // existing with nsId = update
oe.first.interfaceIDs.nightscoutId != null -> oe.first.interfaceIDs.nightscoutId != null ->
activePlugin.activeNsClient?.dbUpdate( activePlugin.activeNsClient?.nsUpdate(
"treatments", "treatments",
DataSyncSelector.PairOfflineEvent(oe.first, oe.second.id), DataSyncSelector.PairOfflineEvent(oe.first, oe.second.id),
"$startId/$lastDbId" "$startId/$lastDbId"
@ -765,7 +765,7 @@ class DataSyncSelectorImplementation @Inject constructor(
if (lastChange > lastSync) { if (lastChange > lastSync) {
if (activePlugin.activeProfileSource.profile?.allProfilesValid != true) return if (activePlugin.activeProfileSource.profile?.allProfilesValid != true) return
val profileJson = activePlugin.activeProfileSource.profile?.data ?: return val profileJson = activePlugin.activeProfileSource.profile?.data ?: return
activePlugin.activeNsClient?.dbAdd("profile", DataSyncSelector.PairProfileStore(profileJson, dateUtil.now()), "") activePlugin.activeNsClient?.nsAdd("profile", DataSyncSelector.PairProfileStore(profileJson, dateUtil.now()), "")
} }
} }
} }

View file

@ -244,7 +244,7 @@ class NSClientPlugin @Inject constructor(
dataSyncSelector.resetToNextFullSync() dataSyncSelector.resetToNextFullSync()
} }
override fun dbAdd(collection: String, dataPair: DataSyncSelector.DataPair, progress: String) { override fun nsAdd(collection: String, dataPair: DataSyncSelector.DataPair, progress: String) {
when (dataPair) { when (dataPair) {
is DataSyncSelector.PairBolus -> dataPair.value.toJson(true, dateUtil) is DataSyncSelector.PairBolus -> dataPair.value.toJson(true, dateUtil)
is DataSyncSelector.PairCarbs -> dataPair.value.toJson(true, dateUtil) is DataSyncSelector.PairCarbs -> dataPair.value.toJson(true, dateUtil)
@ -266,7 +266,7 @@ class NSClientPlugin @Inject constructor(
} }
} }
override fun dbUpdate(collection: String, dataPair: DataSyncSelector.DataPair, progress: String) { override fun nsUpdate(collection: String, dataPair: DataSyncSelector.DataPair, progress: String) {
val id = when (dataPair) { val id = when (dataPair) {
is DataSyncSelector.PairBolus -> dataPair.value.interfaceIDs.nightscoutId is DataSyncSelector.PairBolus -> dataPair.value.interfaceIDs.nightscoutId
is DataSyncSelector.PairCarbs -> dataPair.value.interfaceIDs.nightscoutId is DataSyncSelector.PairCarbs -> dataPair.value.interfaceIDs.nightscoutId

View file

@ -1,5 +1,6 @@
package info.nightscout.plugins.sync.nsclient package info.nightscout.plugins.sync.nsclient
import info.nightscout.androidaps.annotations.OpenForTesting
import info.nightscout.interfaces.receivers.ReceiverStatusStore import info.nightscout.interfaces.receivers.ReceiverStatusStore
import info.nightscout.plugins.sync.R import info.nightscout.plugins.sync.R
import info.nightscout.rx.bus.RxBus import info.nightscout.rx.bus.RxBus
@ -11,6 +12,7 @@ import info.nightscout.shared.sharedPreferences.SP
import javax.inject.Inject import javax.inject.Inject
import javax.inject.Singleton import javax.inject.Singleton
@OpenForTesting
@Singleton @Singleton
class NsClientReceiverDelegate @Inject constructor( class NsClientReceiverDelegate @Inject constructor(
private val rxBus: RxBus, private val rxBus: RxBus,

View file

@ -120,7 +120,7 @@ class NSClientV3Plugin @Inject constructor(
} }
private val disposable = CompositeDisposable() private val disposable = CompositeDisposable()
private val scope = CoroutineScope(Dispatchers.IO + SupervisorJob()) var scope = CoroutineScope(Dispatchers.IO + SupervisorJob())
private lateinit var runLoop: Runnable private lateinit var runLoop: Runnable
private val handler = Handler(HandlerThread(this::class.simpleName + "Handler").also { it.start() }.looper) private val handler = Handler(HandlerThread(this::class.simpleName + "Handler").also { it.start() }.looper)
private val listLog: MutableList<EventNSClientNewLog> = ArrayList() private val listLog: MutableList<EventNSClientNewLog> = ArrayList()
@ -320,11 +320,11 @@ class NSClientV3Plugin @Inject constructor(
storeLastLoadedSrvModified() storeLastLoadedSrvModified()
} }
override fun dbAdd(collection: String, dataPair: DataSyncSelector.DataPair, progress: String) { override fun nsAdd(collection: String, dataPair: DataSyncSelector.DataPair, progress: String) {
dbOperation(collection, dataPair, progress, Operation.CREATE) dbOperation(collection, dataPair, progress, Operation.CREATE)
} }
override fun dbUpdate(collection: String, dataPair: DataSyncSelector.DataPair, progress: String) { override fun nsUpdate(collection: String, dataPair: DataSyncSelector.DataPair, progress: String) {
dbOperation(collection, dataPair, progress, Operation.UPDATE) dbOperation(collection, dataPair, progress, Operation.UPDATE)
} }

View file

@ -0,0 +1,101 @@
package info.nightscout.plugins.sync.nsclientV3
import android.content.Context
import dagger.android.AndroidInjector
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.TestBase
import info.nightscout.core.utils.fabric.FabricPrivacy
import info.nightscout.database.entities.DeviceStatus
import info.nightscout.database.impl.AppRepository
import info.nightscout.interfaces.Config
import info.nightscout.interfaces.XDripBroadcast
import info.nightscout.interfaces.logging.UserEntryLogger
import info.nightscout.interfaces.nsclient.StoreDataForDb
import info.nightscout.interfaces.profile.ProfileFunction
import info.nightscout.interfaces.pump.VirtualPump
import info.nightscout.interfaces.source.NSClientSource
import info.nightscout.interfaces.sync.DataSyncSelector
import info.nightscout.interfaces.ui.UiInteraction
import info.nightscout.plugins.sync.nsShared.StoreDataForDbImpl
import info.nightscout.plugins.sync.nsclient.NsClientReceiverDelegate
import info.nightscout.rx.bus.RxBus
import info.nightscout.sdk.interfaces.NSAndroidClient
import info.nightscout.sdk.localmodel.treatment.CreateUpdateResponse
import info.nightscout.shared.interfaces.ResourceHelper
import info.nightscout.shared.sharedPreferences.SP
import info.nightscout.shared.utils.DateUtil
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.test.UnconfinedTestDispatcher
import kotlinx.coroutines.test.runTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.mockito.Mock
import org.mockito.Mockito.verify
import org.mockito.Mockito.`when`
import org.mockito.internal.verification.Times
@Suppress("SpellCheckingInspection")
internal class NSClientV3PluginTest : TestBase() {
@Mock lateinit var rxBus: RxBus
@Mock lateinit var rh: ResourceHelper
@Mock lateinit var context: Context
@Mock lateinit var fabricPrivacy: FabricPrivacy
@Mock lateinit var sp: SP
@Mock lateinit var nsClientReceiverDelegate: NsClientReceiverDelegate
@Mock lateinit var config: Config
@Mock lateinit var dateUtil: DateUtil
@Mock lateinit var uiInteraction: UiInteraction
@Mock lateinit var dataSyncSelector: DataSyncSelector
@Mock lateinit var profileFunction: ProfileFunction
@Mock lateinit var nsAndroidClient: NSAndroidClient
@Mock lateinit var repository: AppRepository
@Mock lateinit var uel: UserEntryLogger
@Mock lateinit var nsClientSource: NSClientSource
@Mock lateinit var xDripBroadcast: XDripBroadcast
@Mock lateinit var virtualPump: VirtualPump
private lateinit var storeDataForDb: StoreDataForDb
private lateinit var sut: NSClientV3Plugin
private val injector = HasAndroidInjector {
AndroidInjector {
}
}
@BeforeEach
fun prepare() {
storeDataForDb = StoreDataForDbImpl(aapsLogger, rxBus, repository, sp, uel, dateUtil, config, nsClientSource, xDripBroadcast, virtualPump, uiInteraction)
sut =
NSClientV3Plugin(
injector, aapsLogger, aapsSchedulers, rxBus, rh, context, fabricPrivacy,
sp, nsClientReceiverDelegate, config, dateUtil, uiInteraction, storeDataForDb, dataSyncSelector, profileFunction
)
sut.nsAndroidClient = nsAndroidClient
}
@Test
@OptIn(kotlinx.coroutines.ExperimentalCoroutinesApi::class)
fun nsAddDeviceStatus() = runTest {
sut.scope = CoroutineScope(UnconfinedTestDispatcher(testScheduler))
val deviceStatus = DeviceStatus(
timestamp = 10000,
suggested = "{\"temp\":\"absolute\",\"bg\":133,\"tick\":-6,\"eventualBG\":67,\"targetBG\":99,\"insulinReq\":0,\"deliverAt\":\"2023-01-02T15:29:33.374Z\",\"sensitivityRatio\":1,\"variable_sens\":97.5,\"predBGs\":{\"IOB\":[133,127,121,116,111,106,101,97,93,89,85,81,78,75,72,69,67,65,62,60,58,57,55,54,52,51,50,49,48,47,46,45,45,44,43,43,42,42,41,41,41,41,40,40,40,40,39],\"ZT\":[133,127,121,115,110,105,101,96,92,88,84,81,77,74,71,69,66,64,62,59,58,56,54,53,51,50,49,48,47,46,45,44,44,43,42,42,41,41,40,40,40,39,39,39,39,39,39,39],\"UAM\":[133,127,121,115,110,105,101,96,92,88,84,81,77,74,71,69,66,64,62,59,58,56,54,53,51,50,49,48,47,46,45,44,44,43,42,42,41,41,40,40,40,39]},\"reason\":\"COB: 0, Dev: 0.1, BGI: -0.3, ISF: 5.4, CR: 13, Target: 5.5, minPredBG 2.2, minGuardBG 2.1, IOBpredBG 2.2, UAMpredBG 2.2; minGuardBG 2.1<4.0\",\"COB\":0,\"IOB\":0.692,\"duration\":90,\"rate\":0,\"timestamp\":\"2023-01-02T15:29:39.460Z\"}",
iob = "{\"iob\":0.692,\"basaliob\":-0.411,\"activity\":0.0126,\"time\":\"2023-01-02T15:29:39.460Z\"}",
enacted = "{\"temp\":\"absolute\",\"bg\":133,\"tick\":-6,\"eventualBG\":67,\"targetBG\":99,\"insulinReq\":0,\"deliverAt\":\"2023-01-02T15:29:33.374Z\",\"sensitivityRatio\":1,\"variable_sens\":97.5,\"predBGs\":{\"IOB\":[133,127,121,116,111,106,101,97,93,89,85,81,78,75,72,69,67,65,62,60,58,57,55,54,52,51,50,49,48,47,46,45,45,44,43,43,42,42,41,41,41,41,40,40,40,40,39],\"ZT\":[133,127,121,115,110,105,101,96,92,88,84,81,77,74,71,69,66,64,62,59,58,56,54,53,51,50,49,48,47,46,45,44,44,43,42,42,41,41,40,40,40,39,39,39,39,39,39,39],\"UAM\":[133,127,121,115,110,105,101,96,92,88,84,81,77,74,71,69,66,64,62,59,58,56,54,53,51,50,49,48,47,46,45,44,44,43,42,42,41,41,40,40,40,39]},\"reason\":\"COB: 0, Dev: 0.1, BGI: -0.3, ISF: 5.4, CR: 13, Target: 5.5, minPredBG 2.2, minGuardBG 2.1, IOBpredBG 2.2, UAMpredBG 2.2; minGuardBG 2.1<4.0\",\"COB\":0,\"IOB\":0.692,\"duration\":90,\"rate\":0,\"timestamp\":\"2023-01-02T15:29:39.460Z\"}",
device = "openaps://samsung SM-G970F",
pump = "{\"battery\":{\"percent\":75},\"status\":{\"status\":\"normal\",\"timestamp\":\"2023-01-02T15:20:20.656Z\"},\"extended\":{\"Version\":\"3.1.0.3-dev-e-295e1ad18f-2022.12.24\"," +
"\"LastBolus\":\"02.01.23 15:24\",\"LastBolusAmount\":\"1\",\"TempBasalAbsoluteRate\":\"0\",\"TempBasalStart\":\"02.01.23 16:20\",\"TempBasalRemaining\":\"55\",\"BaseBasalRate\":\"0" +
".41\",\"ActiveProfile\":\"L29_U200 IC\"},\"reservoir\":\"133\",\"clock\":\"2023-01-02T15:25:05.826Z\"}",
uploaderBattery = 60,
configuration = "{\"insulin\":5,\"insulinConfiguration\":{},\"sensitivity\":2,\"sensitivityConfiguration\":{\"openapsama_min_5m_carbimpact\":8,\"absorption_cutoff\":4,\"autosens_max\":1.2,\"autosens_min\":0.7},\"overviewConfiguration\":{\"units\":\"mmol\",\"QuickWizard\":\"[]\",\"eatingsoon_duration\":60,\"eatingsoon_target\":4,\"activity_duration\":180,\"activity_target\":7.5,\"hypo_duration\":90,\"hypo_target\":8,\"low_mark\":3.9,\"high_mark\":10,\"statuslights_cage_warning\":72,\"statuslights_cage_critical\":96,\"statuslights_iage_warning\":120,\"statuslights_iage_critical\":150,\"statuslights_sage_warning\":168,\"statuslights_sage_critical\":336,\"statuslights_sbat_warning\":25,\"statuslights_sbat_critical\":5,\"statuslights_bage_warning\":720,\"statuslights_bage_critical\":800,\"statuslights_res_warning\":30,\"statuslights_res_critical\":10,\"statuslights_bat_warning\":50,\"statuslights_bat_critical\":25,\"boluswizard_percentage\":70},\"safetyConfiguration\":{\"age\":\"resistantadult\",\"treatmentssafety_maxbolus\":10,\"treatmentssafety_maxcarbs\":70}}"
)
val dataPair = DataSyncSelector.PairDeviceStatus(deviceStatus, 1000)
`when`(nsAndroidClient.createDeviceStatus(anyObject())).thenReturn(CreateUpdateResponse(201, null))
sut.nsAdd("devicestatus", dataPair, "1/3")
Assertions.assertEquals(1, storeDataForDb.nsIdDeviceStatuses.size)
verify(dataSyncSelector, Times(1)).confirmLastDeviceStatusIdIfGreater(1000)
verify(dataSyncSelector, Times(1)).processChangedDeviceStatusesCompat()
}
}