Files
javierandClaude Fable 5.1 916df7e2f0 Project updates from Template
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>
2026-09-20 12:45:58 +02:00

229 lines
7.2 KiB
Swift

import Hummingbird
import HummingbirdTesting
import Infrastructure
import NIOCore
import Testing
@testable import WebsiteLibrary
@Suite(
"RootController controller",
.tags(.controller)
)
struct RootControllerTests {
// MARK: Constants
private let app: Application = .init(router: {
let router = Router(context: WebsiteRequestContext.self)
router.addRoutes(RootController<WebsiteRequestContext>().routes)
return router
}())
// MARK: Functional tests
@Test
func `serves the landing page at the root path`() async throws {
try await app.test(.router) { client in
try await client.execute(
uri: "/",
method: .get
) { response in
let body = String(buffer: response.body)
#expect(response.status == .ok)
#expect(response.headers[.contentType] == "text/html; charset=utf-8")
#expect(response.headers[.contentLanguage] == "en")
#expect(response.headers[.vary] == "Accept-Language")
#expect(body.contains("Hello world!"))
}
}
}
@Test
func `serves the landing page with revalidation headers`() async throws {
try await app.test(.router) { client in
try await client.execute(
uri: "/",
method: .get
) { response in
let eTag = try #require(response.headers[.eTag])
#expect(eTag.hasPrefix(#"W/""#))
#expect(response.headers[.cacheControl] == "public, no-cache")
}
}
}
@Test
func `revalidates a matching conditional request with a 304`() async throws {
try await app.test(.router) { client in
let eTag = try await client.execute(
uri: "/",
method: .get
) { response in
try #require(response.headers[.eTag])
}
try await client.execute(
uri: "/",
method: .get,
headers: [.ifNoneMatch: eTag]
) { response in
#expect(response.status == .notModified)
#expect(response.headers[.eTag] == eTag)
#expect(response.body.readableBytes == 0)
}
}
}
@Test
func `serves the full page to a non-matching conditional request`() async throws {
try await app.test(.router) { client in
try await client.execute(
uri: "/",
method: .get,
headers: [.ifNoneMatch: #"W/"0123456789abcdef""#]
) { response in
let body = String(buffer: response.body)
#expect(response.status == .ok)
#expect(body.contains("Hello world!"))
}
}
}
@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: "/",
method: .get
) { response in
let body = String(buffer: response.body)
#expect(body.contains("/css/index.css?v=0123456789abcdef"))
#expect(body.contains("/js/index.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: "/",
method: .get
) { response in
let body = String(buffer: response.body)
#expect(body.contains(#"href="/css/index.css""#))
#expect(!body.contains("?v="))
}
}
}
@Test
func `serves the landing page with a canonical URL when an origin is configured`() async throws {
try await app(
siteOrigin: "https://example.com"
).test(.router) { client in
try await client.execute(
uri: "/",
method: .get
) { response in
#expect(String(buffer: response.body).contains(#"<link rel="canonical" href="https://example.com">"#))
}
}
}
/// The template's catalog serves one language, so the default owns every path and no prefixed route is registered.
@Test
func `registers no prefixed route for a single-language catalog`() async throws {
let prefixed = Language.all.filter { !$0.isDefault }
#expect(prefixed.isEmpty)
try await app.test(.router) { client in
try await client.execute(
uri: "/en",
method: .get
) { response in
#expect(response.status == .notFound)
}
}
}
@Test
func `embeds no analytics tracker by default`() async throws {
try await app.test(.router) { client in
try await client.execute(
uri: "/",
method: .get
) { response in
let body = String(buffer: response.body)
#expect(!body.contains("data-website-id"))
#expect(!body.contains("analytics"))
}
}
}
@Test
func `embeds the analytics tracker when one is configured`() async throws {
try await app(
analytics: .init(
scriptURL: "https://analytics.example.com/script",
websiteID: "0000-website-id",
domains: "example.com"
)
).test(.router) { client in
try await client.execute(
uri: "/",
method: .get
) { response in
let body = String(buffer: response.body)
#expect(body.contains(#"<link rel="preconnect" href="https://analytics.example.com">"#))
#expect(body.contains(#"<script defer src="https://analytics.example.com/script" data-website-id="0000-website-id" data-domains="example.com""#))
}
}
}
}
// MARK: - Helpers
private extension RootControllerTests {
// MARK: Methods
/// Builds an application whose root controller appends the given version token to the landing
/// page's asset URLs, derives its absolute links from the given origin, and embeds the given analytics tracker.
/// - Parameters:
/// - assetVersion: the version token appended to the page's asset URLs.
/// - siteOrigin: the public origin the page derives its canonical URL and language alternates from, or `nil` (the default) to omit them.
/// - analytics: the analytics tracker the landing page embeds, or `nil` (the default) to omit it.
/// - Returns: the configured application.
func app(
assetVersion: String? = nil,
siteOrigin: String? = nil,
analytics: Analytics? = nil
) -> some ApplicationProtocol {
let router = Router(context: WebsiteRequestContext.self)
router.addRoutes(RootController<WebsiteRequestContext>(
assetVersion: assetVersion,
siteOrigin: siteOrigin,
analytics: analytics
).routes)
return Application(router: router)
}
}