Skip to content

Commit

Permalink
Merge pull request #2 from gandalf-network/feat/multiple-services
Browse files Browse the repository at this point in the history
Feat/Implement multiple services
  • Loading branch information
sa-ma authored Jul 3, 2024
2 parents 23c1e59 + eb5df17 commit 2bdcf85
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 15 deletions.
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,17 @@ import GandalfConnect
Create an instance of `ConnectInput` with the necessary details:

```swift
<!-- One service -->
let services: InputData = [
"uber": .service(Service(traits: ["rating"], activities: ["trip"]))
]

<!-- Multiple services -->
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",
Expand Down
3 changes: 2 additions & 1 deletion Sources/Example/Example.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ 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(
publicKey: "0x02073d3b9daf439c19a267dcfc19bc1ac1aea5066d8c754554b046476099b6fa22",
Expand Down
25 changes: 21 additions & 4 deletions Sources/GandalfConnect/GandalfConnect.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
}

Expand Down Expand Up @@ -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
]
}
}
Expand Down Expand Up @@ -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
}
Expand Down Expand Up @@ -153,9 +170,9 @@ public class Connect {

let keys = input.keys.map { $0.lowercased() }

if keys.count > 2 || (keys.count == 2 && !keys.contains("gandalf")) {
if keys.count < 1 {
throw GandalfError(
message: "Only one non-Gandalf service is supported per Connect URL",
message: "At least one service is needed.",
code: .InvalidService
)
}
Expand Down
21 changes: 11 additions & 10 deletions Tests/GandalfConnectTests/GandalfConnectTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down Expand Up @@ -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)

Expand All @@ -89,8 +89,9 @@ final class ConnectTests: XCTestCase {
let connect = Connect(input: input)

do {
_ = try await connect.generateURL()
XCTFail("Expected to throw, but did not throw")
let generatedURL = try await connect.generateURL()
XCTAssertTrue(generatedURL.contains(publicKey))
XCTAssertTrue(generatedURL.contains(redirectURL))
} catch let error as GandalfError {
XCTAssertEqual(error.code, .InvalidService)
} catch {
Expand Down Expand Up @@ -119,4 +120,4 @@ final class ConnectTests: XCTestCase {
XCTFail("Unexpected error type: \(type(of: error))")
}
}
}
}

0 comments on commit 2bdcf85

Please sign in to comment.