From 31e4ca98802a97bd709623eaf1d56b5a38acd6e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Menu?= Date: Wed, 27 Nov 2024 16:21:22 +0100 Subject: [PATCH] Fix `PublicationService.get()` --- Sources/Shared/Publication/Publication.swift | 7 +++++-- .../Services/Cover/GeneratedCoverService.swift | 4 ++-- .../Services/Positions/PositionsService.swift | 4 ++-- .../Shared/Publication/Services/PublicationService.swift | 9 ++++++--- .../ContentProtectionServiceTests.swift | 6 +++--- .../Services/Cover/GeneratedCoverServiceTests.swift | 2 +- .../Services/Positions/PositionsServiceTests.swift | 4 ++-- 7 files changed, 21 insertions(+), 15 deletions(-) diff --git a/Sources/Shared/Publication/Publication.swift b/Sources/Shared/Publication/Publication.swift index 0c91ff6ae..39a5298b7 100644 --- a/Sources/Shared/Publication/Publication.swift +++ b/Sources/Shared/Publication/Publication.swift @@ -6,6 +6,7 @@ import CoreServices import Foundation +import ReadiumInternal /// Shared model for a Readium Publication. public class Publication: Closeable, Loggable { @@ -90,8 +91,10 @@ public class Publication: Closeable, Loggable { /// Returns the resource targeted by the given `href`. public func get(_ href: T) -> Resource? { - // Try first the original href and falls back to href without query and fragment. - container[href] ?? container[href.anyURL.removingQuery().removingFragment()] + services.first { $0.get(href) } + // Try first the original href and falls back to href without query and fragment. + ?? container[href] + ?? container[href.anyURL.removingQuery().removingFragment()] } /// Closes any opened resource associated with the `Publication`, including `services`. diff --git a/Sources/Shared/Publication/Services/Cover/GeneratedCoverService.swift b/Sources/Shared/Publication/Services/Cover/GeneratedCoverService.swift index d3f3cb41e..21ffc03d1 100644 --- a/Sources/Shared/Publication/Services/Cover/GeneratedCoverService.swift +++ b/Sources/Shared/Publication/Services/Cover/GeneratedCoverService.swift @@ -43,8 +43,8 @@ public final class GeneratedCoverService: CoverService { public var links: [Link] { [coverLink] } - public func get(link: Link) -> Resource? { - guard link.href == coverLink.href else { + public func get(_ href: T) -> (any Resource)? where T: URLConvertible { + guard href.anyURL.isEquivalentTo(coverLink.url()) else { return nil } diff --git a/Sources/Shared/Publication/Services/Positions/PositionsService.swift b/Sources/Shared/Publication/Services/Positions/PositionsService.swift index 6faeb6d12..1bc926007 100644 --- a/Sources/Shared/Publication/Services/Positions/PositionsService.swift +++ b/Sources/Shared/Publication/Services/Positions/PositionsService.swift @@ -33,8 +33,8 @@ private let positionsLink = Link( public extension PositionsService { var links: [Link] { [positionsLink] } - func get(link: Link) -> Resource? { - guard link.href == positionsLink.href else { + func get(_ href: T) -> (any Resource)? where T: URLConvertible { + guard href.anyURL.isEquivalentTo(positionsLink.url()) else { return nil } return PositionsResource(positions: positions) diff --git a/Sources/Shared/Publication/Services/PublicationService.swift b/Sources/Shared/Publication/Services/PublicationService.swift index 9c8e87cc5..559bc3218 100644 --- a/Sources/Shared/Publication/Services/PublicationService.swift +++ b/Sources/Shared/Publication/Services/PublicationService.swift @@ -31,14 +31,17 @@ public protocol PublicationService: Closeable { /// /// Called by `Publication.get()` for each request. /// - /// - Returns: The Resource containing the response, or null if the service doesn't recognize - /// this request. - func get(link: Link) -> Resource? + /// - Returns: The Resource containing the response, or null if the service + /// doesn't recognize this request. + func get(_ href: T) -> Resource? } public extension PublicationService { var links: [Link] { [] } + func get(_ href: T) -> Resource? { nil } + + @available(*, unavailable, message: "Use get(URLConvertible) instead") func get(link: Link) -> Resource? { nil } } diff --git a/Tests/SharedTests/Publication/Services/Content Protection/ContentProtectionServiceTests.swift b/Tests/SharedTests/Publication/Services/Content Protection/ContentProtectionServiceTests.swift index 69d49ff8f..b4629d7a0 100644 --- a/Tests/SharedTests/Publication/Services/Content Protection/ContentProtectionServiceTests.swift +++ b/Tests/SharedTests/Publication/Services/Content Protection/ContentProtectionServiceTests.swift @@ -11,7 +11,7 @@ class ContentProtectionServiceTests: XCTestCase { func testGetUnknown() { let service = TestContentProtectionService() - let resource = service.get(link: Link(href: "/unknown")) + let resource = service.get(AnyURL(string: "/unknown")!) XCTAssertNil(resource) } @@ -93,11 +93,11 @@ struct TestContentProtectionService: ContentProtectionService { var name: LocalizedString? = nil func getCopy(text: String, peek: Bool) throws -> Resource { - try XCTUnwrap(get(link: Link(href: "~readium/rights/copy?text=\(text)&peek=\(peek)"))) + try XCTUnwrap(get(AnyURL(string: "~readium/rights/copy?text=\(text)&peek=\(peek)")!)) } func getPrint(pageCount: Int, peek: Bool) throws -> Resource { - try XCTUnwrap(get(link: Link(href: "~readium/rights/print?pageCount=\(pageCount)&peek=\(peek)"))) + try XCTUnwrap(get(AnyURL(string: "~readium/rights/print?pageCount=\(pageCount)&peek=\(peek)")!)) } } diff --git a/Tests/SharedTests/Publication/Services/Cover/GeneratedCoverServiceTests.swift b/Tests/SharedTests/Publication/Services/Cover/GeneratedCoverServiceTests.swift index e6b70cd34..4d0994b7c 100644 --- a/Tests/SharedTests/Publication/Services/Cover/GeneratedCoverServiceTests.swift +++ b/Tests/SharedTests/Publication/Services/Cover/GeneratedCoverServiceTests.swift @@ -29,7 +29,7 @@ class GeneratedCoverServiceTests: XCTestCase { GeneratedCoverService(cover: cover), GeneratedCoverService(makeCover: { .success(self.cover) }), ] { - let resource = try XCTUnwrap(service.get(link: Link(href: "~readium/cover"))) + let resource = try XCTUnwrap(service.get(AnyURL(string: "~readium/cover")!)) let result = await resource.read().map(UIImage.init) AssertImageEqual(result, .success(cover)) } diff --git a/Tests/SharedTests/Publication/Services/Positions/PositionsServiceTests.swift b/Tests/SharedTests/Publication/Services/Positions/PositionsServiceTests.swift index c36bc63de..d11aab904 100644 --- a/Tests/SharedTests/Publication/Services/Positions/PositionsServiceTests.swift +++ b/Tests/SharedTests/Publication/Services/Positions/PositionsServiceTests.swift @@ -123,7 +123,7 @@ class PositionsServiceTests: XCTestCase { func testGetPositions() async throws { let service = TestPositionsService(positions) - let resource = service.get(link: Link(href: "~readium/positions")) + let resource = service.get(AnyURL(string: "~readium/positions")!) let result = try await resource?.readAsString().get() XCTAssertEqual( @@ -137,7 +137,7 @@ class PositionsServiceTests: XCTestCase { func testGetUnknown() { let service = TestPositionsService(positions) - let resource = service.get(link: Link(href: "/unknown")) + let resource = service.get(AnyURL(string: "/unknown")!) XCTAssertNil(resource) }