137 lines
5.5 KiB
Swift
137 lines
5.5 KiB
Swift
import Foundation
|
|||
|
|
import Testing
|
||
|
|
|
||
|
|
@testable import Persistence
|
||
|
|
|
||
|
|
@Suite(
|
||
|
|
"ListingDraft model",
|
||
|
|
.tags(.model)
|
||
|
|
)
|
||
|
|
struct ListingDraftTests {
|
||
|
|
|
||
|
|
// MARK: Computed tests
|
||
|
|
|
||
|
|
@Test
|
||
|
|
func `titles a copy by its format`() {
|
||
|
|
#expect(Self.draft().title == "Nightward #3")
|
||
|
|
#expect(Self.draft(format: "manga").title == "Nightward, Vol. 3")
|
||
|
|
#expect(Self.draft(issue: "", format: "hardcovers").title == "Nightward")
|
||
|
|
}
|
||
|
|
|
||
|
|
@Test
|
||
|
|
func `words the printing short and in full`() {
|
||
|
|
#expect(Self.draft().printingLabel == "1st print")
|
||
|
|
#expect(Self.draft().printingDetail == "First printing, direct edition")
|
||
|
|
#expect(Self.draft(format: "manga", printing: 2, edition: "").printingLabel == "2nd printing")
|
||
|
|
#expect(Self.draft(printing: 0, edition: "").printingDetail == "Later printing")
|
||
|
|
}
|
||
|
|
|
||
|
|
@Test
|
||
|
|
func `letters the placeholder cover over a few lines, toned by the series`() {
|
||
|
|
let cover = Self.draft(series: "The Gilded Hour of Saints", format: "trade-paperbacks").cover
|
||
|
|
|
||
|
|
#expect(cover.title == "THE GILDED\nHOUR OF\nSAINTS")
|
||
|
|
#expect(cover.number == "TPB")
|
||
|
|
#expect(cover.imprint == "MERIDIAN COMICS")
|
||
|
|
#expect(ListingDraft.tones.contains(cover.tone))
|
||
|
|
#expect(Self.draft(issue: "1").cover.tone == Self.draft(issue: "2").cover.tone)
|
||
|
|
#expect(Self.draft(format: "manga").cover.number == "VOL 3")
|
||
|
|
}
|
||
|
|
|
||
|
|
// MARK: Methods tests
|
||
|
|
|
||
|
|
@Test
|
||
|
|
func `publishes as a listing carrying what was declared`() {
|
||
|
|
let listing = Self.draft().listing(slug: "nightward-3-raw-nm", shop: Seed.shops[0], at: .init(timeIntervalSince1970: 0))
|
||
|
|
|
||
|
|
#expect(listing.seriesTitle == "Nightward (2019 series)")
|
||
|
|
#expect(listing.issueLabel == "#3")
|
||
|
|
#expect(listing.isFirstPrint)
|
||
|
|
#expect(listing.gradeLabel == "Raw · NM")
|
||
|
|
#expect(listing.defects == ["Spine stress / ticks"])
|
||
|
|
#expect(listing.photos == ["/uploads/a.jpg"])
|
||
|
|
#expect(listing.declaration == "Declared defects: Spine stress / ticks. Two ticks near the top staple.")
|
||
|
|
#expect(listing.isAvailable)
|
||
|
|
}
|
||
|
|
|
||
|
|
@Test(arguments: zip(
|
||
|
|
["Nightward #1 CGC 9.8", "Hollow Comet, Vol. 4 — Sōkai", " Raw · NM+ ", "???"],
|
||
|
|
["nightward-1-cgc-9-8", "hollow-comet-vol-4-sokai", "raw-nm", ""]
|
||
|
|
))
|
||
|
|
func `slugs a title down to letters, digits, and hyphens`(
|
||
|
|
_ title: String,
|
||
|
|
expects slug: String
|
||
|
|
) {
|
||
|
|
#expect(ListingDraft.slug(title) == slug)
|
||
|
|
}
|
||
|
|
|
||
|
|
// MARK: Repository tests
|
||
|
|
|
||
|
|
@Test
|
||
|
|
func `publishes into the seller's shop, under a slug of its own, and into the search`() async throws {
|
||
|
|
try await withDatabase { fluent in
|
||
|
|
let catalogue = CatalogueRepository(fluent: fluent)
|
||
|
|
let joost = try await AccountRepository(fluent: fluent).account(email: "joost@kestrelrow.example")
|
||
|
|
let first = try #require(try await catalogue.publish(Self.draft(), by: joost))
|
||
|
|
let second = try #require(try await catalogue.publish(Self.draft(), by: joost))
|
||
|
|
let found = try await catalogue.listing(slug: first.slug)
|
||
|
|
let newest = try await catalogue.listings().first
|
||
|
|
|
||
|
|
#expect(first.slug == "nightward-3-raw-nm")
|
||
|
|
#expect(second.slug == "nightward-3-raw-nm-2")
|
||
|
|
#expect(first.shop.slug == "kestrel-row-comics")
|
||
|
|
#expect(found?.defects == ["Spine stress / ticks"])
|
||
|
|
#expect(found?.photos == ["/uploads/a.jpg"])
|
||
|
|
#expect(newest?.slug == second.slug)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
@Test
|
||
|
|
func `publishes nothing for an account without a shop`() async throws {
|
||
|
|
try await withDatabase { fluent in
|
||
|
|
let mara = try await AccountRepository(fluent: fluent).account(email: "mara.v@example.com")
|
||
|
|
let listing = try await CatalogueRepository(fluent: fluent).publish(Self.draft(), by: mara)
|
||
|
|
|
||
|
|
#expect(listing == nil)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
@Test
|
||
|
|
func `freezes the declared defects into a sale`() async throws {
|
||
|
|
try await withDatabase { fluent in
|
||
|
|
let accounts = AccountRepository(fluent: fluent)
|
||
|
|
let joost = try await accounts.account(email: "joost@kestrelrow.example")
|
||
|
|
let mara = try await accounts.account(email: "mara.v@example.com")
|
||
|
|
let listing = try #require(try await CatalogueRepository(fluent: fluent).publish(Self.draft(), by: joost))
|
||
|
|
let trade = TradeRepository(fluent: fluent)
|
||
|
|
let number = try await trade.buy(listing: listing.slug, buyer: mara)
|
||
|
|
let sale = try await trade.sale(number: number, for: mara)
|
||
|
|
|
||
|
|
#expect(sale?.declared.notes == "Declared defects: Spine stress / ticks. Two ticks near the top staple.")
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
// MARK: - Helpers
|
||
|
|
|
||
|
|
extension ListingDraftTests {
|
||
|
|
|
||
|
|
/// A draft of a raw Nightward #3 with one declared defect and one photo, unless told otherwise.
|
||
|
|
static func draft(
|
||
|
|
series: String = "Nightward",
|
||
|
|
issue: String = "3",
|
||
|
|
format: String = "single-issues",
|
||
|
|
printing: Int = 1,
|
||
|
|
edition: String = "Direct"
|
||
|
|
) -> ListingDraft {
|
||
|
|
.init(
|
||
|
|
series: series, issue: issue, publisher: "Meridian Comics", year: 2019, format: format,
|
||
|
|
printing: printing, edition: edition, grader: nil, grade: 9.4, condition: "NM", certNumber: nil,
|
||
|
|
pageQuality: nil, keyNotes: nil, defects: ["Spine stress / ticks"],
|
||
|
|
sellerNotes: "Two ticks near the top staple.", priceCents: 3_000, shippingCents: 500,
|
||
|
|
acceptsOffers: true, photos: ["/uploads/a.jpg"]
|
||
|
|
)
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|