mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-03 06:55:59 +00:00
Handle media source validation more gracefully. (#3571)
* Handle media source validation more gracefully. * Fix unit tests.
This commit is contained in:
@@ -10,12 +10,12 @@ import MatrixRustSDK
|
||||
import XCTest
|
||||
|
||||
final class MediaLoaderTests: XCTestCase {
|
||||
func testMediaRequestCoalescing() async {
|
||||
func testMediaRequestCoalescing() async throws {
|
||||
let mediaLoadingClient = ClientSDKMock()
|
||||
mediaLoadingClient.getMediaContentMediaSourceReturnValue = Data()
|
||||
let mediaLoader = MediaLoader(client: mediaLoadingClient)
|
||||
|
||||
let mediaSource = MediaSourceProxy(url: .mockMXCFile, mimeType: nil)
|
||||
let mediaSource = try MediaSourceProxy(url: .mockMXCFile, mimeType: nil)
|
||||
|
||||
do {
|
||||
for _ in 1...10 {
|
||||
@@ -28,12 +28,12 @@ final class MediaLoaderTests: XCTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
func testMediaThumbnailRequestCoalescing() async {
|
||||
func testMediaThumbnailRequestCoalescing() async throws {
|
||||
let mediaLoadingClient = ClientSDKMock()
|
||||
mediaLoadingClient.getMediaThumbnailMediaSourceWidthHeightReturnValue = Data()
|
||||
let mediaLoader = MediaLoader(client: mediaLoadingClient)
|
||||
|
||||
let mediaSource = MediaSourceProxy(url: .mockMXCImage, mimeType: nil)
|
||||
let mediaSource = try MediaSourceProxy(url: .mockMXCImage, mimeType: nil)
|
||||
|
||||
do {
|
||||
for _ in 1...10 {
|
||||
|
||||
@@ -36,7 +36,7 @@ final class MediaProviderTests: XCTestCase {
|
||||
return
|
||||
}
|
||||
|
||||
let loadTask = mediaProvider.loadImageRetryingOnReconnection(MediaSourceProxy(url: .mockMXCImage, mimeType: "image/jpeg"))
|
||||
let loadTask = try mediaProvider.loadImageRetryingOnReconnection(MediaSourceProxy(url: .mockMXCImage, mimeType: "image/jpeg"))
|
||||
|
||||
let connectivitySubject = CurrentValueSubject<NetworkMonitorReachability, Never>(.unreachable)
|
||||
|
||||
@@ -59,7 +59,7 @@ final class MediaProviderTests: XCTestCase {
|
||||
}
|
||||
|
||||
func testLoadingRetriedOnReconnectionCancelsAfterSecondFailure() async throws {
|
||||
let loadTask = mediaProvider.loadImageRetryingOnReconnection(MediaSourceProxy(url: .mockMXCImage, mimeType: "image/jpeg"))
|
||||
let loadTask = try mediaProvider.loadImageRetryingOnReconnection(MediaSourceProxy(url: .mockMXCImage, mimeType: "image/jpeg"))
|
||||
|
||||
let connectivitySubject = CurrentValueSubject<NetworkMonitorReachability, Never>(.reachable)
|
||||
|
||||
@@ -73,7 +73,7 @@ final class MediaProviderTests: XCTestCase {
|
||||
}
|
||||
|
||||
func test_whenImageFromSourceWithSourceNil_nilReturned() throws {
|
||||
let image = mediaProvider.imageFromSource(nil, size: Avatars.Size.room(on: .timeline).scaledSize)
|
||||
let image = try mediaProvider.imageFromSource(nil, size: Avatars.Size.room(on: .timeline).scaledSize)
|
||||
XCTAssertNil(image)
|
||||
}
|
||||
|
||||
@@ -83,14 +83,14 @@ final class MediaProviderTests: XCTestCase {
|
||||
let key = "\(url.absoluteString){\(avatarSize.scaledValue),\(avatarSize.scaledValue)}"
|
||||
let imageForKey = UIImage()
|
||||
imageCache.retrievedImagesInMemory[key] = imageForKey
|
||||
let image = mediaProvider.imageFromSource(MediaSourceProxy(url: url, mimeType: "image/jpeg"),
|
||||
size: avatarSize.scaledSize)
|
||||
let image = try mediaProvider.imageFromSource(MediaSourceProxy(url: url, mimeType: "image/jpeg"),
|
||||
size: avatarSize.scaledSize)
|
||||
XCTAssertEqual(image, imageForKey)
|
||||
}
|
||||
|
||||
func test_whenImageFromSourceWithSourceNotNilAndImageNotCached_nilReturned() throws {
|
||||
let image = mediaProvider.imageFromSource(MediaSourceProxy(url: .mockMXCImage, mimeType: "image/jpeg"),
|
||||
size: Avatars.Size.room(on: .timeline).scaledSize)
|
||||
let image = try mediaProvider.imageFromSource(MediaSourceProxy(url: .mockMXCImage, mimeType: "image/jpeg"),
|
||||
size: Avatars.Size.room(on: .timeline).scaledSize)
|
||||
XCTAssertNil(image)
|
||||
}
|
||||
|
||||
@@ -100,8 +100,8 @@ final class MediaProviderTests: XCTestCase {
|
||||
let key = "\(url.absoluteString){\(avatarSize.scaledValue),\(avatarSize.scaledValue)}"
|
||||
let imageForKey = UIImage()
|
||||
imageCache.retrievedImagesInMemory[key] = imageForKey
|
||||
let result = await mediaProvider.loadImageFromSource(MediaSourceProxy(url: url, mimeType: "image/jpeg"),
|
||||
size: avatarSize.scaledSize)
|
||||
let result = try await mediaProvider.loadImageFromSource(MediaSourceProxy(url: url, mimeType: "image/jpeg"),
|
||||
size: avatarSize.scaledSize)
|
||||
XCTAssertEqual(Result.success(imageForKey), result)
|
||||
}
|
||||
|
||||
@@ -111,8 +111,8 @@ final class MediaProviderTests: XCTestCase {
|
||||
let key = "\(url.absoluteString){\(avatarSize.scaledValue),\(avatarSize.scaledValue)}"
|
||||
let imageForKey = UIImage()
|
||||
imageCache.retrievedImages[key] = imageForKey
|
||||
let result = await mediaProvider.loadImageFromSource(MediaSourceProxy(url: url, mimeType: "image/jpeg"),
|
||||
size: avatarSize.scaledSize)
|
||||
let result = try await mediaProvider.loadImageFromSource(MediaSourceProxy(url: url, mimeType: "image/jpeg"),
|
||||
size: avatarSize.scaledSize)
|
||||
XCTAssertEqual(Result.success(imageForKey), result)
|
||||
}
|
||||
|
||||
@@ -122,8 +122,8 @@ final class MediaProviderTests: XCTestCase {
|
||||
|
||||
mediaLoader.loadMediaThumbnailForSourceWidthHeightReturnValue = expectedImage.pngData()
|
||||
|
||||
let result = await mediaProvider.loadImageFromSource(MediaSourceProxy(url: .mockMXCImage, mimeType: "image/jpeg"),
|
||||
size: avatarSize.scaledSize)
|
||||
let result = try await mediaProvider.loadImageFromSource(MediaSourceProxy(url: .mockMXCImage, mimeType: "image/jpeg"),
|
||||
size: avatarSize.scaledSize)
|
||||
switch result {
|
||||
case .success(let image):
|
||||
XCTAssertEqual(image.pngData(), expectedImage.pngData())
|
||||
@@ -140,8 +140,8 @@ final class MediaProviderTests: XCTestCase {
|
||||
|
||||
mediaLoader.loadMediaThumbnailForSourceWidthHeightReturnValue = expectedImage.pngData()
|
||||
|
||||
_ = await mediaProvider.loadImageFromSource(MediaSourceProxy(url: url, mimeType: "image/jpeg"),
|
||||
size: avatarSize.scaledSize)
|
||||
_ = try await mediaProvider.loadImageFromSource(MediaSourceProxy(url: url, mimeType: "image/jpeg"),
|
||||
size: avatarSize.scaledSize)
|
||||
let storedImage = try XCTUnwrap(imageCache.storedImages[key])
|
||||
XCTAssertEqual(expectedImage.pngData(), storedImage.pngData())
|
||||
}
|
||||
@@ -151,8 +151,8 @@ final class MediaProviderTests: XCTestCase {
|
||||
|
||||
mediaLoader.loadMediaContentForSourceReturnValue = expectedImage.pngData()
|
||||
|
||||
let result = await mediaProvider.loadImageFromSource(MediaSourceProxy(url: .mockMXCImage, mimeType: "image/jpeg"),
|
||||
size: nil)
|
||||
let result = try await mediaProvider.loadImageFromSource(MediaSourceProxy(url: .mockMXCImage, mimeType: "image/jpeg"),
|
||||
size: nil)
|
||||
switch result {
|
||||
case .success(let image):
|
||||
XCTAssertEqual(image.pngData(), expectedImage.pngData())
|
||||
@@ -164,8 +164,8 @@ final class MediaProviderTests: XCTestCase {
|
||||
func test_whenLoadImageFromSourceAndImageNotCachedAndRetrieveImageFailsAndLoadImageThumbnailFails_errorIsThrown() async throws {
|
||||
mediaLoader.loadMediaThumbnailForSourceWidthHeightThrowableError = MediaProviderTestsError.error
|
||||
|
||||
let result = await mediaProvider.loadImageFromSource(MediaSourceProxy(url: .mockMXCImage, mimeType: "image/jpeg"),
|
||||
size: Avatars.Size.room(on: .timeline).scaledSize)
|
||||
let result = try await mediaProvider.loadImageFromSource(MediaSourceProxy(url: .mockMXCImage, mimeType: "image/jpeg"),
|
||||
size: Avatars.Size.room(on: .timeline).scaledSize)
|
||||
switch result {
|
||||
case .success:
|
||||
XCTFail("Should fail")
|
||||
@@ -177,8 +177,8 @@ final class MediaProviderTests: XCTestCase {
|
||||
func test_whenLoadImageFromSourceAndImageNotCachedAndRetrieveImageFailsAndNoAvatarSizeAndLoadImageContentFails_errorIsThrown() async throws {
|
||||
mediaLoader.loadMediaContentForSourceThrowableError = MediaProviderTestsError.error
|
||||
|
||||
let result = await mediaProvider.loadImageFromSource(MediaSourceProxy(url: .mockMXCImage, mimeType: "image/jpeg"),
|
||||
size: nil)
|
||||
let result = try await mediaProvider.loadImageFromSource(MediaSourceProxy(url: .mockMXCImage, mimeType: "image/jpeg"),
|
||||
size: nil)
|
||||
switch result {
|
||||
case .success:
|
||||
XCTFail("Should fail")
|
||||
@@ -190,8 +190,8 @@ final class MediaProviderTests: XCTestCase {
|
||||
func test_whenLoadImageFromSourceAndImageNotCachedAndRetrieveImageFailsAndImageThumbnailIsLoadedWithCorruptedData_errorIsThrown() async throws {
|
||||
mediaLoader.loadMediaThumbnailForSourceWidthHeightReturnValue = Data()
|
||||
|
||||
let result = await mediaProvider.loadImageFromSource(MediaSourceProxy(url: .mockMXCImage, mimeType: "image/jpeg"),
|
||||
size: Avatars.Size.room(on: .timeline).scaledSize)
|
||||
let result = try await mediaProvider.loadImageFromSource(MediaSourceProxy(url: .mockMXCImage, mimeType: "image/jpeg"),
|
||||
size: Avatars.Size.room(on: .timeline).scaledSize)
|
||||
switch result {
|
||||
case .success:
|
||||
XCTFail("Should fail")
|
||||
|
||||
@@ -26,7 +26,7 @@ class VoiceMessageCacheTests: XCTestCase {
|
||||
voiceMessageCache.clearCache()
|
||||
|
||||
fileManager = FileManager.default
|
||||
mediaSource = MediaSourceProxy(url: someURL, mimeType: "audio/ogg")
|
||||
mediaSource = try MediaSourceProxy(url: someURL, mimeType: "audio/ogg")
|
||||
|
||||
// Create the temporary directory we will use
|
||||
try fileManager.createDirectory(at: testTemporaryDirectory, withIntermediateDirectories: true)
|
||||
|
||||
@@ -28,7 +28,7 @@ class VoiceMessageMediaManagerTests: XCTestCase {
|
||||
|
||||
func testLoadVoiceMessageFromSourceUnsupportedMedia() async throws {
|
||||
// Only "audio/ogg" file are supported
|
||||
let unsupportedMediaSource = MediaSourceProxy(url: someURL, mimeType: "audio/wav")
|
||||
let unsupportedMediaSource = try MediaSourceProxy(url: someURL, mimeType: "audio/wav")
|
||||
do {
|
||||
_ = try await voiceMessageMediaManager.loadVoiceMessageFromSource(unsupportedMediaSource, body: nil)
|
||||
XCTFail("A `VoiceMessageMediaManagerError.unsupportedMimeTye` error is expected")
|
||||
@@ -49,7 +49,7 @@ class VoiceMessageMediaManagerTests: XCTestCase {
|
||||
let cachedConvertedFileURL = URL("/some/url/cached_converted_file.m4a")
|
||||
|
||||
voiceMessageCache.fileURLForReturnValue = nil
|
||||
let mediaSource = MediaSourceProxy(url: someURL, mimeType: "audio/ogg; codecs=opus")
|
||||
let mediaSource = try MediaSourceProxy(url: someURL, mimeType: "audio/ogg; codecs=opus")
|
||||
mediaProvider.loadFileFromSourceFilenameReturnValue = .success(MediaFileHandleProxy.unmanaged(url: loadedFile))
|
||||
voiceMessageCache.cacheMediaSourceUsingMoveReturnValue = .success(cachedConvertedFileURL)
|
||||
|
||||
@@ -67,7 +67,7 @@ class VoiceMessageMediaManagerTests: XCTestCase {
|
||||
func testLoadVoiceMessageFromSourceAlreadyCached() async throws {
|
||||
// Check if the file is already present in cache
|
||||
voiceMessageCache.fileURLForReturnValue = URL("/converted_file/url")
|
||||
let mediaSource = MediaSourceProxy(url: someURL, mimeType: audioOGGMimeType)
|
||||
let mediaSource = try MediaSourceProxy(url: someURL, mimeType: audioOGGMimeType)
|
||||
let url = try await voiceMessageMediaManager.loadVoiceMessageFromSource(mediaSource, body: nil)
|
||||
XCTAssertEqual(url, URL("/converted_file/url"))
|
||||
// The file must have be search in the cache
|
||||
@@ -81,7 +81,7 @@ class VoiceMessageMediaManagerTests: XCTestCase {
|
||||
// An error must be reported if the file cannot be retrieved
|
||||
do {
|
||||
voiceMessageCache.fileURLForReturnValue = nil
|
||||
let mediaSource = MediaSourceProxy(url: someURL, mimeType: audioOGGMimeType)
|
||||
let mediaSource = try MediaSourceProxy(url: someURL, mimeType: audioOGGMimeType)
|
||||
_ = try await voiceMessageMediaManager.loadVoiceMessageFromSource(mediaSource, body: nil)
|
||||
XCTFail("A `MediaProviderError.failedRetrievingFile` error is expected")
|
||||
} catch {
|
||||
@@ -102,7 +102,7 @@ class VoiceMessageMediaManagerTests: XCTestCase {
|
||||
|
||||
// Check if the file is not already present in cache
|
||||
voiceMessageCache.fileURLForReturnValue = nil
|
||||
let mediaSource = MediaSourceProxy(url: someURL, mimeType: audioOGGMimeType)
|
||||
let mediaSource = try MediaSourceProxy(url: someURL, mimeType: audioOGGMimeType)
|
||||
mediaProvider.loadFileFromSourceFilenameReturnValue = .success(MediaFileHandleProxy.unmanaged(url: loadedFile))
|
||||
let audioConverter = AudioConverterMock()
|
||||
voiceMessageCache.cacheMediaSourceUsingMoveReturnValue = .success(cachedConvertedFileURL)
|
||||
@@ -145,7 +145,7 @@ class VoiceMessageMediaManagerTests: XCTestCase {
|
||||
voiceMessageCache: voiceMessageCache,
|
||||
audioConverter: audioConverter)
|
||||
|
||||
let mediaSource = MediaSourceProxy(url: someURL, mimeType: audioOGGMimeType)
|
||||
let mediaSource = try MediaSourceProxy(url: someURL, mimeType: audioOGGMimeType)
|
||||
for _ in 0..<10 {
|
||||
let url = try await voiceMessageMediaManager.loadVoiceMessageFromSource(mediaSource, body: nil)
|
||||
XCTAssertEqual(url, cachedConvertedFileURL)
|
||||
|
||||
Reference in New Issue
Block a user