From eb5df1733c3eee470f4fa4c6f18829827ff0fb12 Mon Sep 17 00:00:00 2001 From: Samaila Bala Date: Mon, 24 Jun 2024 23:12:31 +0100 Subject: [PATCH] feat: add support for optional services --- README.md | 7 +++++++ Sources/Example/Example.swift | 2 +- Sources/GandalfConnect/GandalfConnect.swift | 21 +++++++++++++++++-- .../GandalfConnectTests.swift | 16 +++++++------- 4 files changed, 35 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 2c43e6a..58c3d6b 100644 --- a/README.md +++ b/README.md @@ -66,10 +66,17 @@ import GandalfConnect Create an instance of `ConnectInput` with the necessary details: ```swift + let services: InputData = [ "uber": .service(Service(traits: ["rating"], activities: ["trip"])) ] + +let services: InputData = [ + "uber": .service(Service(traits: ["rating"], activities: ["trip"], required: false)), + "netflix": .service(Service(activities: ["watch"])), +] + let input = ConnectInput( publicKey: "yourPublicKey", redirectURL: "https://example.com", diff --git a/Sources/Example/Example.swift b/Sources/Example/Example.swift index 4d8b576..b063bb9 100644 --- a/Sources/Example/Example.swift +++ b/Sources/Example/Example.swift @@ -10,7 +10,7 @@ struct Example { func testConnect() async { let services: InputData = [ - "uber": .service(Service(traits: ["rating"], activities: ["trip"])), + "uber": .service(Service(traits: ["rating"], activities: ["trip"], required: false)), "netflix": .service(Service(activities: ["watch"])), ] let input = ConnectInput( diff --git a/Sources/GandalfConnect/GandalfConnect.swift b/Sources/GandalfConnect/GandalfConnect.swift index 4ce1668..717a393 100644 --- a/Sources/GandalfConnect/GandalfConnect.swift +++ b/Sources/GandalfConnect/GandalfConnect.swift @@ -15,10 +15,12 @@ public struct GandalfError: Error { public struct Service { public var traits: [String]? public var activities: [String]? + public var required: Bool - public init(traits: [String]? = nil, activities: [String]? = nil) { + public init(traits: [String]? = nil, activities: [String]? = nil, required: Bool = true) { self.traits = traits self.activities = activities + self.required = required } } @@ -74,7 +76,8 @@ public class Connect { case .service(let serviceValue): dictionary[key] = [ "traits": serviceValue.traits ?? [], - "activities": serviceValue.activities ?? [] + "activities": serviceValue.activities ?? [], + "required": serviceValue.required ] } } @@ -121,6 +124,20 @@ public class Connect { try Self.validateRedirectURL(url: redirectURL) let cleanServices = try await Self.validateInputData(input: data) self.data = cleanServices + + // Validate that at least one service has the required property set to true + let hasRequiredService = cleanServices.values.contains { value in + switch value { + case .boolean(let isActive): + return isActive + case .service(let serviceData): + return serviceData.required + } + } + + if !hasRequiredService { + throw GandalfError(message: "At least one service must have the required property set to true", code: .InvalidService) + } } verificationComplete = true } diff --git a/Tests/GandalfConnectTests/GandalfConnectTests.swift b/Tests/GandalfConnectTests/GandalfConnectTests.swift index fd68829..fc74726 100644 --- a/Tests/GandalfConnectTests/GandalfConnectTests.swift +++ b/Tests/GandalfConnectTests/GandalfConnectTests.swift @@ -10,13 +10,13 @@ final class ConnectTests: XCTestCase { let invalidRedirectURL = "invalid-url" // Define services in terms of InputData - let services: InputData = ["uber": .service(Service(traits: ["rating"], activities: ["trip"]))] - let invalidServices: InputData = ["facebook": .service(Service(traits: ["plan"], activities: ["watch"]))] - let noRequiredServices: InputData = ["netflix": .service(Service(traits: [], activities: []))] + let services: InputData = ["uber": .service(Service(traits: ["rating"], activities: ["trip"], required: true))] + let invalidServices: InputData = ["facebook": .service(Service(traits: ["plan"], activities: ["watch"], required: true))] + let noRequiredServices: InputData = ["netflix": .service(Service(traits: [], activities: [], required: false))] let multipleServices: InputData = [ - "uber": .service(Service(traits: ["rating"], activities: ["trip"])), - "netflix": .service(Service(traits: ["plan"], activities: ["watch"])), - "instacart": .service(Service(traits: [], activities: ["shop"])) + "uber": .service(Service(traits: ["rating"], activities: ["trip"], required: true)), + "netflix": .service(Service(traits: ["plan"], activities: ["watch"], required: false)), + "instacart": .service(Service(traits: [], activities: ["shop"], required: false)) ] func testInitialization() { @@ -70,7 +70,7 @@ final class ConnectTests: XCTestCase { } } - func testGenerateURLWithNoRequiredTraitOrActivity() async { + func testGenerateURLWithNoRequiredService() async { let input = ConnectInput(publicKey: publicKey, redirectURL: redirectURL, services: noRequiredServices) let connect = Connect(input: input) @@ -120,4 +120,4 @@ final class ConnectTests: XCTestCase { XCTFail("Unexpected error type: \(type(of: error))") } } -} +} \ No newline at end of file