Implemented phase 0 for the POC prototype in the Website service.
This commit is contained in:
1 parent
916df7e2f0
commit
717df5208c
31 files changed
+2351
-240
No files matched your search
@@ -0,0 +1,30 @@
|
||||
import Elementary
|
||||
import Testing
|
||||
|
||||
@testable import WebsiteLibrary
|
||||
|
||||
@Suite(
|
||||
"Icon component",
|
||||
.tags(.component)
|
||||
)
|
||||
struct IconTests {
|
||||
|
||||
// MARK: Functional tests
|
||||
|
||||
@Test
|
||||
func `renders a decorative icon at the given size`() {
|
||||
let html = Icon(.search, size: 16).render()
|
||||
|
||||
#expect(html.hasPrefix("<svg"))
|
||||
#expect(html.contains(#"width="16" height="16""#))
|
||||
#expect(html.contains(#"aria-hidden="true""#))
|
||||
#expect(html.contains(#"stroke="currentColor""#))
|
||||
}
|
||||
|
||||
@Test
|
||||
func `renders no inline styles`() {
|
||||
// The Content-Security-Policy blocks `style` attributes, inside an SVG as anywhere else.
|
||||
#expect(!Icon(.key).render().contains("style="))
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
import Elementary
|
||||
import Testing
|
||||
|
||||
@testable import WebsiteLibrary
|
||||
|
||||
@Suite(
|
||||
"SiteFooter component",
|
||||
.tags(.component)
|
||||
)
|
||||
struct SiteFooterTests {
|
||||
|
||||
// MARK: Functional tests
|
||||
|
||||
@Test
|
||||
func `renders its link columns`() {
|
||||
let html = SiteFooter().render()
|
||||
|
||||
for title in ["Browse", "Sell", "Account", "Language"] {
|
||||
#expect(html.contains(">\(title)</h2>"))
|
||||
}
|
||||
|
||||
for path in [String.Route.series, .Route.openShop, .Route.gradingGuide, .Route.signIn, .Route.recover, .Route.terms] {
|
||||
#expect(html.contains(#"href="\#(path)""#))
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
func `escapes the ampersands in its labels`() {
|
||||
#expect(SiteFooter().render().contains("Want list & alerts"))
|
||||
}
|
||||
|
||||
@Test
|
||||
func `presses the one language the prototype serves`() {
|
||||
let html = SiteFooter().render()
|
||||
|
||||
#expect(html.components(separatedBy: #"aria-pressed="true""#).count - 1 == 1)
|
||||
#expect(html.contains(#"aria-pressed="true">EN<"#))
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
import Elementary
|
||||
import Testing
|
||||
|
||||
@testable import WebsiteLibrary
|
||||
|
||||
@Suite(
|
||||
"SiteHeader component",
|
||||
.tags(.component)
|
||||
)
|
||||
struct SiteHeaderTests {
|
||||
|
||||
// MARK: Functional tests
|
||||
|
||||
@Test
|
||||
func `renders the signed-out actions without a viewer`() {
|
||||
let html = SiteHeader().render()
|
||||
|
||||
#expect(html.contains(#"href="/sign-in""#))
|
||||
#expect(html.contains("Open a shop"))
|
||||
#expect(!html.contains(#"href="/account""#))
|
||||
#expect(!html.contains(#"href="/messages""#))
|
||||
}
|
||||
|
||||
@Test
|
||||
func `renders the signed-in actions for a viewer`() {
|
||||
let html = SiteHeader(viewer: .init(
|
||||
displayName: "Mara Visser",
|
||||
newWantMatches: 2,
|
||||
unreadMessages: 3
|
||||
)).render()
|
||||
|
||||
#expect(html.contains(#"aria-label="Want list, 2 new matches""#))
|
||||
#expect(html.contains(#"aria-label="Messages, 3 unread""#))
|
||||
#expect(html.contains(#"href="/sell""#))
|
||||
#expect(html.contains(">MV<"))
|
||||
#expect(!html.contains(#"href="/sign-in""#))
|
||||
}
|
||||
|
||||
@Test
|
||||
func `omits a badge that counts nothing`() {
|
||||
let html = SiteHeader(viewer: .init(displayName: "Mara")).render()
|
||||
|
||||
#expect(html.contains(#"aria-label="Messages""#))
|
||||
#expect(!html.contains("site-header__badge"))
|
||||
}
|
||||
|
||||
@Test
|
||||
func `links every format and marks none current by default`() {
|
||||
let html = SiteHeader().render()
|
||||
|
||||
for format in Format.allCases {
|
||||
#expect(html.contains(#"href="\#(format.path)""#))
|
||||
}
|
||||
|
||||
#expect(!html.contains("aria-current"))
|
||||
}
|
||||
|
||||
@Test(arguments: Format.allCases)
|
||||
func `marks the active format alone as current`(
|
||||
_ format: Format
|
||||
) {
|
||||
let html = SiteHeader(active: format).render()
|
||||
|
||||
#expect(html.components(separatedBy: #"aria-current="page""#).count - 1 == 1)
|
||||
#expect(html.contains(#"href="\#(format.path)" aria-current="page""#))
|
||||
}
|
||||
|
||||
@Test
|
||||
func `searches through a plain GET form`() {
|
||||
let html = SiteHeader().render()
|
||||
|
||||
#expect(html.contains(#"action="/search""#))
|
||||
#expect(html.contains(#"method="get""#))
|
||||
#expect(html.contains(#"name="q""#))
|
||||
#expect(html.contains(#"for="site-search-query""#))
|
||||
}
|
||||
|
||||
}
|
||||
Reference in new issue
Block a user