Cleanup following the AppMediator introduction (#2723)

- stop using multiple background task, the appCoordinator sync one is enough for the whole app
- move the AppMeditor to the MainActor
- expose the WindowManager through the AppMediator
- hide sensitive WindowManager API behind a different protocol
- remove the now unnecessary `BackgroundTaskService`
This commit is contained in:
Stefan Ceriu
2024-04-22 18:10:24 +03:00
committed by GitHub
parent a3ec0b8505
commit 8ba544bc44
34 changed files with 117 additions and 929 deletions
-160
View File
@@ -1,160 +0,0 @@
//
// Copyright 2022 New Vector Ltd
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
import XCTest
@testable import ElementX
@MainActor
class BackgroundTaskTests: XCTestCase {
private enum Constants {
static let bgTaskName = "test"
}
func testInitAndStop() {
let service = UIKitBackgroundTaskService(appMediator: AppMediatorMock.default)
guard let task = service.startBackgroundTask(withName: Constants.bgTaskName) else {
XCTFail("Failed to setup test conditions")
return
}
XCTAssertEqual(task.name, Constants.bgTaskName, "Task name should be persisted")
XCTAssertFalse(task.isReusable, "Task should be not reusable by default")
XCTAssertTrue(task.isRunning, "Task should be running")
task.stop()
XCTAssertFalse(task.isRunning, "Task should be stopped")
}
func testNotReusableInit() {
let service = UIKitBackgroundTaskService(appMediator: AppMediatorMock.default)
// create two not reusable task with the same name
guard let task1 = service.startBackgroundTask(withName: Constants.bgTaskName),
let task2 = service.startBackgroundTask(withName: Constants.bgTaskName) else {
XCTFail("Failed to setup test conditions")
return
}
// task1 & task2 should be different instances
XCTAssertFalse(task1 === task2,
"Handler should create different tasks when reusability disabled")
}
func testReusableInit() {
let service = UIKitBackgroundTaskService(appMediator: AppMediatorMock.default)
// create two reusable task with the same name
guard let task1 = service.startBackgroundTask(withName: Constants.bgTaskName, isReusable: true),
let task2 = service.startBackgroundTask(withName: Constants.bgTaskName, isReusable: true) else {
XCTFail("Failed to setup test conditions")
return
}
// task1 and task2 should be the same instance
XCTAssertTrue(task1 === task2,
"Handler should create different tasks when reusability disabled")
XCTAssertEqual(task1.name, Constants.bgTaskName, "Task name should be persisted")
XCTAssertTrue(task1.isReusable, "Task should be reusable")
XCTAssertTrue(task1.isRunning, "Task should be running")
}
func testMultipleStops() {
let service = UIKitBackgroundTaskService(appMediator: AppMediatorMock.default)
// create two reusable task with the same name
guard let task = service.startBackgroundTask(withName: Constants.bgTaskName, isReusable: true),
service.startBackgroundTask(withName: Constants.bgTaskName, isReusable: true) != nil else {
XCTFail("Failed to setup test conditions")
return
}
XCTAssertTrue(task.isRunning, "Task should be running")
task.stop()
XCTAssertTrue(task.isRunning, "Task should be still running after one stop call")
task.stop()
XCTAssertFalse(task.isRunning, "Task should be stopped after two stop calls")
}
func testNotValidReuse() {
let service = UIKitBackgroundTaskService(appMediator: AppMediatorMock.default)
// create two reusable task with the same name
guard let task = service.startBackgroundTask(withName: Constants.bgTaskName, isReusable: true) else {
XCTFail("Failed to setup test conditions")
return
}
XCTAssertTrue(task.isRunning, "Task should be running")
task.stop()
XCTAssertFalse(task.isRunning, "Task should be stopped after stop")
task.reuse()
XCTAssertFalse(task.isRunning, "Task should be stopped after one stop call, even if reuse is called after")
}
func testValidReuse() {
let service = UIKitBackgroundTaskService(appMediator: AppMediatorMock.default)
// create two reusable task with the same name
guard let task = service.startBackgroundTask(withName: Constants.bgTaskName, isReusable: true) else {
XCTFail("Failed to setup test conditions")
return
}
XCTAssertTrue(task.isRunning, "Task should be running")
task.reuse()
XCTAssertTrue(task.isRunning, "Task should be still running")
task.stop()
XCTAssertTrue(task.isRunning, "Task should be still running after one stop call")
task.stop()
XCTAssertFalse(task.isRunning, "Task should be stopped after two stop calls")
}
func testBrokenApp() {
let service = UIKitBackgroundTaskService(appMediator: AppMediatorMock.mockBroken)
// create two reusable task with the same name
let task = service.startBackgroundTask(withName: Constants.bgTaskName)
XCTAssertNil(task, "Task should not be created")
}
func testNoTimeApp() {
let service = UIKitBackgroundTaskService(appMediator: AppMediatorMock.mockAboutToSuspend)
// create two reusable task with the same name
let task = service.startBackgroundTask(withName: Constants.bgTaskName)
XCTAssertNil(task, "Task should not be created")
}
}
@@ -22,15 +22,13 @@ import XCTest
final class MediaProviderTests: XCTestCase {
private let mediaLoader = MockMediaLoader()
private var imageCache: MockImageCache!
private var backgroundTaskService = MockBackgroundTaskService()
var mediaProvider: MediaProvider!
override func setUp() {
imageCache = MockImageCache(name: "Test")
mediaProvider = MediaProvider(mediaLoader: mediaLoader,
imageCache: imageCache,
backgroundTaskService: backgroundTaskService)
imageCache: imageCache)
}
func test_whenImageFromSourceWithSourceNil_nilReturned() throws {
@@ -1,23 +0,0 @@
//
// Copyright 2022 New Vector Ltd
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
@testable import ElementX
import Foundation
class MockBackgroundTaskService: BackgroundTaskServiceProtocol {
func startBackgroundTask(withName name: String, isReusable: Bool, expirationHandler: (() -> Void)?) -> ElementX.BackgroundTaskProtocol? {
nil
}
}
@@ -295,8 +295,7 @@ class RoomFlowCoordinatorTests: XCTestCase {
appMediator: AppMediatorMock.default,
appSettings: ServiceLocator.shared.settings,
analytics: ServiceLocator.shared.analytics,
userIndicatorController: ServiceLocator.shared.userIndicatorController,
orientationManager: OrientationManagerMock())
userIndicatorController: ServiceLocator.shared.userIndicatorController)
}
}
@@ -46,7 +46,6 @@ class UserSessionFlowCoordinatorTests: XCTestCase {
userSessionFlowCoordinator = UserSessionFlowCoordinator(userSession: userSession,
navigationRootCoordinator: navigationRootCoordinator,
windowManager: WindowManagerMock(),
appLockService: AppLockServiceMock(),
bugReportService: BugReportServiceMock(),
roomTimelineControllerFactory: MockRoomTimelineControllerFactory(),
@@ -32,8 +32,7 @@ class VoiceMessageMediaManagerTests: XCTestCase {
voiceMessageCache = VoiceMessageCacheMock()
mediaProvider = MockMediaProvider()
voiceMessageMediaManager = VoiceMessageMediaManager(mediaProvider: mediaProvider,
voiceMessageCache: voiceMessageCache,
backgroundTaskService: MockBackgroundTaskService())
voiceMessageCache: voiceMessageCache)
}
func testLoadVoiceMessageFromSourceUnsupportedMedia() async throws {
@@ -65,8 +64,7 @@ class VoiceMessageMediaManagerTests: XCTestCase {
voiceMessageMediaManager = VoiceMessageMediaManager(mediaProvider: mediaProvider,
voiceMessageCache: voiceMessageCache,
audioConverter: AudioConverterMock(),
backgroundTaskService: MockBackgroundTaskService())
audioConverter: AudioConverterMock())
do {
_ = try await voiceMessageMediaManager.loadVoiceMessageFromSource(mediaSource, body: nil)
@@ -119,8 +117,7 @@ class VoiceMessageMediaManagerTests: XCTestCase {
voiceMessageCache.cacheMediaSourceUsingMoveReturnValue = .success(cachedConvertedFileURL)
voiceMessageMediaManager = VoiceMessageMediaManager(mediaProvider: mediaProvider,
voiceMessageCache: voiceMessageCache,
audioConverter: audioConverter,
backgroundTaskService: MockBackgroundTaskService())
audioConverter: audioConverter)
let url = try await voiceMessageMediaManager.loadVoiceMessageFromSource(mediaSource, body: nil)
// The file must have been converted
@@ -155,8 +152,7 @@ class VoiceMessageMediaManagerTests: XCTestCase {
voiceMessageMediaManager = VoiceMessageMediaManager(mediaProvider: mediaProvider,
voiceMessageCache: voiceMessageCache,
audioConverter: audioConverter,
backgroundTaskService: MockBackgroundTaskService())
audioConverter: audioConverter)
let mediaSource = MediaSourceProxy(url: someURL, mimeType: audioOGGMimeType)
for _ in 0..<10 {