This commit contains the latest updates from the generic Website template, which rework the compression and localization: - Reworked the compression and localization in the Infrastructure package. (3c568e4) - Adopted the reworked compression and localization in the Website service. (08cf3e3) The template commit that only touched the root README (53676ed) was left out, as this project no longer carries that file. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
193 lines
5.7 KiB
Swift
193 lines
5.7 KiB
Swift
import Foundation
|
|
import Hummingbird
|
|
import HummingbirdTesting
|
|
import NIOCore
|
|
import Testing
|
|
|
|
@testable import Infrastructure
|
|
|
|
@Suite(
|
|
"NotFoundMiddleware middleware",
|
|
.tags(.middleware)
|
|
)
|
|
struct NotFoundMiddlewareTests {
|
|
|
|
// MARK: Constants
|
|
|
|
private let app: Application = .init(router: {
|
|
let router = Router(context: StubRequestContext.self)
|
|
|
|
router.addMiddleware {
|
|
NotFoundMiddleware(bundle: .module) {
|
|
StubPage(locale: $0)
|
|
}
|
|
}
|
|
|
|
router.get("hello") { _, _ in
|
|
"Hello!"
|
|
}
|
|
|
|
router.get("boom") { _, _ -> String in
|
|
throw HTTPError(.badRequest)
|
|
}
|
|
|
|
return router
|
|
}())
|
|
|
|
// MARK: Functional tests
|
|
|
|
@Test
|
|
func `renders the error page for an unmatched request`() async throws {
|
|
try await app.test(.router) { client in
|
|
try await client.execute(
|
|
uri: "/this-path-does-not-exist",
|
|
method: .get
|
|
) { response in
|
|
let body = String(buffer: response.body)
|
|
|
|
#expect(response.status == .notFound)
|
|
#expect(response.headers[.contentType] == "text/html; charset=utf-8")
|
|
#expect(response.headers[.contentLanguage] == "en")
|
|
#expect(response.headers[.vary] == "Accept-Language")
|
|
#expect(body.contains("Stub content"))
|
|
}
|
|
}
|
|
}
|
|
|
|
@Test
|
|
func `renders the error page in the negotiated language`() async throws {
|
|
try await app.test(.router) { client in
|
|
try await client.execute(
|
|
uri: "/this-path-does-not-exist",
|
|
method: .get,
|
|
headers: [.acceptLanguage: "de-DE,de;q=0.9"]
|
|
) { response in
|
|
#expect(response.status == .notFound)
|
|
#expect(response.headers[.contentLanguage] == "de")
|
|
}
|
|
}
|
|
}
|
|
|
|
@Test
|
|
func `passes a matched response through untouched`() async throws {
|
|
try await app.test(.router) { client in
|
|
try await client.execute(
|
|
uri: "/hello",
|
|
method: .get
|
|
) { response in
|
|
#expect(response.status == .ok)
|
|
#expect(response.body == ByteBuffer(string: "Hello!"))
|
|
}
|
|
}
|
|
}
|
|
|
|
@Test
|
|
func `rethrows a non-not-found error unchanged`() async throws {
|
|
try await app.test(.router) { client in
|
|
try await client.execute(
|
|
uri: "/boom",
|
|
method: .get
|
|
) { response in
|
|
let body = String(buffer: response.body)
|
|
|
|
#expect(response.status == .badRequest)
|
|
#expect(!body.contains("Stub content"))
|
|
}
|
|
}
|
|
}
|
|
|
|
@Test
|
|
func `renders versioned asset URLs when given a version`() async throws {
|
|
try await app(
|
|
assetVersion: "0123456789abcdef"
|
|
).test(.router) { client in
|
|
try await client.execute(
|
|
uri: "/this-path-does-not-exist",
|
|
method: .get
|
|
) { response in
|
|
let body = String(buffer: response.body)
|
|
|
|
#expect(body.contains("/css/stub.css?v=0123456789abcdef"))
|
|
#expect(body.contains("/js/stub.js?v=0123456789abcdef"))
|
|
}
|
|
}
|
|
}
|
|
|
|
@Test
|
|
func `renders unversioned asset URLs by default`() async throws {
|
|
try await app.test(.router) { client in
|
|
try await client.execute(
|
|
uri: "/this-path-does-not-exist",
|
|
method: .get
|
|
) { response in
|
|
let body = String(buffer: response.body)
|
|
|
|
#expect(body.contains(#"href="/css/stub.css""#))
|
|
#expect(!body.contains("?v="))
|
|
}
|
|
}
|
|
}
|
|
|
|
@Test
|
|
func `serves the error page without revalidation headers`() async throws {
|
|
// A `304 Not Modified` only ever stands in for a success, so the error page must not
|
|
// invite revalidation with an entity tag or a cache policy.
|
|
try await app.test(.router) { client in
|
|
try await client.execute(
|
|
uri: "/this-path-does-not-exist",
|
|
method: .get
|
|
) { response in
|
|
#expect(response.status == .notFound)
|
|
#expect(response.headers[.eTag] == nil)
|
|
#expect(response.headers[.cacheControl] == nil)
|
|
}
|
|
}
|
|
}
|
|
|
|
@Test
|
|
func `serves the full error page to a conditional request`() async throws {
|
|
try await app.test(.router) { client in
|
|
try await client.execute(
|
|
uri: "/this-path-does-not-exist",
|
|
method: .get,
|
|
headers: [.ifNoneMatch: "*"]
|
|
) { response in
|
|
let body = String(buffer: response.body)
|
|
|
|
#expect(response.status == .notFound)
|
|
#expect(body.contains("Stub content"))
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
// MARK: - Helpers
|
|
|
|
private extension NotFoundMiddlewareTests {
|
|
|
|
// MARK: Methods
|
|
|
|
/// Builds an application whose not-found middleware appends the given version token to the
|
|
/// error page's asset URLs.
|
|
/// - Parameter assetVersion: the version token appended to the page's asset URLs.
|
|
/// - Returns: the configured application.
|
|
func app(
|
|
assetVersion: String?
|
|
) -> some ApplicationProtocol {
|
|
let router = Router(context: StubRequestContext.self)
|
|
|
|
router.addMiddleware {
|
|
NotFoundMiddleware(bundle: .module) {
|
|
StubPage(
|
|
locale: $0,
|
|
assetVersion: assetVersion
|
|
)
|
|
}
|
|
}
|
|
|
|
return Application(router: router)
|
|
}
|
|
|
|
}
|