Skip to content

Commit dac31aa

Browse files
committed
Move remote command parsing and validation to RemoteDataService
1 parent db2ef8d commit dac31aa

File tree

5 files changed

+31
-229
lines changed

5 files changed

+31
-229
lines changed

Loop.xcodeproj/project.pbxproj

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -418,7 +418,6 @@
418418
A9DF02CB24F72B9E00B7C988 /* CriticalEventLogTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9DF02CA24F72B9E00B7C988 /* CriticalEventLogTests.swift */; };
419419
A9DFAFB324F0415E00950D1E /* CarbBackfillRequestUserInfoTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9DFAFB224F0415E00950D1E /* CarbBackfillRequestUserInfoTests.swift */; };
420420
A9DFAFB524F048A000950D1E /* WatchHistoricalCarbsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9DFAFB424F048A000950D1E /* WatchHistoricalCarbsTests.swift */; };
421-
A9E8A80528A7CAC000C0A8A4 /* RemoteCommandTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9E8A80428A7CAC000C0A8A4 /* RemoteCommandTests.swift */; };
422421
A9F5F1F5251050EC00E7C8A4 /* ZipArchiveTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9F5F1F4251050EC00E7C8A4 /* ZipArchiveTests.swift */; };
423422
A9F66FC3247F451500096EA7 /* UIDevice+Loop.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9F66FC2247F451500096EA7 /* UIDevice+Loop.swift */; };
424423
A9F703732489BC8500C98AD8 /* CarbStore+SimulatedCoreData.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9F703722489BC8500C98AD8 /* CarbStore+SimulatedCoreData.swift */; };
@@ -492,7 +491,6 @@
492491
C16575752539FD60004AE16E /* LoopCoreConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = C16575742539FD60004AE16E /* LoopCoreConstants.swift */; };
493492
C16575762539FEF3004AE16E /* LoopCoreConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = C16575742539FD60004AE16E /* LoopCoreConstants.swift */; };
494493
C1657578253A0021004AE16E /* ChartConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1657577253A0021004AE16E /* ChartConstants.swift */; };
495-
C165B8CE23302C5D0004112E /* RemoteCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = C165B8CD23302C5D0004112E /* RemoteCommand.swift */; };
496494
C16B983E26B4893300256B05 /* DoseEnactor.swift in Sources */ = {isa = PBXBuildFile; fileRef = C16B983D26B4893300256B05 /* DoseEnactor.swift */; };
497495
C16B984026B4898800256B05 /* DoseEnactorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C16B983F26B4898800256B05 /* DoseEnactorTests.swift */; };
498496
C16DA84222E8E112008624C2 /* PluginManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C16DA84122E8E112008624C2 /* PluginManager.swift */; };
@@ -1419,7 +1417,6 @@
14191417
A9DF02CA24F72B9E00B7C988 /* CriticalEventLogTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CriticalEventLogTests.swift; sourceTree = "<group>"; };
14201418
A9DFAFB224F0415E00950D1E /* CarbBackfillRequestUserInfoTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CarbBackfillRequestUserInfoTests.swift; sourceTree = "<group>"; };
14211419
A9DFAFB424F048A000950D1E /* WatchHistoricalCarbsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WatchHistoricalCarbsTests.swift; sourceTree = "<group>"; };
1422-
A9E8A80428A7CAC000C0A8A4 /* RemoteCommandTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RemoteCommandTests.swift; sourceTree = "<group>"; };
14231420
A9F5F1F4251050EC00E7C8A4 /* ZipArchiveTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ZipArchiveTests.swift; sourceTree = "<group>"; };
14241421
A9F66FC2247F451500096EA7 /* UIDevice+Loop.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIDevice+Loop.swift"; sourceTree = "<group>"; };
14251422
A9F703722489BC8500C98AD8 /* CarbStore+SimulatedCoreData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CarbStore+SimulatedCoreData.swift"; sourceTree = "<group>"; };
@@ -1568,7 +1565,6 @@
15681565
C16575722538AFF6004AE16E /* CGMStalenessMonitorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CGMStalenessMonitorTests.swift; sourceTree = "<group>"; };
15691566
C16575742539FD60004AE16E /* LoopCoreConstants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoopCoreConstants.swift; sourceTree = "<group>"; };
15701567
C1657577253A0021004AE16E /* ChartConstants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChartConstants.swift; sourceTree = "<group>"; };
1571-
C165B8CD23302C5D0004112E /* RemoteCommand.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RemoteCommand.swift; sourceTree = "<group>"; };
15721568
C16B983D26B4893300256B05 /* DoseEnactor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DoseEnactor.swift; sourceTree = "<group>"; };
15731569
C16B983F26B4898800256B05 /* DoseEnactorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DoseEnactorTests.swift; sourceTree = "<group>"; };
15741570
C16DA84122E8E112008624C2 /* PluginManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PluginManager.swift; sourceTree = "<group>"; };
@@ -2043,7 +2039,6 @@
20432039
A9B996EF27235191002DC09C /* LoopWarning.swift */,
20442040
4F526D601DF8D9A900A04910 /* NetBasal.swift */,
20452041
438D42F81D7C88BC003244B0 /* PredictionInputEffect.swift */,
2046-
C165B8CD23302C5D0004112E /* RemoteCommand.swift */,
20472042
4328E0311CFC068900E199AA /* WatchContext+LoopKit.swift */,
20482043
E9C00EF424C623EF00628F35 /* LoopSettings+Loop.swift */,
20492044
A987CD4824A58A0100439ADC /* ZipArchive.swift */,
@@ -2812,7 +2807,6 @@
28122807
A99A114A29A58789007919CE /* Remote */ = {
28132808
isa = PBXGroup;
28142809
children = (
2815-
A9E8A80428A7CAC000C0A8A4 /* RemoteCommandTests.swift */,
28162810
A99A114B29A5879C007919CE /* BolusActionTests.swift */,
28172811
A99A114C29A5879C007919CE /* CarbActionTests.swift */,
28182812
A99A114D29A5879C007919CE /* OverrideActionTests.swift */,
@@ -3842,7 +3836,6 @@
38423836
439BED2A1E76093C00B0AED5 /* CGMManager.swift in Sources */,
38433837
C16B983E26B4893300256B05 /* DoseEnactor.swift in Sources */,
38443838
E98A55EF24EDD6E60008715D /* DosingDecisionStoreProtocol.swift in Sources */,
3845-
C165B8CE23302C5D0004112E /* RemoteCommand.swift in Sources */,
38463839
B4001CEE28CBBC82002FB414 /* AlertManagementView.swift in Sources */,
38473840
E9C00EF524C623EF00628F35 /* LoopSettings+Loop.swift in Sources */,
38483841
4389916B1E91B689000EEF90 /* ChartSettings+Loop.swift in Sources */,
@@ -4161,7 +4154,6 @@
41614154
A96DAC2A2838EF8A00D94E38 /* DiagnosticLogTests.swift in Sources */,
41624155
A9DAE7D02332D77F006AE942 /* LoopTests.swift in Sources */,
41634156
E93E86B024DDE1BD00FF40C8 /* MockGlucoseStore.swift in Sources */,
4164-
A9E8A80528A7CAC000C0A8A4 /* RemoteCommandTests.swift in Sources */,
41654157
1DFE9E172447B6270082C280 /* UserNotificationAlertSchedulerTests.swift in Sources */,
41664158
B4BC56382518DEA900373647 /* CGMStatusHUDViewModelTests.swift in Sources */,
41674159
C1900900252271BB00721625 /* SimpleBolusCalculatorTests.swift in Sources */,

Loop/Managers/DeviceDataManager.swift

Lines changed: 15 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1372,81 +1372,56 @@ extension DeviceDataManager {
13721372
log.error("Remote Notification: Overrides not enabled.")
13731373
return
13741374
}
1375-
1376-
if let expirationStr = notification["expiration"] as? String {
1377-
let formatter = ISO8601DateFormatter()
1378-
formatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds]
1379-
if let expiration = formatter.date(from: expirationStr) {
1380-
let nowDate = Date()
1381-
guard nowDate < expiration else {
1382-
let expiredInterval = nowDate.timeIntervalSince(expiration)
1383-
await NotificationManager.sendRemoteCommandExpiredNotification(timeExpired: expiredInterval)
1384-
log.error("Remote Notification: Expired: %{public}@", String(describing: notification))
1385-
return
1386-
}
1387-
} else {
1388-
log.error("Remote Notification: Invalid expiration: %{public}@", expirationStr)
1389-
return
1390-
}
1391-
}
1392-
1393-
let action: Action
13941375

1376+
let command: RemoteCommand
13951377
do {
1396-
action = try RemoteCommand.createRemoteAction(notification: notification).get()
1378+
command = try await remoteDataServicesManager.commandFromPushNotification(notification)
13971379
} catch {
13981380
log.error("Remote Notification: Parse Error: %{public}@", String(describing: error))
13991381
return
14001382
}
14011383

1402-
log.default("Remote Notification: Handling action %{public}@", String(describing: action))
1384+
await handleRemoteCommand(command)
1385+
}
1386+
1387+
func handleRemoteCommand(_ command: RemoteCommand) async {
1388+
1389+
log.default("Remote Notification: Handling command %{public}@", String(describing: command))
14031390

1404-
switch action {
1391+
switch command.action {
14051392
case .temporaryScheduleOverride(let overrideAction):
14061393
do {
1394+
try command.validate()
14071395
try await handleOverrideAction(overrideAction)
14081396
} catch {
14091397
log.error("Remote Notification: Override Action Error: %{public}@", String(describing: error))
14101398
}
14111399
case .cancelTemporaryOverride(let overrideCancelAction):
14121400
do {
1401+
try command.validate()
14131402
try await handleOverrideCancelAction(overrideCancelAction)
14141403
} catch {
14151404
log.error("Remote Notification: Override Action Cancel Error: %{public}@", String(describing: error))
14161405
}
14171406
case .bolusEntry(let bolusAction):
14181407
do {
1419-
try validatePushNotificationSource(notification: notification)
1408+
try command.validate()
14201409
try await handleBolusAction(bolusAction)
14211410
} catch {
14221411
await NotificationManager.sendRemoteBolusFailureNotification(for: error, amount: bolusAction.amountInUnits)
1423-
log.error("Remote Notification: Bolus Action Error: %{public}@", String(describing: notification))
1412+
log.error("Remote Notification: Bolus Action Error: %{public}@", String(describing: error))
14241413
}
14251414
case .carbsEntry(let carbAction):
14261415
do {
1427-
try validatePushNotificationSource(notification: notification)
1416+
try command.validate()
14281417
try await handleCarbAction(carbAction)
14291418
} catch {
14301419
await NotificationManager.sendRemoteCarbEntryFailureNotification(for: error, amountInGrams: carbAction.amountInGrams)
1431-
log.error("Remote Notification: Carb Action Error: %{public}@", String(describing: notification))
1420+
log.error("Remote Notification: Carb Action Error: %{public}@", String(describing: error))
14321421
}
14331422
}
14341423
}
14351424

1436-
func validatePushNotificationSource(notification: [String: AnyObject]) throws {
1437-
1438-
let defaultServiceIdentifier = "NightscoutService"
1439-
let serviceIdentifer = notification["serviceIdentifier"] as? String ?? defaultServiceIdentifier
1440-
1441-
let validationResult = remoteDataServicesManager.validatePushNotificationSource(notification, serviceIdentifier: serviceIdentifer)
1442-
switch validationResult {
1443-
case .success():
1444-
log.info("Remote Notification: Validation successful")
1445-
case .failure(let error):
1446-
throw error
1447-
}
1448-
}
1449-
14501425
//Remote Overrides
14511426

14521427
func handleOverrideAction(_ action: OverrideAction) async throws {

Loop/Managers/RemoteDataServicesManager.swift

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -597,13 +597,11 @@ extension RemoteDataServicesManager {
597597

598598
extension RemoteDataServicesManager {
599599

600-
func validatePushNotificationSource(_ notification: [String: AnyObject], serviceIdentifier: String) -> Result<Void, Error> {
600+
func serviceForPushNotification(_ notification: [String: AnyObject]) -> RemoteDataService? {
601601

602-
guard let matchedService = remoteDataServices.first(where: {$0.serviceIdentifier == serviceIdentifier}) else {
603-
return .failure(PushNotificationValidationError.unsupportedService(serviceIdentifier: serviceIdentifier))
604-
}
605-
606-
return matchedService.validatePushNotificationSource(notification)
602+
let defaultServiceIdentifier = "NightscoutService"
603+
let serviceIdentifier = notification["serviceIdentifier"] as? String ?? defaultServiceIdentifier
604+
return remoteDataServices.first(where: {$0.serviceIdentifier == serviceIdentifier})
607605
}
608606

609607
public func temporaryScheduleOverrideHistoryDidUpdate() {
@@ -644,18 +642,22 @@ extension RemoteDataServicesManager {
644642
UserDefaults.appGroup?.deleteQueryAnchor(for: remoteDataService, withRemoteDataType: .overrides)
645643
}
646644
}
645+
}
646+
647+
extension RemoteDataServicesManager: RemoteCommandSource {
647648

648-
private enum PushNotificationValidationError: LocalizedError {
649-
case unsupportedService(serviceIdentifier: String)
649+
func commandFromPushNotification(_ notification: [String : AnyObject]) async throws -> RemoteCommand {
650650

651-
var errorDescription: String? {
652-
switch self {
653-
case .unsupportedService(let serviceIdentifier):
654-
return "Unsupported Loop service: \(serviceIdentifier)"
655-
}
651+
enum RemoteDataServicesManagerCommandError: LocalizedError {
652+
case missingNotificationService
656653
}
654+
655+
guard let service = serviceForPushNotification(notification) else {
656+
throw RemoteDataServicesManagerCommandError.missingNotificationService
657+
}
658+
659+
return try await service.commandFromPushNotification(notification)
657660
}
658-
659661
}
660662

661663

Loop/Models/RemoteCommand.swift

Lines changed: 0 additions & 59 deletions
This file was deleted.

LoopTests/Models/Remote/RemoteCommandTests.swift

Lines changed: 0 additions & 108 deletions
This file was deleted.

0 commit comments

Comments
 (0)