From c80ff5bc992b6ab66562400dfed6cd601c8ec2cd Mon Sep 17 00:00:00 2001 From: Jeremy Massel <1123407+jkmassel@users.noreply.github.com> Date: Tue, 8 Sep 2026 14:00:21 -0600 Subject: [PATCH] test(ios): reuse ResizingProcessor instead of a second transcoding mock MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `TranscodingProcessor` duplicated `ResizingProcessor` — same `.processed(_, mimeType: "video/mp4", filename: "clip.mp4")` result, one call site — and was the weaker of the two. It wrote to a fixed `$TMPDIR/clip.mp4` instead of a per-call UUID path inside the managed upload directory, and swallowed the write with `try?`, so a failed write still returned `.processed(, …)` and the test passed green against a file that never existed. `ResizingProcessor` uses `try` and a unique path. Also drops `@unchecked Sendable` from `ThrowingUploader`, which has no stored properties and so satisfies `MediaUploader`'s inherited `Sendable` conformance on its own. The escape hatch is only needed by the mocks holding `NSLock`-guarded state; carrying it on a stateless one normalizes it as boilerplate, which is how an unsynchronized property gets added later without a diagnostic. `ContentTypeDeleteClient` keeps it — it subclasses `InternalMediaClient`, itself an `@unchecked Sendable` class, and must restate the conformance. --- .../Media/MediaUploadServerTests.swift | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/ios/Tests/GutenbergKitTests/Media/MediaUploadServerTests.swift b/ios/Tests/GutenbergKitTests/Media/MediaUploadServerTests.swift index 76d44b47a..e698fe890 100644 --- a/ios/Tests/GutenbergKitTests/Media/MediaUploadServerTests.swift +++ b/ios/Tests/GutenbergKitTests/Media/MediaUploadServerTests.swift @@ -708,7 +708,7 @@ struct MediaUploadServerTests { // those reads: a file admitted for processing was forwarded unprocessed. The // host dropping it before the request is the same condition, deterministically. let mockUploader = MockInternalMediaClient() - var processor: TranscodingProcessor? = TranscodingProcessor() + var processor: ResizingProcessor? = ResizingProcessor() weak let weakProcessor = processor let server = try await MediaUploadServer.start(processor: processor, internalClient: mockUploader) defer { server.stop() } @@ -1143,7 +1143,7 @@ private final class RecordingUploader: MediaUploader, @unchecked Sendable { /// An uploader whose delivery fails terminally, as one would after exhausting its own /// post-process recovery and force-deleting the orphan. -private final class ThrowingUploader: MediaUploader, @unchecked Sendable { +private final class ThrowingUploader: MediaUploader { struct Failure: Error {} func upload(_ upload: MediaUpload) async throws -> Data { @@ -1151,20 +1151,6 @@ private final class ThrowingUploader: MediaUploader, @unchecked Sendable { } } -/// A processor that transcodes, used to check the server holds it across the whole -/// request rather than re-reading a reference the host may have dropped. -private final class TranscodingProcessor: MediaProcessor, @unchecked Sendable { - func handlesFile(ofType mimeType: String, named filename: String) -> Bool { - true - } - - func processFile(at url: URL, mimeType: String, filename: String) async throws -> ProcessedProxyFile { - let processed = FileManager.default.temporaryDirectory.appendingPathComponent("clip.mp4") - try? Data("transcoded".utf8).write(to: processed) - return .processed(processed, mimeType: "video/mp4", filename: "clip.mp4") - } -} - private final class ProcessOnlyProcessor: MediaProcessor, @unchecked Sendable { private let lock = NSLock() private var _processFileCalled = false