PumpManagerStatusTests.swift 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307
  1. //
  2. // PumpManagerStatusTests.swift
  3. // LoopKitTests
  4. //
  5. // Created by Darin Krauss on 5/4/20.
  6. // Copyright © 2020 LoopKit Authors. All rights reserved.
  7. //
  8. import XCTest
  9. import HealthKit
  10. @testable import LoopKit
  11. class PumpManagerStatusCodableTests: XCTestCase {
  12. func testCodable() throws {
  13. let device = HKDevice(name: "Acme Best Device",
  14. manufacturer: "Acme",
  15. model: "Best",
  16. hardwareVersion: "0.1.2",
  17. firmwareVersion: "1.2.3",
  18. softwareVersion: "2.3.4",
  19. localIdentifier: "Locally Identified",
  20. udiDeviceIdentifier: "U0D1I2")
  21. let pumpStatusHighlight = PumpManagerStatus.PumpStatusHighlight(localizedMessage: "Test message",
  22. imageName: "test.image",
  23. state: .normalPump)
  24. let pumpLifecycleProgress = PumpManagerStatus.PumpLifecycleProgress(percentComplete: 0.5,
  25. progressState: .warning)
  26. try assertPumpManagerStatusCodable(PumpManagerStatus(timeZone: TimeZone(identifier: "America/Los_Angeles")!,
  27. device: device,
  28. pumpBatteryChargeRemaining: 0.75,
  29. basalDeliveryState: .active(dateFormatter.date(from: "2020-05-14T15:56:09Z")!),
  30. bolusState: .noBolus,
  31. insulinType: .novolog,
  32. pumpStatusHighlight: pumpStatusHighlight,
  33. pumpLifecycleProgress: pumpLifecycleProgress,
  34. deliveryIsUncertain: true),
  35. encodesJSON: """
  36. {
  37. "basalDeliveryState" : {
  38. "active" : {
  39. "at" : "2020-05-14T15:56:09Z"
  40. }
  41. },
  42. "bolusState" : "noBolus",
  43. "deliveryIsUncertain" : true,
  44. "device" : {
  45. "firmwareVersion" : "1.2.3",
  46. "hardwareVersion" : "0.1.2",
  47. "localIdentifier" : "Locally Identified",
  48. "manufacturer" : "Acme",
  49. "model" : "Best",
  50. "name" : "Acme Best Device",
  51. "softwareVersion" : "2.3.4",
  52. "udiDeviceIdentifier" : "U0D1I2"
  53. },
  54. "insulinType\" : 0,
  55. "pumpBatteryChargeRemaining" : 0.75,
  56. "pumpLifecycleProgress" : {
  57. "percentComplete" : 0.5,
  58. "progressState" : "warning"
  59. },
  60. "pumpStatusHighlight" : {
  61. "imageName" : "test.image",
  62. "localizedMessage" : "Test message",
  63. "state" : "normalPump"
  64. },
  65. "timeZone" : {
  66. "identifier" : "America/Los_Angeles"
  67. }
  68. }
  69. """
  70. )
  71. }
  72. private func assertPumpManagerStatusCodable(_ original: PumpManagerStatus, encodesJSON string: String) throws {
  73. let data = try encoder.encode(original)
  74. XCTAssertEqual(String(data: data, encoding: .utf8), string)
  75. let decoded = try decoder.decode(PumpManagerStatus.self, from: data)
  76. XCTAssertEqual(decoded, original)
  77. }
  78. private let dateFormatter = ISO8601DateFormatter()
  79. private let encoder: JSONEncoder = {
  80. let encoder = JSONEncoder()
  81. encoder.outputFormatting = [.prettyPrinted, .sortedKeys, .withoutEscapingSlashes]
  82. encoder.dateEncodingStrategy = .iso8601
  83. return encoder
  84. }()
  85. private let decoder: JSONDecoder = {
  86. let decoder = JSONDecoder()
  87. decoder.dateDecodingStrategy = .iso8601
  88. return decoder
  89. }()
  90. }
  91. class PumpManagerStatusBasalDeliveryStateCodableTests: XCTestCase {
  92. func testCodableActive() throws {
  93. try assertPumpManagerStatusBasalDeliveryStateCodable(.active(dateFormatter.date(from: "2020-05-14T12:18:09Z")!), encodesJSON: """
  94. {
  95. "basalDeliveryState" : {
  96. "active" : {
  97. "at" : "2020-05-14T12:18:09Z"
  98. }
  99. }
  100. }
  101. """
  102. )
  103. }
  104. func testCodableInitiatingTempBasal() throws {
  105. try assertPumpManagerStatusBasalDeliveryStateCodable(.initiatingTempBasal, encodesJSON: """
  106. {
  107. "basalDeliveryState" : "initiatingTempBasal"
  108. }
  109. """
  110. )
  111. }
  112. func testCodableTempBasal() throws {
  113. let dose = DoseEntry(type: .tempBasal,
  114. startDate: dateFormatter.date(from: "2020-05-14T13:13:14Z")!,
  115. endDate: dateFormatter.date(from: "2020-05-14T13:43:14Z")!,
  116. value: 1.25,
  117. unit: .unitsPerHour,
  118. deliveredUnits: 0.5,
  119. description: "Temporary Basal",
  120. syncIdentifier: "238E41EA-9576-4981-A1A4-51E10228584F",
  121. scheduledBasalRate: HKQuantity(unit: DoseEntry.unitsPerHour, doubleValue: 1.0))
  122. try assertPumpManagerStatusBasalDeliveryStateCodable(.tempBasal(dose), encodesJSON: """
  123. {
  124. "basalDeliveryState" : {
  125. "tempBasal" : {
  126. "dose" : {
  127. "automatic" : null,
  128. "deliveredUnits" : 0.5,
  129. "description" : "Temporary Basal",
  130. "endDate" : "2020-05-14T13:43:14Z",
  131. "scheduledBasalRate" : 1,
  132. "scheduledBasalRateUnit" : "IU/hr",
  133. "startDate" : "2020-05-14T13:13:14Z",
  134. "syncIdentifier" : "238E41EA-9576-4981-A1A4-51E10228584F",
  135. "type" : "tempBasal",
  136. "unit" : "U/hour",
  137. "value" : 1.25
  138. }
  139. }
  140. }
  141. }
  142. """
  143. )
  144. }
  145. func testCodableCancelingTempBasal() throws {
  146. try assertPumpManagerStatusBasalDeliveryStateCodable(.cancelingTempBasal, encodesJSON: """
  147. {
  148. "basalDeliveryState" : "cancelingTempBasal"
  149. }
  150. """
  151. )
  152. }
  153. func testCodableSuspending() throws {
  154. try assertPumpManagerStatusBasalDeliveryStateCodable(.suspending, encodesJSON: """
  155. {
  156. "basalDeliveryState" : "suspending"
  157. }
  158. """
  159. )
  160. }
  161. func testCodableSuspended() throws {
  162. try assertPumpManagerStatusBasalDeliveryStateCodable(.suspended(dateFormatter.date(from: "2020-05-14T22:38:19Z")!), encodesJSON: """
  163. {
  164. "basalDeliveryState" : {
  165. "suspended" : {
  166. "at" : "2020-05-14T22:38:19Z"
  167. }
  168. }
  169. }
  170. """
  171. )
  172. }
  173. func testCodableResuming() throws {
  174. try assertPumpManagerStatusBasalDeliveryStateCodable(.resuming, encodesJSON: """
  175. {
  176. "basalDeliveryState" : "resuming"
  177. }
  178. """
  179. )
  180. }
  181. private func assertPumpManagerStatusBasalDeliveryStateCodable(_ original: PumpManagerStatus.BasalDeliveryState, encodesJSON string: String) throws {
  182. let data = try encoder.encode(TestContainer(basalDeliveryState: original))
  183. XCTAssertEqual(String(data: data, encoding: .utf8), string)
  184. let decoded = try decoder.decode(TestContainer.self, from: data)
  185. XCTAssertEqual(decoded.basalDeliveryState, original)
  186. }
  187. private let dateFormatter = ISO8601DateFormatter()
  188. private let encoder: JSONEncoder = {
  189. let encoder = JSONEncoder()
  190. encoder.outputFormatting = [.prettyPrinted, .sortedKeys, .withoutEscapingSlashes]
  191. encoder.dateEncodingStrategy = .iso8601
  192. return encoder
  193. }()
  194. private let decoder: JSONDecoder = {
  195. let decoder = JSONDecoder()
  196. decoder.dateDecodingStrategy = .iso8601
  197. return decoder
  198. }()
  199. private struct TestContainer: Codable, Equatable {
  200. let basalDeliveryState: PumpManagerStatus.BasalDeliveryState
  201. }
  202. }
  203. class PumpManagerStatusBolusStateCodableTests: XCTestCase {
  204. func testCodableNone() throws {
  205. try assertPumpManagerStatusBolusStateCodable(.noBolus, encodesJSON: """
  206. {
  207. "bolusState" : "noBolus"
  208. }
  209. """
  210. )
  211. }
  212. func testCodableInitiating() throws {
  213. try assertPumpManagerStatusBolusStateCodable(.initiating, encodesJSON: """
  214. {
  215. "bolusState" : "initiating"
  216. }
  217. """
  218. )
  219. }
  220. func testCodableInProgress() throws {
  221. let dose = DoseEntry(type: .bolus,
  222. startDate: dateFormatter.date(from: "2020-05-14T22:38:16Z")!,
  223. value: 2.5,
  224. unit: .units,
  225. deliveredUnits: 1.0,
  226. description: "Bolus",
  227. syncIdentifier: "2A67A303-5203-4CB8-8123-79498265368E")
  228. try assertPumpManagerStatusBolusStateCodable(.inProgress(dose), encodesJSON: """
  229. {
  230. "bolusState" : {
  231. "inProgress" : {
  232. "dose" : {
  233. "automatic" : null,
  234. "deliveredUnits" : 1,
  235. "description" : "Bolus",
  236. "endDate" : "2020-05-14T22:38:16Z",
  237. "startDate" : "2020-05-14T22:38:16Z",
  238. "syncIdentifier" : "2A67A303-5203-4CB8-8123-79498265368E",
  239. "type" : "bolus",
  240. "unit" : "U",
  241. "value" : 2.5
  242. }
  243. }
  244. }
  245. }
  246. """
  247. )
  248. }
  249. func testCodableCancelling() throws {
  250. try assertPumpManagerStatusBolusStateCodable(.canceling, encodesJSON: """
  251. {
  252. "bolusState" : "canceling"
  253. }
  254. """
  255. )
  256. }
  257. private func assertPumpManagerStatusBolusStateCodable(_ original: PumpManagerStatus.BolusState, encodesJSON string: String) throws {
  258. let data = try encoder.encode(TestContainer(bolusState: original))
  259. XCTAssertEqual(String(data: data, encoding: .utf8), string)
  260. let decoded = try decoder.decode(TestContainer.self, from: data)
  261. XCTAssertEqual(decoded.bolusState, original)
  262. }
  263. private let dateFormatter = ISO8601DateFormatter()
  264. private let encoder: JSONEncoder = {
  265. let encoder = JSONEncoder()
  266. encoder.outputFormatting = [.prettyPrinted, .sortedKeys, .withoutEscapingSlashes]
  267. encoder.dateEncodingStrategy = .iso8601
  268. return encoder
  269. }()
  270. private let decoder: JSONDecoder = {
  271. let decoder = JSONDecoder()
  272. decoder.dateDecodingStrategy = .iso8601
  273. return decoder
  274. }()
  275. private struct TestContainer: Codable, Equatable {
  276. let bolusState: PumpManagerStatus.BolusState
  277. }
  278. }