Moved test database teardown into defer blocks and unified the one-decimal formatting in the Website service.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
06953a1be0
commit
e0524da525
16 files changed
+45
-73
No files matched your search
@@ -12,16 +12,12 @@ func withDatabase(
|
|||||||
logger: Logger(label: "test")
|
logger: Logger(label: "test")
|
||||||
)()
|
)()
|
||||||
|
|
||||||
do {
|
defer {
|
||||||
|
try? await fluent.shutdown()
|
||||||
|
}
|
||||||
|
|
||||||
await PrepareDB()(for: fluent)
|
await PrepareDB()(for: fluent)
|
||||||
|
|
||||||
try await fluent.migrate()
|
try await fluent.migrate()
|
||||||
try await body(fluent)
|
try await body(fluent)
|
||||||
} catch {
|
|
||||||
try? await fluent.shutdown()
|
|
||||||
|
|
||||||
throw error
|
|
||||||
}
|
|
||||||
|
|
||||||
try await fluent.shutdown()
|
|
||||||
}
|
}
|
||||||
@@ -18,7 +18,7 @@ extension Listing {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
"\(grader) \(grade.gradeLabel)",
|
"\(grader) \(grade.oneDecimal)",
|
||||||
grade >= 9 ? .good : grade < 7 ? .warn : .neutral,
|
grade >= 9 ? .good : grade < 7 ? .warn : .neutral,
|
||||||
true
|
true
|
||||||
)
|
)
|
||||||
@@ -72,7 +72,7 @@ extension Shop {
|
|||||||
|
|
||||||
/// The shop's standing in a line: where it is, since when, and how it is rated.
|
/// The shop's standing in a line: where it is, since when, and how it is rated.
|
||||||
var standing: String {
|
var standing: String {
|
||||||
"\(location) · selling on CCN since \(sinceYear) · \(rating.formatted(.number.precision(.fractionLength(1)).locale(.init(identifier: "en")))) from \(ratedSales) rated sales"
|
"\(location) · selling on CCN since \(sinceYear) · \(rating.oneDecimal) from \(ratedSales) rated sales"
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -81,8 +81,8 @@ extension Double {
|
|||||||
|
|
||||||
// MARK: Computed
|
// MARK: Computed
|
||||||
|
|
||||||
/// The grade to one decimal place, e.g. `9.8`.
|
/// The number to one decimal place, e.g. `9.8`.
|
||||||
var gradeLabel: String {
|
var oneDecimal: String {
|
||||||
formatted(.number.precision(.fractionLength(1)).locale(.init(identifier: "en")))
|
formatted(.number.precision(.fractionLength(1)).locale(.init(identifier: "en")))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -179,7 +179,7 @@ private extension ComparePage {
|
|||||||
of copy: Listing
|
of copy: Listing
|
||||||
) -> [(term: String, value: String)] {
|
) -> [(term: String, value: String)] {
|
||||||
let customs = copy.shop.shipsFromEU ? "" : " · customs may apply"
|
let customs = copy.shop.shipsFromEU ? "" : " · customs may apply"
|
||||||
let rating = copy.shop.rating.formatted(.number.precision(.fractionLength(1)).locale(.init(identifier: "en")))
|
let rating = copy.shop.rating.oneDecimal
|
||||||
|
|
||||||
return [
|
return [
|
||||||
("Asking", copy.priceCents.euros + (copy.acceptsOffers ? " · accepts offers" : "")),
|
("Asking", copy.priceCents.euros + (copy.acceptsOffers ? " · accepts offers" : "")),
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ extension GradingGuidePage: Page {
|
|||||||
ForEach(Grading.scale) { step in
|
ForEach(Grading.scale) { step in
|
||||||
li(.class("guide__grade")) {
|
li(.class("guide__grade")) {
|
||||||
strong {
|
strong {
|
||||||
step.grade.gradeLabel
|
step.grade.oneDecimal
|
||||||
}
|
}
|
||||||
span {
|
span {
|
||||||
step.code
|
step.code
|
||||||
@@ -83,7 +83,7 @@ extension GradingGuidePage: Page {
|
|||||||
li(.class("card guide__reference")) {
|
li(.class("card guide__reference")) {
|
||||||
div(.class("guide__reference-grade")) {
|
div(.class("guide__reference-grade")) {
|
||||||
span(.class("type-stat")) {
|
span(.class("type-stat")) {
|
||||||
reference.grade.gradeLabel
|
reference.grade.oneDecimal
|
||||||
}
|
}
|
||||||
span(.class("type-label")) {
|
span(.class("type-label")) {
|
||||||
reference.name
|
reference.name
|
||||||
@@ -94,7 +94,7 @@ extension GradingGuidePage: Page {
|
|||||||
.class("guide__photo"),
|
.class("guide__photo"),
|
||||||
.custom(name: "aria-hidden", value: "true")
|
.custom(name: "aria-hidden", value: "true")
|
||||||
) {
|
) {
|
||||||
"Photo: \(reference.grade.gradeLabel) example"
|
"Photo: \(reference.grade.oneDecimal) example"
|
||||||
}
|
}
|
||||||
div {
|
div {
|
||||||
h3(.class("type-eyebrow guide__allowed")) {
|
h3(.class("type-eyebrow guide__allowed")) {
|
||||||
|
|||||||
@@ -213,7 +213,7 @@ private extension NewListingPage {
|
|||||||
mode(.raw, "Raw (seller-graded)", "You grade it against the guide and declare every defect.")
|
mode(.raw, "Raw (seller-graded)", "You grade it against the guide and declare every defect.")
|
||||||
}
|
}
|
||||||
div(.class("listing-form__grid")) {
|
div(.class("listing-form__grid")) {
|
||||||
select(.grade, "Grade", options: [("", "Pick a grade")] + Grading.scale.map { ($0.grade.gradeLabel, "\($0.grade.gradeLabel) · \($0.code)") })
|
select(.grade, "Grade", options: [("", "Pick a grade")] + Grading.scale.map { ($0.grade.oneDecimal, "\($0.grade.oneDecimal) · \($0.code)") })
|
||||||
select(.grader, "Grader", options: [("", "—")] + Grading.graders.map { ($0, $0) }, scope: "slabbed")
|
select(.grader, "Grader", options: [("", "—")] + Grading.graders.map { ($0, $0) }, scope: "slabbed")
|
||||||
select(.pageQuality, "Page quality", options: [("", "Not stated")] + Grading.pageQualities.map { ($0, $0) }, scope: "slabbed")
|
select(.pageQuality, "Page quality", options: [("", "Not stated")] + Grading.pageQualities.map { ($0, $0) }, scope: "slabbed")
|
||||||
text(.cert, "Cert number", placeholder: "4312087-002", scope: "slabbed")
|
text(.cert, "Cert number", placeholder: "4312087-002", scope: "slabbed")
|
||||||
|
|||||||
@@ -112,7 +112,7 @@ extension SellerDashboardPage: Page {
|
|||||||
tile("\(offers.count)", "Open offers", offers.first.map { "next: \($0.expiresAt.countdown(from: now))" })
|
tile("\(offers.count)", "Open offers", offers.first.map { "next: \($0.expiresAt.countdown(from: now))" })
|
||||||
tile("\(viewer?.unreadMessages ?? 0)", "Unread conversations", nil)
|
tile("\(viewer?.unreadMessages ?? 0)", "Unread conversations", nil)
|
||||||
tile("\(sales.count)", "Sales", "\(sales.count { $0.next == .sent }) awaiting your dispatch")
|
tile("\(sales.count)", "Sales", "\(sales.count { $0.next == .sent }) awaiting your dispatch")
|
||||||
tile(shop.rating.formatted(.number.precision(.fractionLength(1)).locale(.init(identifier: "en"))), "Rating", "\(shop.ratedSales) rated sales")
|
tile(shop.rating.oneDecimal, "Rating", "\(shop.ratedSales) rated sales")
|
||||||
}
|
}
|
||||||
section(.class("card sell__panel")) {
|
section(.class("card sell__panel")) {
|
||||||
div(.class("section-head")) {
|
div(.class("section-head")) {
|
||||||
|
|||||||
@@ -219,8 +219,8 @@ private extension WantsPage {
|
|||||||
SelectField(
|
SelectField(
|
||||||
name: "min-grade",
|
name: "min-grade",
|
||||||
title: "Lowest grade",
|
title: "Lowest grade",
|
||||||
options: [("", "Any grade")] + Grading.scale.map { ($0.grade.gradeLabel, "\($0.grade.gradeLabel) · \($0.code)") },
|
options: [("", "Any grade")] + Grading.scale.map { ($0.grade.oneDecimal, "\($0.grade.oneDecimal) · \($0.code)") },
|
||||||
selected: draft.minGrade?.gradeLabel ?? ""
|
selected: draft.minGrade?.oneDecimal ?? ""
|
||||||
)
|
)
|
||||||
TextField(
|
TextField(
|
||||||
name: "max-price",
|
name: "max-price",
|
||||||
@@ -260,7 +260,7 @@ private extension WantsPage {
|
|||||||
) -> String {
|
) -> String {
|
||||||
[
|
[
|
||||||
want.slabbedOnly ? "slabbed only" : nil,
|
want.slabbedOnly ? "slabbed only" : nil,
|
||||||
want.minGrade.map { "grade ≥ \($0.gradeLabel)" },
|
want.minGrade.map { "grade ≥ \($0.oneDecimal)" },
|
||||||
want.maxPriceCents.map { "max \($0.euros)" },
|
want.maxPriceCents.map { "max \($0.euros)" },
|
||||||
"ships from EU only",
|
"ships from EU only",
|
||||||
]
|
]
|
||||||
@@ -275,7 +275,7 @@ private extension WantsPage {
|
|||||||
var parameters = SearchParameters().setting(.query, to: want.title.replacingOccurrences(of: "·", with: " "))
|
var parameters = SearchParameters().setting(.query, to: want.title.replacingOccurrences(of: "·", with: " "))
|
||||||
|
|
||||||
if let minGrade = want.minGrade {
|
if let minGrade = want.minGrade {
|
||||||
parameters = parameters.setting(.gradeMin, to: minGrade.gradeLabel)
|
parameters = parameters.setting(.gradeMin, to: minGrade.oneDecimal)
|
||||||
}
|
}
|
||||||
|
|
||||||
if let maxPriceCents = want.maxPriceCents {
|
if let maxPriceCents = want.maxPriceCents {
|
||||||
|
|||||||
@@ -190,7 +190,7 @@ extension ListingForm {
|
|||||||
if defects.contains(.caseScuffs) {
|
if defects.contains(.caseScuffs) {
|
||||||
problems[.defects] = "Case scuffs are for slabs; this copy is raw."
|
problems[.defects] = "Case scuffs are for slabs; this copy is raw."
|
||||||
} else if defects.contains(.crease), let grade, grade > Grading.creaseCap {
|
} else if defects.contains(.crease), let grade, grade > Grading.creaseCap {
|
||||||
problems[.defects] = "A colour-breaking crease caps a raw book at \(Grading.creaseCap.gradeLabel). Lower the grade, or untick the crease."
|
problems[.defects] = "A colour-breaking crease caps a raw book at \(Grading.creaseCap.oneDecimal). Lower the grade, or untick the crease."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -125,7 +125,7 @@ extension SearchParameters {
|
|||||||
|
|
||||||
if filter.gradeMin != nil || filter.gradeMax != nil {
|
if filter.gradeMin != nil || filter.gradeMax != nil {
|
||||||
pills.append(.init(
|
pills.append(.init(
|
||||||
label: "Grade \((filter.gradeMin ?? 0.5).gradeLabel)–\((filter.gradeMax ?? 10).gradeLabel)",
|
label: "Grade \((filter.gradeMin ?? 0.5).oneDecimal)–\((filter.gradeMax ?? 10).oneDecimal)",
|
||||||
removed: removing(.gradeMin).removing(.gradeMax)
|
removed: removing(.gradeMin).removing(.gradeMax)
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ struct SellingPagesTests {
|
|||||||
let html = GradingGuidePage().render()
|
let html = GradingGuidePage().render()
|
||||||
|
|
||||||
for step in Grading.scale {
|
for step in Grading.scale {
|
||||||
#expect(html.contains("<strong>\(step.grade.gradeLabel)</strong><span>\(step.code)</span>"))
|
#expect(html.contains("<strong>\(step.grade.oneDecimal)</strong><span>\(step.code)</span>"))
|
||||||
}
|
}
|
||||||
|
|
||||||
for defect in Grading.Defect.allCases {
|
for defect in Grading.Defect.allCases {
|
||||||
|
|||||||
+4
-8
@@ -256,7 +256,10 @@ private extension AccountAndCollectingControllerTests {
|
|||||||
logger: Logger(label: "test")
|
logger: Logger(label: "test")
|
||||||
)()
|
)()
|
||||||
|
|
||||||
do {
|
defer {
|
||||||
|
try? await fluent.shutdown()
|
||||||
|
}
|
||||||
|
|
||||||
await PrepareDB()(for: fluent)
|
await PrepareDB()(for: fluent)
|
||||||
|
|
||||||
try await fluent.migrate()
|
try await fluent.migrate()
|
||||||
@@ -273,13 +276,6 @@ private extension AccountAndCollectingControllerTests {
|
|||||||
router.addRoutes(CollectingController<WebsiteRequestContext>(collecting: collecting, catalogue: catalogue, sessions: sessions).routes)
|
router.addRoutes(CollectingController<WebsiteRequestContext>(collecting: collecting, catalogue: catalogue, sessions: sessions).routes)
|
||||||
|
|
||||||
try await Application(router: router).test(.router, body)
|
try await Application(router: router).test(.router, body)
|
||||||
} catch {
|
|
||||||
try? await fluent.shutdown()
|
|
||||||
|
|
||||||
throw error
|
|
||||||
}
|
|
||||||
|
|
||||||
try await fluent.shutdown()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-8
@@ -110,7 +110,10 @@ private extension CatalogueControllerTests {
|
|||||||
logger: Logger(label: "test")
|
logger: Logger(label: "test")
|
||||||
)()
|
)()
|
||||||
|
|
||||||
do {
|
defer {
|
||||||
|
try? await fluent.shutdown()
|
||||||
|
}
|
||||||
|
|
||||||
await PrepareDB()(for: fluent)
|
await PrepareDB()(for: fluent)
|
||||||
|
|
||||||
try await fluent.migrate()
|
try await fluent.migrate()
|
||||||
@@ -120,13 +123,6 @@ private extension CatalogueControllerTests {
|
|||||||
router.addRoutes(CatalogueController<WebsiteRequestContext>(repository: .init(fluent: fluent)).routes)
|
router.addRoutes(CatalogueController<WebsiteRequestContext>(repository: .init(fluent: fluent)).routes)
|
||||||
|
|
||||||
try await Application(router: router).test(.router, body)
|
try await Application(router: router).test(.router, body)
|
||||||
} catch {
|
|
||||||
try? await fluent.shutdown()
|
|
||||||
|
|
||||||
throw error
|
|
||||||
}
|
|
||||||
|
|
||||||
try await fluent.shutdown()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
+4
-8
@@ -204,7 +204,10 @@ private extension ListingFormControllerTests {
|
|||||||
logger: Logger(label: "test")
|
logger: Logger(label: "test")
|
||||||
)()
|
)()
|
||||||
|
|
||||||
do {
|
defer {
|
||||||
|
try? await fluent.shutdown()
|
||||||
|
}
|
||||||
|
|
||||||
await PrepareDB()(for: fluent)
|
await PrepareDB()(for: fluent)
|
||||||
|
|
||||||
try await fluent.migrate()
|
try await fluent.migrate()
|
||||||
@@ -226,13 +229,6 @@ private extension ListingFormControllerTests {
|
|||||||
try await Application(router: router).test(.router) { client in
|
try await Application(router: router).test(.router) { client in
|
||||||
try await body(client, folder)
|
try await body(client, folder)
|
||||||
}
|
}
|
||||||
} catch {
|
|
||||||
try? await fluent.shutdown()
|
|
||||||
|
|
||||||
throw error
|
|
||||||
}
|
|
||||||
|
|
||||||
try await fluent.shutdown()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+4
-8
@@ -156,7 +156,10 @@ private extension PasskeyControllerTests {
|
|||||||
logger: Logger(label: "test")
|
logger: Logger(label: "test")
|
||||||
)()
|
)()
|
||||||
|
|
||||||
do {
|
defer {
|
||||||
|
try? await fluent.shutdown()
|
||||||
|
}
|
||||||
|
|
||||||
await PrepareDB()(for: fluent)
|
await PrepareDB()(for: fluent)
|
||||||
|
|
||||||
try await fluent.migrate()
|
try await fluent.migrate()
|
||||||
@@ -170,13 +173,6 @@ private extension PasskeyControllerTests {
|
|||||||
).routes)
|
).routes)
|
||||||
|
|
||||||
try await Application(router: router).test(.router, body)
|
try await Application(router: router).test(.router, body)
|
||||||
} catch {
|
|
||||||
try? await fluent.shutdown()
|
|
||||||
|
|
||||||
throw error
|
|
||||||
}
|
|
||||||
|
|
||||||
try await fluent.shutdown()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
+4
-8
@@ -203,7 +203,10 @@ private extension SessionControllerTests {
|
|||||||
logger: Logger(label: "test")
|
logger: Logger(label: "test")
|
||||||
)()
|
)()
|
||||||
|
|
||||||
do {
|
defer {
|
||||||
|
try? await fluent.shutdown()
|
||||||
|
}
|
||||||
|
|
||||||
await PrepareDB()(for: fluent)
|
await PrepareDB()(for: fluent)
|
||||||
|
|
||||||
try await fluent.migrate()
|
try await fluent.migrate()
|
||||||
@@ -221,13 +224,6 @@ private extension SessionControllerTests {
|
|||||||
).routes)
|
).routes)
|
||||||
|
|
||||||
try await Application(router: router).test(.router, body)
|
try await Application(router: router).test(.router, body)
|
||||||
} catch {
|
|
||||||
try? await fluent.shutdown()
|
|
||||||
|
|
||||||
throw error
|
|
||||||
}
|
|
||||||
|
|
||||||
try await fluent.shutdown()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -320,7 +320,10 @@ private extension TradeControllerTests {
|
|||||||
logger: Logger(label: "test")
|
logger: Logger(label: "test")
|
||||||
)()
|
)()
|
||||||
|
|
||||||
do {
|
defer {
|
||||||
|
try? await fluent.shutdown()
|
||||||
|
}
|
||||||
|
|
||||||
await PrepareDB()(for: fluent)
|
await PrepareDB()(for: fluent)
|
||||||
|
|
||||||
try await fluent.migrate()
|
try await fluent.migrate()
|
||||||
@@ -335,13 +338,6 @@ private extension TradeControllerTests {
|
|||||||
router.addRoutes(TradeController<WebsiteRequestContext>(trade: trade, catalogue: catalogue, sessions: sessions).routes)
|
router.addRoutes(TradeController<WebsiteRequestContext>(trade: trade, catalogue: catalogue, sessions: sessions).routes)
|
||||||
|
|
||||||
try await Application(router: router).test(.router, body)
|
try await Application(router: router).test(.router, body)
|
||||||
} catch {
|
|
||||||
try? await fluent.shutdown()
|
|
||||||
|
|
||||||
throw error
|
|
||||||
}
|
|
||||||
|
|
||||||
try await fluent.shutdown()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user