PumpManagerStatusTests.swift 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322
  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. "scheduledBasalRate" : 1,
  145. "scheduledBasalRateUnit" : "IU/hr",
  146. "startDate" : "2020-05-14T13:13:14Z",
  147. "syncIdentifier" : "238E41EA-9576-4981-A1A4-51E10228584F",
  148. "type" : "tempBasal",
  149. "unit" : "U/hour",
  150. "value" : 1.25
  151. }
  152. }
  153. }
  154. }
  155. """
  156. )
  157. }
  158. func testCodableCancelingTempBasal() throws {
  159. try assertPumpManagerStatusBasalDeliveryStateCodable(.cancelingTempBasal, encodesJSON: """
  160. {
  161. "basalDeliveryState" : "cancelingTempBasal"
  162. }
  163. """
  164. )
  165. }
  166. func testCodableSuspending() throws {
  167. try assertPumpManagerStatusBasalDeliveryStateCodable(.suspending, encodesJSON: """
  168. {
  169. "basalDeliveryState" : "suspending"
  170. }
  171. """
  172. )
  173. }
  174. func testCodableSuspended() throws {
  175. try assertPumpManagerStatusBasalDeliveryStateCodable(.suspended(dateFormatter.date(from: "2020-05-14T22:38:19Z")!), encodesJSON: """
  176. {
  177. "basalDeliveryState" : {
  178. "suspended" : {
  179. "at" : "2020-05-14T22:38:19Z"
  180. }
  181. }
  182. }
  183. """
  184. )
  185. }
  186. func testCodableResuming() throws {
  187. try assertPumpManagerStatusBasalDeliveryStateCodable(.resuming, encodesJSON: """
  188. {
  189. "basalDeliveryState" : "resuming"
  190. }
  191. """
  192. )
  193. }
  194. private func assertPumpManagerStatusBasalDeliveryStateCodable(_ original: PumpManagerStatus.BasalDeliveryState, encodesJSON string: String) throws {
  195. let data = try encoder.encode(TestContainer(basalDeliveryState: original))
  196. XCTAssertEqual(String(data: data, encoding: .utf8), string)
  197. let decoded = try decoder.decode(TestContainer.self, from: data)
  198. XCTAssertEqual(decoded.basalDeliveryState, original)
  199. }
  200. private let dateFormatter = ISO8601DateFormatter()
  201. private let encoder: JSONEncoder = {
  202. let encoder = JSONEncoder()
  203. encoder.outputFormatting = [.prettyPrinted, .sortedKeys, .withoutEscapingSlashes]
  204. encoder.dateEncodingStrategy = .iso8601
  205. return encoder
  206. }()
  207. private let decoder: JSONDecoder = {
  208. let decoder = JSONDecoder()
  209. decoder.dateDecodingStrategy = .iso8601
  210. return decoder
  211. }()
  212. private struct TestContainer: Codable, Equatable {
  213. let basalDeliveryState: PumpManagerStatus.BasalDeliveryState
  214. }
  215. }
  216. class PumpManagerStatusBolusStateCodableTests: XCTestCase {
  217. func testCodableNone() throws {
  218. try assertPumpManagerStatusBolusStateCodable(.noBolus, encodesJSON: """
  219. {
  220. "bolusState" : "noBolus"
  221. }
  222. """
  223. )
  224. }
  225. func testCodableInitiating() throws {
  226. try assertPumpManagerStatusBolusStateCodable(.initiating, encodesJSON: """
  227. {
  228. "bolusState" : "initiating"
  229. }
  230. """
  231. )
  232. }
  233. func testCodableInProgress() throws {
  234. let dose = DoseEntry(type: .bolus,
  235. startDate: dateFormatter.date(from: "2020-05-14T22:38:16Z")!,
  236. value: 2.5,
  237. unit: .units,
  238. deliveredUnits: 1.0,
  239. description: "Bolus",
  240. syncIdentifier: "2A67A303-5203-4CB8-8123-79498265368E",
  241. isMutable: true)
  242. try assertPumpManagerStatusBolusStateCodable(.inProgress(dose), encodesJSON: """
  243. {
  244. "bolusState" : {
  245. "inProgress" : {
  246. "dose" : {
  247. "deliveredUnits" : 1,
  248. "description" : "Bolus",
  249. "endDate" : "2020-05-14T22:38:16Z",
  250. "isMutable" : true,
  251. "startDate" : "2020-05-14T22:38:16Z",
  252. "syncIdentifier" : "2A67A303-5203-4CB8-8123-79498265368E",
  253. "type" : "bolus",
  254. "unit" : "U",
  255. "value" : 2.5
  256. }
  257. }
  258. }
  259. }
  260. """
  261. )
  262. }
  263. func testCodableCancelling() throws {
  264. try assertPumpManagerStatusBolusStateCodable(.canceling, encodesJSON: """
  265. {
  266. "bolusState" : "canceling"
  267. }
  268. """
  269. )
  270. }
  271. private func assertPumpManagerStatusBolusStateCodable(_ original: PumpManagerStatus.BolusState, encodesJSON string: String) throws {
  272. let data = try encoder.encode(TestContainer(bolusState: original))
  273. XCTAssertEqual(String(data: data, encoding: .utf8), string)
  274. let decoded = try decoder.decode(TestContainer.self, from: data)
  275. XCTAssertEqual(decoded.bolusState, original)
  276. }
  277. private let dateFormatter = ISO8601DateFormatter()
  278. private let encoder: JSONEncoder = {
  279. let encoder = JSONEncoder()
  280. encoder.outputFormatting = [.prettyPrinted, .sortedKeys, .withoutEscapingSlashes]
  281. encoder.dateEncodingStrategy = .iso8601
  282. return encoder
  283. }()
  284. private let decoder: JSONDecoder = {
  285. let decoder = JSONDecoder()
  286. decoder.dateDecodingStrategy = .iso8601
  287. return decoder
  288. }()
  289. private struct TestContainer: Codable, Equatable {
  290. let bolusState: PumpManagerStatus.BolusState
  291. }
  292. }