import Foundation import Testing @testable import Persistence @Suite( "CollectingRepository repository", .tags(.repository) ) struct CollectingRepositoryTests { // MARK: Wants tests @Test func `matches a want within its limits, shipping from the EU alone`() async throws { try await withDatabase { fluent in let collecting = CollectingRepository(fluent: fluent) let mara = try await AccountRepository(fluent: fluent).account(email: "mara.v@example.com") try await collecting.addWant(title: " Nightward #1 ", minGrade: 9.0, maxPriceCents: 20_000, slabbedOnly: false, for: mara) try await collecting.addWant(title: " ", minGrade: nil, maxPriceCents: nil, slabbedOnly: false, for: mara) let wants = try await collecting.wants(of: mara) let want = try #require(wants.first) #expect(wants.count == 1) #expect(want.title == "Nightward #1") // The raw NM at €120 from Antwerp; the €150 CGC 9.4 ships from the UK, and the rest cost more or grade lower. #expect(want.matches.map(\.slug) == ["nightward-1-raw-nm"]) #expect(want.newMatchCount == 1) #expect(want.alerts) } } @Test func `counts a match as new until the wants are looked at, and again when a copy is listed`() async throws { try await withDatabase { fluent in let clock = Clock() let collecting = CollectingRepository(fluent: fluent, now: clock.now) let accounts = AccountRepository(fluent: fluent) let mara = try await accounts.account(email: "mara.v@example.com") let joost = try await accounts.account(email: "joost@kestrelrow.example") try await collecting.addWant(title: "Nightward #3", minGrade: nil, maxPriceCents: nil, slabbedOnly: false, for: mara) let nothing = try await collecting.newMatchCount(for: mara) _ = try await CatalogueRepository(fluent: fluent).publish(ListingDraftTests.draft(), by: joost, at: clock.now()) clock.advance(by: 60) let listed = try await collecting.newMatchCount(for: mara) try await collecting.markWantsSeen(by: mara) let seen = try await collecting.newMatchCount(for: mara) let stillMatching = try await collecting.wants(of: mara).first?.matches.count #expect(nothing == 0) #expect(listed == 1) #expect(seen == 0) #expect(stillMatching == 1) } } @Test func `keeps a want's alerts and removal to its owner`() async throws { try await withDatabase { fluent in let collecting = CollectingRepository(fluent: fluent) let accounts = AccountRepository(fluent: fluent) let mara = try await accounts.account(email: "mara.v@example.com") let sam = try await accounts.account(email: "sam@example.com") try await collecting.addWant(title: "Nightward #1", minGrade: nil, maxPriceCents: nil, slabbedOnly: true, for: mara) let id = try #require(try await collecting.wants(of: mara).first?.id) try await collecting.toggleAlerts(ofWant: id, of: sam) try await collecting.removeWant(id, of: sam) let untouched = try await collecting.wants(of: mara) try await collecting.toggleAlerts(ofWant: id, of: mara) let silenced = try await collecting.wants(of: mara) let quiet = try await collecting.newMatchCount(for: mara) try await collecting.removeWant(id, of: mara) let removed = try await collecting.wants(of: mara) #expect(untouched.first?.alerts == true) #expect(untouched.first?.matches.allSatisfy(\.isSlabbed) == true) #expect(silenced.first?.alerts == false) #expect(quiet == 0) #expect(removed.isEmpty) } } // MARK: Series tests @Test func `knows the seeded runs, and makes up a series it only knows from its listings`() async throws { try await withDatabase { fluent in let collecting = CollectingRepository(fluent: fluent) let all = try await collecting.allSeries() let nightward = try await collecting.series(slug: "nightward") let listedOnly = try await collecting.series(slug: "hollow-comet") let unknown = try await collecting.series(slug: "no-such-series") #expect(all.map(\.slug) == ["echo-country", "ferrous-saint", "nightward", "paper-tigers", "vermilion-lake"]) #expect(nightward?.issueCount == 24) #expect(listedOnly?.name == "Hollow Comet") #expect(listedOnly?.issueCount == 0) #expect(unknown == nil) } } @Test func `derives a listing's series and issue number from what it states`() { let single = Seed.listings[0] let manga = Seed.listings[5] #expect(single.seriesName == "Nightward") #expect(single.seriesSlug == "nightward") #expect(single.issueNumber == 1) #expect(manga.seriesSlug == "hollow-comet") #expect(manga.issueNumber == nil) } }