From 30b59dedaec4c587581cc96779070ac1f1b86ec3 Mon Sep 17 00:00:00 2001 From: Morten Bjerg Gregersen Date: Mon, 16 Oct 2023 23:34:51 +0200 Subject: [PATCH] Patch Device.Status to contain "PROCESSING" (#137) * Patch Device.Status to contain "PROCESSING" * Update Device.swift --------- Co-authored-by: Morten Bjerg Gregersen <759680+MortenGregersen@users.noreply.github.com> --- .../Extensions/DeviceStatus+PrettyName.swift | 1 + .../Bagbutik-Models/Provisioning/Device.swift | 1 + .../Schemas/ObjectSchema.swift | 2 - Sources/BagbutikSpecDecoder/Spec.swift | 30 ++++++++++--- .../BagbutikSpecDecoderTests/SpecTests.swift | 44 ++++++++++++++++++- 5 files changed, 70 insertions(+), 8 deletions(-) diff --git a/Sources/Bagbutik-Models/Extensions/DeviceStatus+PrettyName.swift b/Sources/Bagbutik-Models/Extensions/DeviceStatus+PrettyName.swift index 662770104..27b86cef9 100644 --- a/Sources/Bagbutik-Models/Extensions/DeviceStatus+PrettyName.swift +++ b/Sources/Bagbutik-Models/Extensions/DeviceStatus+PrettyName.swift @@ -4,6 +4,7 @@ public extension Device.Attributes.Status { switch self { case .enabled: return "Enabled" case .disabled: return "Disabled" + case .processing: return "Processing" } } } diff --git a/Sources/Bagbutik-Models/Provisioning/Device.swift b/Sources/Bagbutik-Models/Provisioning/Device.swift index 6778a18bc..0e23c699e 100644 --- a/Sources/Bagbutik-Models/Provisioning/Device.swift +++ b/Sources/Bagbutik-Models/Provisioning/Device.swift @@ -97,6 +97,7 @@ public struct Device: Codable, Identifiable { public enum Status: String, ParameterValue, Codable, CaseIterable { case enabled = "ENABLED" case disabled = "DISABLED" + case processing = "PROCESSING" } } } diff --git a/Sources/BagbutikSpecDecoder/Schemas/ObjectSchema.swift b/Sources/BagbutikSpecDecoder/Schemas/ObjectSchema.swift index 33160d519..1adcdf51c 100644 --- a/Sources/BagbutikSpecDecoder/Schemas/ObjectSchema.swift +++ b/Sources/BagbutikSpecDecoder/Schemas/ObjectSchema.swift @@ -34,8 +34,6 @@ public struct ObjectSchema: Decodable, Equatable { case properties case deprecated case required - case attributes - case relationships } private enum PropertyCodingKeys: String, CodingKey { diff --git a/Sources/BagbutikSpecDecoder/Spec.swift b/Sources/BagbutikSpecDecoder/Spec.swift index 88e9ea568..5bc8013b8 100644 --- a/Sources/BagbutikSpecDecoder/Spec.swift +++ b/Sources/BagbutikSpecDecoder/Spec.swift @@ -13,7 +13,7 @@ public struct Spec: Decodable { components = try container.decode(Components.self, forKey: .components) } - internal init(paths: [String: Path], components: Components) throws { + init(paths: [String: Path], components: Components) throws { self.paths = paths self.components = components } @@ -91,8 +91,7 @@ public struct Spec: Decodable { guard case .enumSchema(let mainAttributesPropertySchema) = mainAttributesProperty.type, mainAttributesPropertySchema.cases == parameterEnumSchema.cases else { return nil } return (name: propertyName, schema: mainAttributesPropertySchema) - }).first - { + }).first { newType = "\(path.info.mainType).Attributes.\(propertyInfo.name.capitalizingFirstLetter())" var enumSchema = propertyInfo.schema enumSchema.additionalProtocols.insert("ParameterValue") @@ -100,7 +99,7 @@ public struct Spec: Decodable { mainSchema.properties["attributes"]?.type = .schema(mainAttributesSchema) components.schemas[path.info.mainType] = .object(mainSchema) } - if let newType = newType { + if let newType { operation.parameters?[parameterIndex] = .filter(name: parameterName, type: .simple(type: .init(type: newType)), required: parameterRequired, documentation: parameterDocumentation) } } @@ -159,7 +158,28 @@ public struct Spec: Decodable { } components.schemas["BundleIdPlatform"] = .enum(bundleIdPlatformSchema) } - + + // Add the case `PROCESSING` to Device.Status + // Apple's OpenAPI spec doesn't include Processing as status for Device. + if case .object(var deviceSchema) = components.schemas["Device"], + var deviceAttributesSchema: ObjectSchema = deviceSchema.subSchemas.compactMap({ + guard case .objectSchema(let subSchema) = $0, + subSchema.name == "Attributes" else { + return nil + } + return subSchema + }).first, + var statusProperty = deviceAttributesSchema.properties["status"], + case .enumSchema(var statusEnum) = statusProperty.type { + var values = statusEnum.cases + values.append(.init(id: "processing", value: "PROCESSING")) + statusEnum.cases = values + statusProperty.type = .enumSchema(statusEnum) + deviceAttributesSchema.properties["status"] = statusProperty + deviceSchema.properties["attributes"]?.type = .schema(deviceAttributesSchema) + components.schemas["Device"] = .object(deviceSchema) + } + // Add the case `VISION_OS` to Platform // Apple's OpenAPI spec doesn't include visionOS for App Categories. Reported to Apple 28/8/23 as FB13071298. if case .enum(var platformSchema) = components.schemas["Platform"] { diff --git a/Tests/BagbutikSpecDecoderTests/SpecTests.swift b/Tests/BagbutikSpecDecoderTests/SpecTests.swift index bd3d5ec57..468951583 100644 --- a/Tests/BagbutikSpecDecoderTests/SpecTests.swift +++ b/Tests/BagbutikSpecDecoderTests/SpecTests.swift @@ -769,6 +769,32 @@ final class SpecTests: XCTestCase { "type" : "string", "enum" : [ "IOS", "MAC_OS" ] }, + "Device" : { + "type" : "object", + "title" : "Device", + "properties" : { + "type" : { + "type" : "string", + "enum" : [ "devices" ] + }, + "id" : { + "type" : "string" + }, + "attributes" : { + "type" : "object", + "properties" : { + "status" : { + "type" : "string", + "enum" : [ "ENABLED", "DISABLED" ] + }, + } + }, + "links" : { + "$ref" : "#/components/schemas/ResourceLinks" + } + }, + "required" : [ "id", "type" ] + }, "ErrorResponse" : { "type" : "object", "properties" : { @@ -826,6 +852,22 @@ final class SpecTests: XCTestCase { XCTAssertTrue(bundleIdPlatformCaseValues.contains("UNIVERSAL")) XCTAssertTrue(bundleIdPlatformCaseValues.contains("SERVICES")) + guard case .object(let deviceSchema) = spec.components.schemas["Device"], + var deviceAttributesSchema: ObjectSchema = deviceSchema.subSchemas.compactMap({ + guard case .objectSchema(let subSchema) = $0, + subSchema.name == "Attributes" else { + return nil + } + return subSchema + }).first, + var statusProperty = deviceAttributesSchema.properties["status"], + case .enumSchema(var deviceStatusSchema) = statusProperty.type else { + XCTFail(); return + } + let deviceStatusCaseValues = deviceStatusSchema.cases.map(\.value) + XCTAssertEqual(deviceStatusCaseValues.count, 3) + XCTAssertTrue(deviceStatusCaseValues.contains("PROCESSING")) + guard case .object(let errorResponse) = spec.components.schemas["ErrorResponse"], case .arrayOfSubSchema(let errorSchema) = errorResponse.properties["errors"]?.type, case .oneOf(_, let oneOfSchema) = errorSchema.properties["source"]?.type @@ -842,7 +884,7 @@ final class SpecTests: XCTestCase { XCTFail(); return } XCTAssertEqual(errorSchemaRef, "Errors") - + guard case .enum(let bundleIdPlatformSchema) = spec.components.schemas["Platform"] else { XCTFail(); return }