Files
ccn/Services/Website/Tests/Library/Cases/Public/Controllers/RootControllerTests.swift
T
javier 65b62681eb Project updates from Template (#1)
This PR contains the latest updates from the generic Website template, which have been added while working on #loud-amsterdam.

Reviewed-on: #1
Co-authored-by: Javier Cicchelli <javier@rock-n-code.com>
2026-09-04 13:40:35 +00:00

237 lines
7.4 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.addMiddleware {
LocalizationMiddleware()
}
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.addMiddleware {
LocalizationMiddleware()
}
router.addRoutes(RootController<WebsiteRequestContext>(
assetVersion: assetVersion,
siteOrigin: siteOrigin,
analytics: analytics
).routes)
return Application(router: router)
}
}