feat: Adds api route tests.
This commit is contained in:
@@ -42,8 +42,10 @@ let package = Package(
|
||||
]
|
||||
),
|
||||
.testTarget(
|
||||
name: "swift-manual-dTests",
|
||||
dependencies: ["swift-manual-d"]
|
||||
name: "ApiRouteTests",
|
||||
dependencies: [
|
||||
.target(name: "ManualDCore")
|
||||
]
|
||||
),
|
||||
]
|
||||
)
|
||||
|
||||
53
Sources/ManualDCore/Project.swift
Normal file
53
Sources/ManualDCore/Project.swift
Normal file
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
import CasePathsCore
|
||||
import Foundation
|
||||
@preconcurrency import URLRouting
|
||||
|
||||
extension SiteRoute {
|
||||
/// Represents view routes.
|
||||
///
|
||||
/// The routes return html.
|
||||
public enum View {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
75
Tests/ApiRouteTests/ProjectRouteTests.swift
Normal file
75
Tests/ApiRouteTests/ProjectRouteTests.swift
Normal file
@@ -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))
|
||||
}
|
||||
}
|
||||
@@ -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.
|
||||
}
|
||||
Reference in New Issue
Block a user