diff --git a/Package.swift b/Package.swift index 73e12f5..347dad2 100644 --- a/Package.swift +++ b/Package.swift @@ -42,8 +42,10 @@ let package = Package( ] ), .testTarget( - name: "swift-manual-dTests", - dependencies: ["swift-manual-d"] + name: "ApiRouteTests", + dependencies: [ + .target(name: "ManualDCore") + ] ), ] ) diff --git a/Sources/ManualDCore/Project.swift b/Sources/ManualDCore/Project.swift new file mode 100644 index 0000000..01ae942 --- /dev/null +++ b/Sources/ManualDCore/Project.swift @@ -0,0 +1,53 @@ +import Foundation + +public struct Project: Codable, Equatable, Identifiable, Sendable { + + public let id: UUID + public let name: String + public let streetAddress: String + public let city: String + public let state: String + public let zipCode: String + + public init( + id: UUID, + name: String, + streetAddress: String, + city: String, + state: String, + zipCode: String + ) { + self.id = id + self.name = name + self.streetAddress = streetAddress + self.city = city + self.state = state + self.zipCode = zipCode + } +} + +extension Project { + + public struct Create: Codable, Equatable, Sendable { + + public let name: String + public let streetAddress: String + public let city: String + public let state: String + public let zipCode: String + + public init( + name: String, + streetAddress: String, + city: String, + state: String, + zipCode: String + ) { + self.name = name + self.streetAddress = streetAddress + self.city = city + self.state = state + self.zipCode = zipCode + } + } +} diff --git a/Sources/ManualDCore/Routes/ApiRoute.swift b/Sources/ManualDCore/Routes/ApiRoute.swift index 5f4700c..65bf19d 100644 --- a/Sources/ManualDCore/Routes/ApiRoute.swift +++ b/Sources/ManualDCore/Routes/ApiRoute.swift @@ -6,12 +6,60 @@ extension SiteRoute { /// Represents api routes. /// /// The routes return json as opposed to view routes that return html. - public enum Api { + public enum Api: Sendable, Equatable { + + case project(Self.ProjectRoute) + public static let rootPath = Path { "api" "v1" } + public static let router = OneOf { + Route(.case(Self.project)) { + rootPath + ProjectRoute.router + } + } + + } + +} + +extension SiteRoute.Api { + public enum ProjectRoute: Sendable, Equatable { + case create(Project.Create) + case delete(id: Project.ID) + case get(id: Project.ID) + case index + + static let rootPath = "projects" + + public static let router = OneOf { + Route(.case(Self.create)) { + Path { rootPath } + Method.post + Body(.json(Project.Create.self)) + } + Route(.case(Self.delete(id:))) { + Path { + rootPath + Project.ID.parser() + } + Method.delete + } + Route(.case(Self.get(id:))) { + Path { + rootPath + Project.ID.parser() + } + Method.get + } + Route(.case(Self.index)) { + Path { rootPath } + Method.get + } + } } } diff --git a/Sources/ManualDCore/Routes/SiteRoute.swift b/Sources/ManualDCore/Routes/SiteRoute.swift index da49b8a..48d7a9d 100644 --- a/Sources/ManualDCore/Routes/SiteRoute.swift +++ b/Sources/ManualDCore/Routes/SiteRoute.swift @@ -2,5 +2,13 @@ import CasePathsCore import Foundation @preconcurrency import URLRouting -public enum SiteRoute { +public enum SiteRoute: Equatable, Sendable { + + case api(Self.Api) + + public static let router = OneOf { + Route(.case(Self.api)) { + SiteRoute.Api.router + } + } } diff --git a/Sources/ManualDCore/Routes/ViewRoute.swift b/Sources/ManualDCore/Routes/ViewRoute.swift index e69de29..ebfb895 100644 --- a/Sources/ManualDCore/Routes/ViewRoute.swift +++ b/Sources/ManualDCore/Routes/ViewRoute.swift @@ -0,0 +1,12 @@ +import CasePathsCore +import Foundation +@preconcurrency import URLRouting + +extension SiteRoute { + /// Represents view routes. + /// + /// The routes return html. + public enum View { + + } +} diff --git a/Tests/ApiRouteTests/ProjectRouteTests.swift b/Tests/ApiRouteTests/ProjectRouteTests.swift new file mode 100644 index 0000000..1865f8f --- /dev/null +++ b/Tests/ApiRouteTests/ProjectRouteTests.swift @@ -0,0 +1,75 @@ +import Dependencies +import Foundation +import ManualDCore +import Testing +import URLRouting + +@Suite("ProjectRouteTests") +struct ProjectRouteTests { + let router = SiteRoute.Api.router + + @Test + func create() throws { + let json = """ + { + \"name\": \"Test\", + \"streetAddress\": \"1234 Seasme Street\", + \"city\": \"Nowhere\", + \"state\": \"OH\", + \"zipCode\": \"55555\" + } + """ + var request = URLRequestData( + method: "POST", + path: "/api/v1/projects", + body: .init(json.utf8) + ) + let route = try router.parse(&request) + #expect( + route + == .project( + .create( + .init( + name: "Test", + streetAddress: "1234 Seasme Street", + city: "Nowhere", + state: "OH", + zipCode: "55555" + ) + ) + ) + ) + } + + @Test + func delete() throws { + let id = UUID(0) + var request = URLRequestData( + method: "DELETE", + path: "/api/v1/projects/\(id)" + ) + let route = try router.parse(&request) + #expect(route == .project(.delete(id: id))) + } + + @Test + func get() throws { + let id = UUID(0) + var request = URLRequestData( + method: "GET", + path: "/api/v1/projects/\(id)" + ) + let route = try router.parse(&request) + #expect(route == .project(.get(id: id))) + } + + @Test + func index() throws { + var request = URLRequestData( + method: "GET", + path: "/api/v1/projects" + ) + let route = try router.parse(&request) + #expect(route == .project(.index)) + } +} diff --git a/Tests/swift-manual-dTests/swift_manual_dTests.swift b/Tests/swift-manual-dTests/swift_manual_dTests.swift deleted file mode 100644 index 90d617f..0000000 --- a/Tests/swift-manual-dTests/swift_manual_dTests.swift +++ /dev/null @@ -1,6 +0,0 @@ -import Testing -@testable import swift_manual_d - -@Test func example() async throws { - // Write your test here and use APIs like `#expect(...)` to check expected conditions. -}