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"] ) } }