mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-04 19:44:05 +00:00
Use the maxUploadSize in the media upload screen. (#4359)
* Fix a bug where some files sizes were sent as 0. * Make FileManger.sizeForItem(at:) a UInt. The docs specifically say that FileAttributeKey.size returns an unsigned long long so I have no idea why we were returning a Double here… * Add the maxMediaUploadSize property on ClientProxy. * Use the maxUploadSize to set a target video size and to show a file too big error. * Refactor media upload parameter order.
This commit is contained in:
@@ -12,6 +12,7 @@ import XCTest
|
||||
@MainActor
|
||||
class MediaUploadPreviewScreenViewModelTests: XCTestCase {
|
||||
var timelineProxy: TimelineProxyMock!
|
||||
var clientProxy: ClientProxyMock!
|
||||
var viewModel: MediaUploadPreviewScreenViewModel!
|
||||
var context: MediaUploadPreviewScreenViewModel.Context { viewModel.context }
|
||||
|
||||
@@ -89,6 +90,54 @@ class MediaUploadPreviewScreenViewModelTests: XCTestCase {
|
||||
try await send()
|
||||
}
|
||||
|
||||
func testUploadWithUnknownMaxUploadSize() async throws {
|
||||
// Given an upload screen that is unable to fetch the max upload size.
|
||||
setUpViewModel(url: imageURL, expectedCaption: nil, maxUploadSizeResult: .failure(.sdkError(ClientProxyMockError.generic)))
|
||||
XCTAssertFalse(context.viewState.shouldDisableInteraction)
|
||||
XCTAssertNil(context.alertInfo)
|
||||
|
||||
// When attempting to send the media.
|
||||
let deferredAlert = deferFulfillment(context.observe(\.viewState.bindings.alertInfo)) { $0 != nil }
|
||||
context.send(viewAction: .send)
|
||||
|
||||
XCTAssertTrue(context.viewState.shouldDisableInteraction, "The interaction should be disabled while sending.")
|
||||
|
||||
// Then alert should be shown to tell the user it failed.
|
||||
try await deferredAlert.fulfill()
|
||||
|
||||
XCTAssertFalse(context.viewState.shouldDisableInteraction)
|
||||
XCTAssertEqual(context.alertInfo?.id, .maxUploadSizeUnknown)
|
||||
|
||||
// When trying with the max upload size now available.
|
||||
let deferredDismiss = deferFulfillment(viewModel.actions) { $0 == .dismiss }
|
||||
clientProxy.underlyingMaxMediaUploadSize = .success(100 * 1024 * 1024)
|
||||
context.alertInfo?.primaryButton.action?()
|
||||
|
||||
XCTAssertTrue(context.viewState.shouldDisableInteraction, "The interaction should be disabled while retrying.")
|
||||
|
||||
// Then the file should upload successfully.
|
||||
try await deferredDismiss.fulfill()
|
||||
}
|
||||
|
||||
func testUploadExceedingMaxUploadSize() async throws {
|
||||
// Given an upload screen with a really small max upload size.
|
||||
setUpViewModel(url: imageURL, expectedCaption: nil, maxUploadSizeResult: .success(100))
|
||||
XCTAssertFalse(context.viewState.shouldDisableInteraction)
|
||||
XCTAssertNil(context.alertInfo)
|
||||
|
||||
// When attempting to send an image that is larger the limit.
|
||||
let deferredAlert = deferFulfillment(context.observe(\.viewState.bindings.alertInfo)) { $0 != nil }
|
||||
context.send(viewAction: .send)
|
||||
|
||||
XCTAssertTrue(context.viewState.shouldDisableInteraction, "The interaction should be disabled while sending.")
|
||||
|
||||
// Then an alert should be shown to inform the user of the max upload size.
|
||||
try await deferredAlert.fulfill()
|
||||
|
||||
XCTAssertFalse(context.viewState.shouldDisableInteraction)
|
||||
XCTAssertEqual(context.alertInfo?.id, .maxUploadSizeExceeded(limit: 100))
|
||||
}
|
||||
|
||||
// MARK: - Helpers
|
||||
|
||||
private var audioURL: URL { assertResourceURL(filename: "test_audio.mp3") }
|
||||
@@ -104,7 +153,7 @@ class MediaUploadPreviewScreenViewModelTests: XCTestCase {
|
||||
return url
|
||||
}
|
||||
|
||||
private func setUpViewModel(url: URL, expectedCaption: String?) {
|
||||
private func setUpViewModel(url: URL, expectedCaption: String?, maxUploadSizeResult: Result<UInt, ClientProxyError>? = nil) {
|
||||
timelineProxy = TimelineProxyMock(.init())
|
||||
timelineProxy.sendAudioUrlAudioInfoCaptionRequestHandleClosure = { [weak self] _, _, caption, _ in
|
||||
self?.verifyCaption(caption, expectedCaption: expectedCaption) ?? .failure(.sdkError(TestError.unknown))
|
||||
@@ -119,13 +168,19 @@ class MediaUploadPreviewScreenViewModelTests: XCTestCase {
|
||||
self?.verifyCaption(caption, expectedCaption: expectedCaption) ?? .failure(.sdkError(TestError.unknown))
|
||||
}
|
||||
|
||||
viewModel = MediaUploadPreviewScreenViewModel(timelineController: MockTimelineController(timelineProxy: timelineProxy),
|
||||
userIndicatorController: UserIndicatorControllerMock(),
|
||||
mediaUploadingPreprocessor: MediaUploadingPreprocessor(appSettings: ServiceLocator.shared.settings),
|
||||
clientProxy = ClientProxyMock(.init())
|
||||
if let maxUploadSizeResult {
|
||||
clientProxy.underlyingMaxMediaUploadSize = maxUploadSizeResult
|
||||
}
|
||||
|
||||
viewModel = MediaUploadPreviewScreenViewModel(url: url,
|
||||
title: "Some File",
|
||||
url: url,
|
||||
isRoomEncrypted: true,
|
||||
shouldShowCaptionWarning: true,
|
||||
isRoomEncrypted: true)
|
||||
mediaUploadingPreprocessor: MediaUploadingPreprocessor(appSettings: ServiceLocator.shared.settings),
|
||||
timelineController: MockTimelineController(timelineProxy: timelineProxy),
|
||||
clientProxy: clientProxy,
|
||||
userIndicatorController: UserIndicatorControllerMock())
|
||||
}
|
||||
|
||||
private func verifyCaption(_ caption: String?, expectedCaption: String?) -> Result<Void, TimelineProxyError> {
|
||||
|
||||
@@ -11,6 +11,7 @@ import XCTest
|
||||
@testable import ElementX
|
||||
|
||||
final class MediaUploadingPreprocessorTests: XCTestCase {
|
||||
let maxUploadSize: UInt = 100 * 1024 * 1024
|
||||
var appSettings: AppSettings!
|
||||
var mediaUploadingPreprocessor: MediaUploadingPreprocessor!
|
||||
|
||||
@@ -32,7 +33,7 @@ final class MediaUploadingPreprocessorTests: XCTestCase {
|
||||
return
|
||||
}
|
||||
|
||||
guard case let .success(result) = await mediaUploadingPreprocessor.processMedia(at: url),
|
||||
guard case let .success(result) = await mediaUploadingPreprocessor.processMedia(at: url, maxUploadSize: maxUploadSize),
|
||||
case let .audio(audioURL, audioInfo) = result else {
|
||||
XCTFail("Failed processing asset")
|
||||
return
|
||||
@@ -55,7 +56,7 @@ final class MediaUploadingPreprocessorTests: XCTestCase {
|
||||
return
|
||||
}
|
||||
|
||||
guard case let .success(result) = await mediaUploadingPreprocessor.processMedia(at: url),
|
||||
guard case let .success(result) = await mediaUploadingPreprocessor.processMedia(at: url, maxUploadSize: maxUploadSize),
|
||||
case let .video(videoURL, thumbnailURL, videoInfo) = result else {
|
||||
XCTFail("Failed processing asset")
|
||||
return
|
||||
@@ -92,7 +93,7 @@ final class MediaUploadingPreprocessorTests: XCTestCase {
|
||||
// Repeat with optimised media setting
|
||||
appSettings.optimizeMediaUploads = true
|
||||
|
||||
guard case let .success(optimizedResult) = await mediaUploadingPreprocessor.processMedia(at: url),
|
||||
guard case let .success(optimizedResult) = await mediaUploadingPreprocessor.processMedia(at: url, maxUploadSize: maxUploadSize),
|
||||
case let .video(optimizedVideoURL, _, optimizedVideoInfo) = optimizedResult else {
|
||||
XCTFail("Failed processing asset")
|
||||
return
|
||||
@@ -118,7 +119,7 @@ final class MediaUploadingPreprocessorTests: XCTestCase {
|
||||
return
|
||||
}
|
||||
|
||||
guard case let .success(result) = await mediaUploadingPreprocessor.processMedia(at: url),
|
||||
guard case let .success(result) = await mediaUploadingPreprocessor.processMedia(at: url, maxUploadSize: maxUploadSize),
|
||||
case let .video(videoURL, thumbnailURL, videoInfo) = result else {
|
||||
XCTFail("Failed processing asset")
|
||||
return
|
||||
@@ -155,7 +156,7 @@ final class MediaUploadingPreprocessorTests: XCTestCase {
|
||||
// Repeat with optimised media setting
|
||||
appSettings.optimizeMediaUploads = true
|
||||
|
||||
guard case let .success(optimizedResult) = await mediaUploadingPreprocessor.processMedia(at: url),
|
||||
guard case let .success(optimizedResult) = await mediaUploadingPreprocessor.processMedia(at: url, maxUploadSize: maxUploadSize),
|
||||
case let .video(optimizedVideoURL, _, optimizedVideoInfo) = optimizedResult else {
|
||||
XCTFail("Failed processing asset")
|
||||
return
|
||||
@@ -178,7 +179,7 @@ final class MediaUploadingPreprocessorTests: XCTestCase {
|
||||
return
|
||||
}
|
||||
|
||||
guard case let .success(result) = await mediaUploadingPreprocessor.processMedia(at: url),
|
||||
guard case let .success(result) = await mediaUploadingPreprocessor.processMedia(at: url, maxUploadSize: maxUploadSize),
|
||||
case let .image(convertedImageURL, thumbnailURL, imageInfo) = result else {
|
||||
XCTFail("Failed processing asset")
|
||||
return
|
||||
@@ -202,7 +203,7 @@ final class MediaUploadingPreprocessorTests: XCTestCase {
|
||||
// Repeat with optimised media setting
|
||||
appSettings.optimizeMediaUploads = true
|
||||
|
||||
guard case let .success(optimizedResult) = await mediaUploadingPreprocessor.processMedia(at: url),
|
||||
guard case let .success(optimizedResult) = await mediaUploadingPreprocessor.processMedia(at: url, maxUploadSize: maxUploadSize),
|
||||
case let .image(optimizedImageURL, thumbnailURL, optimizedImageInfo) = optimizedResult else {
|
||||
XCTFail("Failed processing asset")
|
||||
return
|
||||
@@ -224,7 +225,7 @@ final class MediaUploadingPreprocessorTests: XCTestCase {
|
||||
return
|
||||
}
|
||||
|
||||
guard case let .success(result) = await mediaUploadingPreprocessor.processMedia(at: url),
|
||||
guard case let .success(result) = await mediaUploadingPreprocessor.processMedia(at: url, maxUploadSize: maxUploadSize),
|
||||
case let .image(convertedImageURL, thumbnailURL, imageInfo) = result else {
|
||||
XCTFail("Failed processing asset")
|
||||
return
|
||||
@@ -248,7 +249,7 @@ final class MediaUploadingPreprocessorTests: XCTestCase {
|
||||
// Repeat with optimised media setting
|
||||
appSettings.optimizeMediaUploads = true
|
||||
|
||||
guard case let .success(optimizedResult) = await mediaUploadingPreprocessor.processMedia(at: url),
|
||||
guard case let .success(optimizedResult) = await mediaUploadingPreprocessor.processMedia(at: url, maxUploadSize: maxUploadSize),
|
||||
case let .image(optimizedImageURL, thumbnailURL, optimizedImageInfo) = optimizedResult else {
|
||||
XCTFail("Failed processing asset")
|
||||
return
|
||||
@@ -270,7 +271,7 @@ final class MediaUploadingPreprocessorTests: XCTestCase {
|
||||
return
|
||||
}
|
||||
|
||||
guard case let .success(result) = await mediaUploadingPreprocessor.processMedia(at: url),
|
||||
guard case let .success(result) = await mediaUploadingPreprocessor.processMedia(at: url, maxUploadSize: maxUploadSize),
|
||||
case let .image(convertedImageURL, _, imageInfo) = result else {
|
||||
XCTFail("Failed processing asset")
|
||||
return
|
||||
@@ -296,7 +297,7 @@ final class MediaUploadingPreprocessorTests: XCTestCase {
|
||||
// Repeat with optimised media setting
|
||||
appSettings.optimizeMediaUploads = true
|
||||
|
||||
guard case let .success(optimizedResult) = await mediaUploadingPreprocessor.processMedia(at: url),
|
||||
guard case let .success(optimizedResult) = await mediaUploadingPreprocessor.processMedia(at: url, maxUploadSize: maxUploadSize),
|
||||
case let .image(optimizedImageURL, _, optimizedImageInfo) = optimizedResult else {
|
||||
XCTFail("Failed processing asset")
|
||||
return
|
||||
@@ -321,7 +322,7 @@ final class MediaUploadingPreprocessorTests: XCTestCase {
|
||||
return
|
||||
}
|
||||
|
||||
guard case let .success(result) = await mediaUploadingPreprocessor.processMedia(at: url),
|
||||
guard case let .success(result) = await mediaUploadingPreprocessor.processMedia(at: url, maxUploadSize: maxUploadSize),
|
||||
case let .image(convertedImageURL, thumbnailURL, imageInfo) = result else {
|
||||
XCTFail("Failed processing asset")
|
||||
return
|
||||
@@ -349,7 +350,7 @@ final class MediaUploadingPreprocessorTests: XCTestCase {
|
||||
// Repeat with optimised media setting
|
||||
appSettings.optimizeMediaUploads = true
|
||||
|
||||
guard case let .success(optimizedResult) = await mediaUploadingPreprocessor.processMedia(at: url),
|
||||
guard case let .success(optimizedResult) = await mediaUploadingPreprocessor.processMedia(at: url, maxUploadSize: maxUploadSize),
|
||||
case let .image(optimizedImageURL, thumbnailURL, optimizedImageInfo) = optimizedResult else {
|
||||
XCTFail("Failed processing asset")
|
||||
return
|
||||
@@ -379,7 +380,7 @@ final class MediaUploadingPreprocessorTests: XCTestCase {
|
||||
return
|
||||
}
|
||||
|
||||
guard case let .success(result) = await mediaUploadingPreprocessor.processMedia(at: url),
|
||||
guard case let .success(result) = await mediaUploadingPreprocessor.processMedia(at: url, maxUploadSize: maxUploadSize),
|
||||
case let .image(convertedImageURL, _, imageInfo) = result else {
|
||||
XCTFail("Failed processing asset")
|
||||
return
|
||||
@@ -405,7 +406,7 @@ final class MediaUploadingPreprocessorTests: XCTestCase {
|
||||
// Repeat with optimised media setting
|
||||
appSettings.optimizeMediaUploads = true
|
||||
|
||||
guard case let .success(optimizedResult) = await mediaUploadingPreprocessor.processMedia(at: url),
|
||||
guard case let .success(optimizedResult) = await mediaUploadingPreprocessor.processMedia(at: url, maxUploadSize: maxUploadSize),
|
||||
case let .image(optimizedImageURL, _, optimizedImageInfo) = optimizedResult else {
|
||||
XCTFail("Failed processing asset")
|
||||
return
|
||||
@@ -429,7 +430,7 @@ final class MediaUploadingPreprocessorTests: XCTestCase {
|
||||
return
|
||||
}
|
||||
|
||||
guard case let .success(result) = await mediaUploadingPreprocessor.processMedia(at: url),
|
||||
guard case let .success(result) = await mediaUploadingPreprocessor.processMedia(at: url, maxUploadSize: maxUploadSize),
|
||||
case let .image(convertedImageURL, thumbnailURL, imageInfo) = result else {
|
||||
XCTFail("Failed processing asset")
|
||||
return
|
||||
@@ -449,7 +450,7 @@ final class MediaUploadingPreprocessorTests: XCTestCase {
|
||||
// Repeat with optimised media setting
|
||||
appSettings.optimizeMediaUploads = true
|
||||
|
||||
guard case let .success(optimizedResult) = await mediaUploadingPreprocessor.processMedia(at: url),
|
||||
guard case let .success(optimizedResult) = await mediaUploadingPreprocessor.processMedia(at: url, maxUploadSize: maxUploadSize),
|
||||
case let .image(optimizedImageURL, thumbnailURL, optimizedImageInfo) = optimizedResult else {
|
||||
XCTFail("Failed processing asset")
|
||||
return
|
||||
|
||||
@@ -111,6 +111,7 @@ class RoomDetailsEditScreenViewModelTests: XCTestCase {
|
||||
private func setupViewModel(roomProxyConfiguration: JoinedRoomProxyMockConfiguration) {
|
||||
userIndicatorController = UserIndicatorControllerMock.default
|
||||
viewModel = .init(roomProxy: JoinedRoomProxyMock(roomProxyConfiguration),
|
||||
clientProxy: ClientProxyMock(.init()),
|
||||
mediaProvider: MediaProviderMock(configuration: .init()),
|
||||
mediaUploadingPreprocessor: MediaUploadingPreprocessor(appSettings: ServiceLocator.shared.settings),
|
||||
userIndicatorController: userIndicatorController)
|
||||
|
||||
Reference in New Issue
Block a user