ReconciliationTests.swift 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. //
  2. // ReconciliationTests.swift
  3. // MinimedKitTests
  4. //
  5. // Created by Pete Schwamb on 9/5/22.
  6. // Copyright © 2022 LoopKit Authors. All rights reserved.
  7. //
  8. import XCTest
  9. import RileyLinkBLEKit
  10. @testable import MinimedKit
  11. import LoopKit
  12. extension DateFormatter {
  13. static var descriptionFormatter: DateFormatter {
  14. let formatter = self.init()
  15. formatter.dateFormat = "yyyy-MM-dd HH:mm:ssZZZZZ"
  16. return formatter
  17. }
  18. }
  19. final class ReconciliationTests: XCTestCase {
  20. let testingDateFormatter = DateFormatter.descriptionFormatter
  21. func testingDate(_ input: String) -> Date {
  22. return testingDateFormatter.date(from: input)!
  23. }
  24. func testPendingDoseUpdatesWithActualDeliveryFromHistoryDose() {
  25. let bolusTime = Date().addingTimeInterval(-TimeInterval(minutes: 5));
  26. let bolusEventTime = bolusTime.addingTimeInterval(2)
  27. let cancelTime = bolusEventTime.addingTimeInterval(TimeInterval(minutes: 1))
  28. let unfinalizedBolus = UnfinalizedDose(bolusAmount: 5.4, startTime: bolusTime, duration: TimeInterval(200), insulinType: .novolog, automatic: false, isReconciledWithHistory: false)
  29. // 5.4 bolus interrupted at 1.0 units
  30. let eventDose = DoseEntry(type: .bolus, startDate: bolusEventTime, endDate: cancelTime, value: unfinalizedBolus.units, unit: .units, deliveredUnits: 1.0)
  31. let bolusEvent = NewPumpEvent(
  32. date: bolusEventTime,
  33. dose: eventDose,
  34. raw: Data(hexadecimalString: "abcdef")!,
  35. title: "Test Bolus",
  36. type: .bolus)
  37. let result = MinimedPumpManager.reconcilePendingDosesWith([bolusEvent], reconciliationMappings: [:], pendingDoses: [unfinalizedBolus])
  38. // Should mark pending bolus as reconciled
  39. XCTAssertEqual(1, result.pendingDoses.count)
  40. let pendingBolus = result.pendingDoses.first!
  41. XCTAssertEqual(true, pendingBolus.isReconciledWithHistory)
  42. // Pending bolus should be updated with actual delivery amount
  43. XCTAssertEqual(1.0, pendingBolus.units)
  44. XCTAssertEqual(5.4, pendingBolus.programmedUnits)
  45. XCTAssertEqual(TimeInterval(minutes: 1), pendingBolus.duration)
  46. XCTAssertEqual(true, pendingBolus.isFinished)
  47. }
  48. func testReconciledDosesShouldOnlyAppearInReturnedPendingDoses() {
  49. let bolusTime = Date().addingTimeInterval(-TimeInterval(minutes: 5));
  50. // Shows up in history 2 seconds later
  51. let bolusEventTime = bolusTime.addingTimeInterval(2)
  52. let bolusAmount = 1.5
  53. let bolusDuration = PumpModel.model523.bolusDeliveryTime(units: bolusAmount)
  54. let unfinalizedBolus = UnfinalizedDose(bolusAmount: bolusAmount, startTime: bolusTime, duration: bolusDuration, insulinType: .novolog, automatic: false, isReconciledWithHistory: false)
  55. let eventDose = DoseEntry(type: .bolus, startDate: bolusEventTime, endDate: bolusEventTime.addingTimeInterval(bolusDuration), value: bolusAmount, unit: .units, deliveredUnits: bolusAmount)
  56. let bolusEvent = NewPumpEvent(
  57. date: bolusEventTime,
  58. dose: eventDose,
  59. raw: Data(hexadecimalString: "abcdef")!,
  60. title: "Test Bolus",
  61. type: .bolus)
  62. let result = MinimedPumpManager.reconcilePendingDosesWith([bolusEvent], reconciliationMappings: [:], pendingDoses: [unfinalizedBolus])
  63. // Should mark pending bolus as reconciled
  64. XCTAssertEqual(1, result.pendingDoses.count)
  65. let pendingBolus = result.pendingDoses.first!
  66. XCTAssertEqual(true, pendingBolus.isReconciledWithHistory)
  67. XCTAssertEqual(1, result.reconciliationMappings.count)
  68. XCTAssertEqual(unfinalizedBolus.uuid, result.reconciliationMappings[bolusEvent.raw]?.uuid)
  69. XCTAssertEqual(unfinalizedBolus.startTime, result.reconciliationMappings[bolusEvent.raw]?.startTime)
  70. // Bolus should not be returned as history event
  71. XCTAssert(result.remainingEvents.isEmpty)
  72. }
  73. func testReconciledDosesShouldNotAppearInReturnedPumpEvents() {
  74. let bolusTime = Date().addingTimeInterval(-TimeInterval(minutes: 5));
  75. // Shows up in history 2 seconds later
  76. let bolusEventTime = bolusTime.addingTimeInterval(2)
  77. let bolusAmount = 1.5
  78. let bolusDuration = PumpModel.model523.bolusDeliveryTime(units: bolusAmount)
  79. let eventDose = DoseEntry(type: .bolus, startDate: bolusEventTime, endDate: bolusEventTime.addingTimeInterval(bolusDuration), value: bolusAmount, unit: .units, deliveredUnits: bolusAmount)
  80. let bolusEvent = NewPumpEvent(
  81. date: bolusEventTime,
  82. dose: eventDose,
  83. raw: Data(hexadecimalString: "abcdef")!,
  84. title: "Test Bolus",
  85. type: .bolus)
  86. let reconciliationMappings: [Data:ReconciledDoseMapping] = [
  87. bolusEvent.raw : ReconciledDoseMapping(startTime: bolusTime, uuid: UUID(), eventRaw: bolusEvent.raw)
  88. ]
  89. let result = MinimedPumpManager.reconcilePendingDosesWith([bolusEvent], reconciliationMappings: reconciliationMappings, pendingDoses: [])
  90. // Bolus should not be returned as history event
  91. XCTAssert(result.remainingEvents.isEmpty)
  92. }
  93. }