// // Copyright 2023 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 Combine @testable import ElementX import Foundation import XCTest @MainActor class MediaPlayerProviderTests: XCTestCase { private var mediaPlayerProvider: MediaPlayerProvider! private let oggMimeType = "audio/ogg" private let someURL = URL("/some/url") private let someOtherURL = URL("/some/other/url") override func setUp() async throws { mediaPlayerProvider = MediaPlayerProvider() } func testPlayerForWrongMediaType() async throws { let mediaSourceWithoutMimeType = MediaSourceProxy(url: someURL, mimeType: nil) switch mediaPlayerProvider.player(for: mediaSourceWithoutMimeType) { case .failure(.unsupportedMediaType): // Ok break default: XCTFail("An error is expected") } let mediaSourceVideo = MediaSourceProxy(url: someURL, mimeType: "video/mp4") switch mediaPlayerProvider.player(for: mediaSourceVideo) { case .failure(.unsupportedMediaType): // Ok break default: XCTFail("An error is expected") } } func testPlayerFor() async throws { let mediaSource = MediaSourceProxy(url: someURL, mimeType: oggMimeType) guard case .success(let playerA) = mediaPlayerProvider.player(for: mediaSource) else { XCTFail("A valid player is expected") return } // calling it again with another mediasource must returns the same player let otherMediaSource = MediaSourceProxy(url: someOtherURL, mimeType: oggMimeType) guard case .success(let playerB) = mediaPlayerProvider.player(for: otherMediaSource) else { XCTFail("A valid player is expected") return } XCTAssert(playerA === playerB) } func testPlayerStates() async throws { let audioPlayerStateId = AudioPlayerStateIdentifier.timelineItemIdentifier(.random) // By default, there should be no player state XCTAssertNil(mediaPlayerProvider.playerState(for: audioPlayerStateId)) let audioPlayerState = AudioPlayerState(id: audioPlayerStateId, duration: 10.0) mediaPlayerProvider.register(audioPlayerState: audioPlayerState) XCTAssertEqual(audioPlayerState, mediaPlayerProvider.playerState(for: audioPlayerStateId)) mediaPlayerProvider.unregister(audioPlayerState: audioPlayerState) XCTAssertNil(mediaPlayerProvider.playerState(for: audioPlayerStateId)) } func testDetachAllStates() async throws { let audioPlayer = AudioPlayerMock() audioPlayer.actions = PassthroughSubject().eraseToAnyPublisher() let audioPlayerStates = Array(repeating: AudioPlayerState(id: .timelineItemIdentifier(.random), duration: 0), count: 10) for audioPlayerState in audioPlayerStates { mediaPlayerProvider.register(audioPlayerState: audioPlayerState) audioPlayerState.attachAudioPlayer(audioPlayer) let isAttached = audioPlayerState.isAttached XCTAssertTrue(isAttached) } mediaPlayerProvider.detachAllStates(except: nil) for audioPlayerState in audioPlayerStates { let isAttached = audioPlayerState.isAttached XCTAssertFalse(isAttached) } } func testDetachAllStatesWithException() async throws { let audioPlayer = AudioPlayerMock() audioPlayer.actions = PassthroughSubject().eraseToAnyPublisher() let audioPlayerStates = Array(repeating: AudioPlayerState(id: .timelineItemIdentifier(.random), duration: 0), count: 10) for audioPlayerState in audioPlayerStates { mediaPlayerProvider.register(audioPlayerState: audioPlayerState) audioPlayerState.attachAudioPlayer(audioPlayer) let isAttached = audioPlayerState.isAttached XCTAssertTrue(isAttached) } let exception = audioPlayerStates[1] mediaPlayerProvider.detachAllStates(except: exception) for audioPlayerState in audioPlayerStates { let isAttached = audioPlayerState.isAttached if audioPlayerState == exception { XCTAssertTrue(isAttached) } else { XCTAssertFalse(isAttached) } } } }