From 9115e25017a3f03e539f532b5583e63c255e7373 Mon Sep 17 00:00:00 2001 From: Otavio Cordeiro Date: Wed, 17 Dec 2025 09:43:03 +0100 Subject: [PATCH] Use .jpg extension for all image preview URLs All preview images generated by the backend are JPEG format, regardless of the original image format (e.g., foo.png -> foo.preview.jpg). Updated the imagePreviewURL getter, its documentation, and all tests to reflect this behavior. --- .../URL+ImagePreview.swift | 19 ++++++------- .../URLImagePreviewTests.swift | 28 +++++++++---------- 2 files changed, 22 insertions(+), 25 deletions(-) diff --git a/Packages/FoundationExtensions/Sources/FoundationExtensions/URL+ImagePreview.swift b/Packages/FoundationExtensions/Sources/FoundationExtensions/URL+ImagePreview.swift index 42d09d9..8466f26 100644 --- a/Packages/FoundationExtensions/Sources/FoundationExtensions/URL+ImagePreview.swift +++ b/Packages/FoundationExtensions/Sources/FoundationExtensions/URL+ImagePreview.swift @@ -2,14 +2,15 @@ import Foundation public extension URL { - /// Creates a preview URL by appending `.preview` before the file extension. + /// Creates a preview URL by appending `.preview.jpg` to the filename without its extension. /// - /// This property generates a preview version of an image URL by inserting - /// `.preview` between the filename and its extension. This is commonly used - /// for generating thumbnail or preview versions of images. + /// This property generates a preview version of an image URL. All preview images + /// generated by the backend are JPEG format, regardless of the original image format. + /// The preview URL is constructed by taking the filename (without extension), appending + /// `.preview`, and then adding the `.jpg` extension. /// - /// - Returns: A new URL with `.preview` inserted before the file extension - /// - Example: `https://cdn.some.pics/user/image.jpg` → `https://cdn.some.pics/user/image.preview.jpg` + /// - Returns: A new URL with `.preview.jpg` replacing the original file extension + /// - Example: `https://cdn.some.pics/user/image.png` → `https://cdn.some.pics/user/image.preview.jpg` var imagePreviewURL: URL { let pathExtension = pathExtension let lastPathComponent = lastPathComponent @@ -19,11 +20,7 @@ public extension URL { lastPathComponent.dropLast(pathExtension.count + (pathExtension.isEmpty ? 0 : 1)) ) - let newFilename = if pathExtension.isEmpty { - "\(filenameWithoutExtension).preview" - } else { - "\(filenameWithoutExtension).preview.\(pathExtension)" - } + let newFilename = "\(filenameWithoutExtension).preview.jpg" return baseURL.appendingPathComponent(newFilename) } diff --git a/Packages/FoundationExtensions/Tests/FoundationExtensionsTests/URLImagePreviewTests.swift b/Packages/FoundationExtensions/Tests/FoundationExtensionsTests/URLImagePreviewTests.swift index 2c34414..bddecfb 100644 --- a/Packages/FoundationExtensions/Tests/FoundationExtensionsTests/URLImagePreviewTests.swift +++ b/Packages/FoundationExtensions/Tests/FoundationExtensionsTests/URLImagePreviewTests.swift @@ -14,7 +14,7 @@ final class URLImagePreviewTests: XCTestCase { XCTAssertEqual( result.absoluteString, "https://cdn.some.pics/user/image.preview.jpg", - "It should insert .preview before the file extension" + "It should replace the file extension with .preview.jpg" ) } @@ -28,8 +28,8 @@ final class URLImagePreviewTests: XCTestCase { // Then XCTAssertEqual( result.absoluteString, - "https://example.com/photos/sunset.preview.png", - "It should insert .preview before PNG extension" + "https://example.com/photos/sunset.preview.jpg", + "It should replace PNG extension with .preview.jpg" ) } @@ -43,8 +43,8 @@ final class URLImagePreviewTests: XCTestCase { // Then XCTAssertEqual( result.absoluteString, - "https://example.com/images/photo.preview", - "It should append .preview when there is no file extension" + "https://example.com/images/photo.preview.jpg", + "It should append .preview.jpg when there is no file extension" ) } @@ -58,8 +58,8 @@ final class URLImagePreviewTests: XCTestCase { // Then XCTAssertEqual( result.absoluteString, - "https://cdn.example.com/user-uploads/my-vacation-photo.preview.jpeg", - "It should handle complex filenames with hyphens" + "https://cdn.example.com/user-uploads/my-vacation-photo.preview.jpg", + "It should replace the extension with .preview.jpg for complex filenames" ) } @@ -74,7 +74,7 @@ final class URLImagePreviewTests: XCTestCase { XCTAssertEqual( result.absoluteString, "https://api.example.com/images/photo.preview.jpg?size=large&quality=high", - "It should preserve query parameters in the preview URL" + "It should preserve query parameters and use .preview.jpg extension" ) } @@ -88,8 +88,8 @@ final class URLImagePreviewTests: XCTestCase { // Then XCTAssertEqual( result.absoluteString, - "https://storage.example.com/users/123/albums/vacation/beach.preview.gif", - "It should maintain the full directory structure" + "https://storage.example.com/users/123/albums/vacation/beach.preview.jpg", + "It should maintain the full directory structure and use .preview.jpg extension" ) } @@ -103,8 +103,8 @@ final class URLImagePreviewTests: XCTestCase { // Then XCTAssertEqual( result.path, - "/Users/test/Documents/screenshot.preview.png", - "It should work with local file URLs" + "/Users/test/Documents/screenshot.preview.jpg", + "It should work with local file URLs and use .preview.jpg extension" ) } @@ -119,7 +119,7 @@ final class URLImagePreviewTests: XCTestCase { XCTAssertEqual( result.absoluteString, "https://example.com/files/image.backup.preview.jpg", - "It should insert .preview before the last extension when multiple dots exist" + "It should replace the last extension with .preview.jpg when multiple dots exist" ) } @@ -134,7 +134,7 @@ final class URLImagePreviewTests: XCTestCase { XCTAssertEqual( result.absoluteString, "https://example.com/a.preview.jpg", - "It should handle single character filenames" + "It should handle single character filenames and use .preview.jpg extension" ) } }