PumpManagerStatusTests.swift 11 KB

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