Replace the existing MockClientProxy with a generated one + special configuration options

This commit is contained in:
Stefan Ceriu
2024-02-27 16:22:47 +02:00
parent 14d76d9860
commit c8f728ca23
36 changed files with 793 additions and 311 deletions
@@ -22,7 +22,7 @@ import XCTest
@MainActor
class BlockedUsersScreenViewModelTests: XCTestCase {
func testInitialState() {
let clientProxy = MockClientProxy(userID: RoomMemberProxyMock.mockMe.userID)
let clientProxy = ClientProxyMock(.init(userID: RoomMemberProxyMock.mockMe.userID))
let viewModel = BlockedUsersScreenViewModel(clientProxy: clientProxy,
userIndicatorController: ServiceLocator.shared.userIndicatorController)
@@ -22,7 +22,7 @@ import XCTest
@MainActor
class CreateRoomScreenViewModelTests: XCTestCase {
var viewModel: CreateRoomViewModelProtocol!
var clientProxy: MockClientProxy!
var clientProxy: ClientProxyMock!
var userSession: MockUserSession!
private let usersSubject = CurrentValueSubject<[UserProfileProxy], Never>([])
@@ -34,7 +34,7 @@ class CreateRoomScreenViewModelTests: XCTestCase {
override func setUpWithError() throws {
cancellables.removeAll()
clientProxy = MockClientProxy(userID: "@a:b.com")
clientProxy = ClientProxyMock(.init(userID: "@a:b.com"))
userSession = MockUserSession(clientProxy: clientProxy,
mediaProvider: MockMediaProvider(),
voiceMessageMediaManager: VoiceMessageMediaManagerMock())
@@ -22,7 +22,7 @@ import XCTest
@MainActor
class HomeScreenViewModelTests: XCTestCase {
var viewModel: HomeScreenViewModelProtocol!
var clientProxy: MockClientProxy!
var clientProxy: ClientProxyMock!
var context: HomeScreenViewModelType.Context! { viewModel.context }
var cancellables = Set<AnyCancellable>()
var roomSummaryProvider: MockRoomSummaryProvider!
@@ -31,7 +31,7 @@ class HomeScreenViewModelTests: XCTestCase {
ServiceLocator.shared.settings.roomListFiltersEnabled = true
cancellables.removeAll()
roomSummaryProvider = MockRoomSummaryProvider(state: .loaded(.mockRooms))
clientProxy = MockClientProxy(userID: "@mock:client.com", roomSummaryProvider: roomSummaryProvider)
clientProxy = ClientProxyMock(.init(userID: "@mock:client.com", roomSummaryProvider: roomSummaryProvider))
viewModel = HomeScreenViewModel(userSession: MockUserSession(clientProxy: clientProxy,
mediaProvider: MockMediaProvider(),
voiceMessageMediaManager: VoiceMessageMediaManagerMock()),
@@ -89,7 +89,8 @@ class HomeScreenViewModelTests: XCTestCase {
func testLeaveRoomAlert() async throws {
let mockRoomId = "1"
clientProxy.roomForIdentifierMocks[mockRoomId] = .init(with: .init(id: mockRoomId, name: "Some room"))
clientProxy.roomForIdentifierClosure = { _ in RoomProxyMock(with: .init(id: mockRoomId, name: "Some room")) }
let deferred = deferFulfillment(context.$viewState) { value in
value.bindings.leaveRoomAlertItem != nil
@@ -106,7 +107,8 @@ class HomeScreenViewModelTests: XCTestCase {
let mockRoomId = "1"
let room: RoomProxyMock = .init(with: .init(id: mockRoomId, name: "Some room"))
room.leaveRoomClosure = { .failure(.failedLeavingRoom) }
clientProxy.roomForIdentifierMocks[mockRoomId] = room
clientProxy.roomForIdentifierClosure = { _ in room }
let deferred = deferFulfillment(context.$viewState) { value in
value.bindings.alertInfo != nil
@@ -136,7 +138,9 @@ class HomeScreenViewModelTests: XCTestCase {
.store(in: &cancellables)
let room: RoomProxyMock = .init(with: .init(id: mockRoomId, name: "Some room"))
room.leaveRoomClosure = { .success(()) }
clientProxy.roomForIdentifierMocks[mockRoomId] = room
clientProxy.roomForIdentifierClosure = { _ in room }
context.send(viewAction: .confirmLeaveRoom(roomIdentifier: mockRoomId))
await fulfillment(of: [expectation])
XCTAssertNil(context.alertInfo)
@@ -20,7 +20,7 @@ import XCTest
@MainActor
class InvitesScreenViewModelTests: XCTestCase {
var viewModel: InvitesScreenViewModelProtocol!
var clientProxy: MockClientProxy!
var clientProxy: ClientProxyMock!
var userSession: MockUserSession!
var mockNotificationCenter: NotificationCenterMock!
@@ -29,7 +29,7 @@ class InvitesScreenViewModelTests: XCTestCase {
}
override func setUpWithError() throws {
clientProxy = MockClientProxy(userID: "@a:b.com")
clientProxy = ClientProxyMock(.init(userID: "@a:b.com"))
userSession = MockUserSession(clientProxy: clientProxy,
mediaProvider: MockMediaProvider(),
voiceMessageMediaManager: VoiceMessageMediaManagerMock())
@@ -37,8 +37,8 @@ final class MediaUploadingPreprocessorTests: XCTestCase {
XCTAssertEqual(audioURL.lastPathComponent, "test_audio.mp3")
XCTAssertEqual(audioInfo.mimetype, "audio/mpeg")
XCTAssertEqual(floor(audioInfo.duration ?? 0), 27252)
XCTAssertEqual(audioInfo.size, 764_176)
XCTAssertEqual(audioInfo.duration ?? 0, 27252, accuracy: 100)
XCTAssertEqual(audioInfo.size ?? 0, 764_176, accuracy: 100)
}
func testLandscapeMovVideoProcessing() async {
@@ -69,14 +69,14 @@ final class MediaUploadingPreprocessorTests: XCTestCase {
// Check resulting video info
XCTAssertEqual(videoInfo.mimetype, "video/mp4")
XCTAssertEqual(videoInfo.blurhash, "K22PJZx^DgadWAbbMuRio$")
XCTAssertEqual(videoInfo.size, 1_431_959)
XCTAssertEqual(videoInfo.size ?? 0, 1_431_959, accuracy: 100)
XCTAssertEqual(videoInfo.width, 1280)
XCTAssertEqual(videoInfo.height, 720)
XCTAssertEqual(floor(videoInfo.duration ?? 0), 30483)
XCTAssertEqual(videoInfo.duration ?? 0, 30483, accuracy: 100)
XCTAssertNotNil(videoInfo.thumbnailInfo)
XCTAssertEqual(videoInfo.thumbnailInfo?.mimetype, "image/jpeg")
XCTAssertEqual(videoInfo.thumbnailInfo?.size, 33949)
XCTAssertEqual(videoInfo.thumbnailInfo?.size ?? 0, 33949, accuracy: 100)
XCTAssertEqual(videoInfo.thumbnailInfo?.width, 800)
XCTAssertEqual(videoInfo.thumbnailInfo?.height, 450)
}
@@ -109,14 +109,14 @@ final class MediaUploadingPreprocessorTests: XCTestCase {
// Check resulting video info
XCTAssertEqual(videoInfo.mimetype, "video/mp4")
XCTAssertEqual(videoInfo.blurhash, "K7C$_zt70LKQMx^+~B9GIU")
XCTAssertEqual(videoInfo.size, 9_775_822)
XCTAssertEqual(videoInfo.size ?? 0, 9_775_822, accuracy: 100)
XCTAssertEqual(videoInfo.width, 1080)
XCTAssertEqual(videoInfo.height, 1920)
XCTAssertEqual(floor(videoInfo.duration ?? 0), 21000)
XCTAssertEqual(videoInfo.duration ?? 0, 21000, accuracy: 100)
XCTAssertNotNil(videoInfo.thumbnailInfo)
XCTAssertEqual(videoInfo.thumbnailInfo?.mimetype, "image/jpeg")
XCTAssertEqual(videoInfo.thumbnailInfo?.size, 82854)
XCTAssertEqual(videoInfo.thumbnailInfo?.size ?? 0, 82854, accuracy: 100)
XCTAssertEqual(videoInfo.thumbnailInfo?.width, 337)
XCTAssertEqual(videoInfo.thumbnailInfo?.height, 600)
}
@@ -138,13 +138,13 @@ final class MediaUploadingPreprocessorTests: XCTestCase {
// Check resulting image info
XCTAssertEqual(imageInfo.mimetype, "image/jpeg")
XCTAssertEqual(imageInfo.blurhash, "K%I#.NofkC_4ayayxujsWB")
XCTAssertEqual(imageInfo.size, 3_305_795)
XCTAssertEqual(imageInfo.size ?? 0, 3_305_795, accuracy: 100)
XCTAssertEqual(imageInfo.width, 6103)
XCTAssertEqual(imageInfo.height, 2621)
XCTAssertNotNil(imageInfo.thumbnailInfo)
XCTAssertEqual(imageInfo.thumbnailInfo?.mimetype, "image/jpeg")
XCTAssertEqual(imageInfo.thumbnailInfo?.size, 89553)
XCTAssertEqual(imageInfo.thumbnailInfo?.size ?? 0, 89553, accuracy: 100)
XCTAssertEqual(imageInfo.thumbnailInfo?.width, 800)
XCTAssertEqual(imageInfo.thumbnailInfo?.height, 344)
}
@@ -166,13 +166,13 @@ final class MediaUploadingPreprocessorTests: XCTestCase {
// Check resulting image info
XCTAssertEqual(imageInfo.mimetype, "image/jpeg")
XCTAssertEqual(imageInfo.blurhash, "KdE:ets+RP^-n*RP%OWAV@")
XCTAssertEqual(imageInfo.size, 4_414_666)
XCTAssertEqual(imageInfo.size ?? 0, 4_414_666, accuracy: 100)
XCTAssertEqual(imageInfo.width, 3024)
XCTAssertEqual(imageInfo.height, 4032)
XCTAssertNotNil(imageInfo.thumbnailInfo)
XCTAssertEqual(imageInfo.thumbnailInfo?.mimetype, "image/jpeg")
XCTAssertEqual(imageInfo.thumbnailInfo?.size, 264_500)
XCTAssertEqual(imageInfo.thumbnailInfo?.size ?? 0, 264_500, accuracy: 100)
XCTAssertEqual(imageInfo.thumbnailInfo?.width, 600)
XCTAssertEqual(imageInfo.thumbnailInfo?.height, 800)
}
@@ -23,7 +23,7 @@ import XCTest
@MainActor
final class NotificationManagerTests: XCTestCase {
var notificationManager: NotificationManager!
private let clientProxy = MockClientProxy(userID: "@test:user.net")
private let clientProxy = ClientProxyMock(.init(userID: "@test:user.net"))
private lazy var mockUserSession = MockUserSession(clientProxy: clientProxy,
mediaProvider: MockMediaProvider(),
voiceMessageMediaManager: VoiceMessageMediaManagerMock())
@@ -53,7 +53,8 @@ final class NotificationManagerTests: XCTestCase {
func test_whenRegistered_pusherIsCalled() async {
_ = await notificationManager.register(with: Data())
XCTAssertTrue(clientProxy.setPusherCalled)
XCTAssertTrue(clientProxy.setPusherWithCalled)
}
func test_whenRegisteredSuccess_completionSuccessIsCalled() async throws {
@@ -65,21 +66,28 @@ final class NotificationManagerTests: XCTestCase {
enum TestError: Error {
case someError
}
clientProxy.setPusherErrorToThrow = TestError.someError
clientProxy.setPusherWithThrowableError = TestError.someError
let success = await notificationManager.register(with: Data())
XCTAssertFalse(success)
}
func test_whenRegistered_pusherIsCalledWithCorrectValues() async throws {
let pushkeyData = Data("1234".utf8)
_ = await notificationManager.register(with: pushkeyData)
XCTAssertEqual(clientProxy.setPusherArgument?.identifiers.pushkey, pushkeyData.base64EncodedString())
XCTAssertEqual(clientProxy.setPusherArgument?.identifiers.appId, appSettings.pusherAppId)
XCTAssertEqual(clientProxy.setPusherArgument?.appDisplayName, "\(InfoPlistReader.main.bundleDisplayName) (iOS)")
XCTAssertEqual(clientProxy.setPusherArgument?.deviceDisplayName, UIDevice.current.name)
XCTAssertNotNil(clientProxy.setPusherArgument?.profileTag)
XCTAssertEqual(clientProxy.setPusherArgument?.lang, Bundle.app.preferredLocalizations.first)
guard case let .http(data) = clientProxy.setPusherArgument?.kind else {
guard let configuration = clientProxy.setPusherWithReceivedInvocations.first else {
XCTFail("Invalid pusher configuration sent")
return
}
XCTAssertEqual(configuration.identifiers.pushkey, pushkeyData.base64EncodedString())
XCTAssertEqual(configuration.identifiers.appId, appSettings.pusherAppId)
XCTAssertEqual(configuration.appDisplayName, "\(InfoPlistReader.main.bundleDisplayName) (iOS)")
XCTAssertEqual(configuration.deviceDisplayName, UIDevice.current.name)
XCTAssertNotNil(configuration.profileTag)
XCTAssertEqual(configuration.lang, Bundle.app.preferredLocalizations.first)
guard case let .http(data) = configuration.kind else {
XCTFail("Http kind expected")
return
}
@@ -30,7 +30,7 @@ class NotificationSettingsEditScreenViewModelTests: XCTestCase {
}
@MainActor override func setUpWithError() throws {
let clientProxy = MockClientProxy(userID: "@a:b.com")
let clientProxy = ClientProxyMock(.init(userID: "@a:b.com"))
userSession = MockUserSession(clientProxy: clientProxy,
mediaProvider: MockMediaProvider(),
voiceMessageMediaManager: VoiceMessageMediaManagerMock())
@@ -27,7 +27,7 @@ class RoomFlowCoordinatorTests: XCTestCase {
override func setUp() async throws {
cancellables.removeAll()
let clientProxy = MockClientProxy(userID: "hi@bob", roomSummaryProvider: MockRoomSummaryProvider(state: .loaded(.mockRooms)))
let clientProxy = ClientProxyMock(.init(userID: "hi@bob", roomSummaryProvider: MockRoomSummaryProvider(state: .loaded(.mockRooms))))
let mediaProvider = MockMediaProvider()
let voiceMessageMediaManager = VoiceMessageMediaManagerMock()
let userSession = MockUserSession(clientProxy: clientProxy,
@@ -27,7 +27,7 @@ class SettingsScreenViewModelTests: XCTestCase {
@MainActor override func setUpWithError() throws {
cancellables.removeAll()
let userSession = MockUserSession(clientProxy: MockClientProxy(userID: ""),
let userSession = MockUserSession(clientProxy: ClientProxyMock(.init(userID: "")),
mediaProvider: MockMediaProvider(),
voiceMessageMediaManager: VoiceMessageMediaManagerMock())
viewModel = SettingsScreenViewModel(userSession: userSession, appSettings: ServiceLocator.shared.settings)
@@ -21,7 +21,7 @@ import XCTest
@MainActor
class StartChatScreenViewModelTests: XCTestCase {
var viewModel: StartChatScreenViewModelProtocol!
var clientProxy: MockClientProxy!
var clientProxy: ClientProxyMock!
var userDiscoveryService: UserDiscoveryServiceMock!
var context: StartChatScreenViewModel.Context {
@@ -29,7 +29,7 @@ class StartChatScreenViewModelTests: XCTestCase {
}
override func setUpWithError() throws {
clientProxy = .init(userID: "")
clientProxy = .init(.init(userID: ""))
userDiscoveryService = UserDiscoveryServiceMock()
userDiscoveryService.fetchSuggestionsReturnValue = .success([])
userDiscoveryService.searchProfilesWithReturnValue = .success([])
@@ -21,68 +21,68 @@ import XCTest
@MainActor
class UserDiscoveryServiceTest: XCTestCase {
var service: UserDiscoveryService!
var clientProxy: MockClientProxy!
var clientProxy: ClientProxyMock!
override func setUpWithError() throws {
clientProxy = .init(userID: "@foo:matrix.org")
clientProxy = .init(.init(userID: "@foo:matrix.org"))
service = UserDiscoveryService(clientProxy: clientProxy)
}
func testQueryShowingResults() async throws {
clientProxy.searchUsersResult = .success(.init(results: [UserProfileProxy.mockAlice], limited: true))
clientProxy.searchUsersSearchTermLimitReturnValue = .success(.init(results: [UserProfileProxy.mockAlice], limited: true))
let results = await (try? search(query: "AAA").get()) ?? []
assertSearchResults(results, toBe: 1)
}
func testOwnerIsFiltered() async throws {
clientProxy.searchUsersResult = .success(.init(results: [UserProfileProxy(userID: "@foo:matrix.org")], limited: true))
clientProxy.searchUsersSearchTermLimitReturnValue = .success(.init(results: [UserProfileProxy(userID: "@foo:matrix.org")], limited: true))
let results = await (try? search(query: "AAA").get()) ?? []
assertSearchResults(results, toBe: 0)
}
func testGetProfileIsNotCalled() async {
clientProxy.searchUsersResult = .success(.init(results: searchResults, limited: true))
clientProxy.getProfileResult = .success(.init(userID: "@alice:matrix.org"))
clientProxy.searchUsersSearchTermLimitReturnValue = .success(.init(results: searchResults, limited: true))
clientProxy.profileForReturnValue = .success(.init(userID: "@alice:matrix.org"))
let results = await (try? search(query: "AAA").get()) ?? []
assertSearchResults(results, toBe: 3)
XCTAssertFalse(clientProxy.getProfileCalled)
XCTAssertFalse(clientProxy.profileForCalled)
}
func testGetProfileIsNotCalledForAccountOwnerID() async {
clientProxy.searchUsersResult = .success(.init(results: searchResults, limited: true))
clientProxy.getProfileResult = .success(.init(userID: "@alice:matrix.org"))
clientProxy.searchUsersSearchTermLimitReturnValue = .success(.init(results: searchResults, limited: true))
clientProxy.profileForReturnValue = .success(.init(userID: "@alice:matrix.org"))
let results = await (try? search(query: "foo:matrix.org").get()) ?? []
assertSearchResults(results, toBe: 3)
XCTAssertFalse(clientProxy.getProfileCalled)
XCTAssertFalse(clientProxy.profileForCalled)
}
func testLocalResultShows() async {
clientProxy.searchUsersResult = .success(.init(results: searchResults, limited: true))
clientProxy.getProfileResult = .success(.init(userID: "@some:matrix.org"))
clientProxy.searchUsersSearchTermLimitReturnValue = .success(.init(results: searchResults, limited: true))
clientProxy.profileForReturnValue = .success(.init(userID: "@some:matrix.org"))
let results = await (try? search(query: "@a:b.com").get()) ?? []
assertSearchResults(results, toBe: 4)
XCTAssertTrue(clientProxy.getProfileCalled)
XCTAssertTrue(clientProxy.profileForCalled)
}
func testLocalResultShowsOnSearchError() async {
clientProxy.searchUsersResult = .failure(.failedSearchingUsers)
clientProxy.getProfileResult = .success(.init(userID: "@some:matrix.org"))
clientProxy.searchUsersSearchTermLimitReturnValue = .failure(.failedSearchingUsers)
clientProxy.profileForReturnValue = .success(.init(userID: "@some:matrix.org"))
let results = await (try? search(query: "@a:b.com").get()) ?? []
assertSearchResults(results, toBe: 1)
XCTAssertTrue(clientProxy.getProfileCalled)
XCTAssertTrue(clientProxy.profileForCalled)
}
func testSearchErrorTriggers() async {
clientProxy.searchUsersResult = .failure(.failedSearchingUsers)
clientProxy.getProfileResult = .success(.init(userID: "@some:matrix.org"))
clientProxy.searchUsersSearchTermLimitReturnValue = .failure(.failedSearchingUsers)
clientProxy.profileForReturnValue = .success(.init(userID: "@some:matrix.org"))
switch await search(query: "some query") {
case .success:
@@ -91,30 +91,30 @@ class UserDiscoveryServiceTest: XCTestCase {
XCTAssertEqual(error, UserDiscoveryErrorType.failedSearchingUsers)
}
XCTAssertFalse(clientProxy.getProfileCalled)
XCTAssertFalse(clientProxy.profileForCalled)
}
func testLocalResultWithDuplicates() async {
clientProxy.searchUsersResult = .success(.init(results: searchResults, limited: true))
clientProxy.getProfileResult = .success(.init(userID: "@bob:matrix.org"))
clientProxy.searchUsersSearchTermLimitReturnValue = .success(.init(results: searchResults, limited: true))
clientProxy.profileForReturnValue = .success(.init(userID: "@bob:matrix.org"))
let results = await (try? search(query: "@a:b.com").get()) ?? []
assertSearchResults(results, toBe: 3)
let firstUserID = results.first?.userID
XCTAssertEqual(firstUserID, "@bob:matrix.org")
XCTAssertTrue(clientProxy.getProfileCalled)
XCTAssertTrue(clientProxy.profileForCalled)
}
func testSearchResultsShowWhenGetProfileFails() async {
clientProxy.searchUsersResult = .success(.init(results: searchResults, limited: true))
clientProxy.getProfileResult = .failure(.failedGettingUserProfile)
clientProxy.searchUsersSearchTermLimitReturnValue = .success(.init(results: searchResults, limited: true))
clientProxy.profileForReturnValue = .failure(.failedGettingUserProfile)
let results = await (try? search(query: "@a:b.com").get()) ?? []
let firstUserID = results.first?.userID
XCTAssertEqual(firstUserID, "@a:b.com")
XCTAssertTrue(clientProxy.getProfileCalled)
XCTAssertTrue(clientProxy.profileForCalled)
}
// MARK: - Private
@@ -19,11 +19,15 @@ import XCTest
final class UserSessionTests: XCTestCase {
var userSession: UserSession!
let clientProxy = MockClientProxy(userID: "@test:user.net")
var clientProxy: ClientProxyMock!
let actionsPublisher = PassthroughSubject<ClientProxyAction, Never>()
private var cancellables = Set<AnyCancellable>()
override func setUpWithError() throws {
clientProxy = ClientProxyMock(.init(userID: "@test:user.net"))
clientProxy.actionsPublisher = actionsPublisher.eraseToAnyPublisher()
cancellables.removeAll()
userSession = UserSession(clientProxy: clientProxy,
mediaProvider: MockMediaProvider(),
@@ -42,8 +46,11 @@ final class UserSessionTests: XCTestCase {
let controller = SessionVerificationControllerProxyMock.configureMock(callbacks: PassthroughSubject<SessionVerificationControllerProxyCallback, Never>(),
isVerified: false,
requestDelay: .zero)
clientProxy.sessionVerificationControllerProxyResult = .success(controller)
clientProxy.actionsSubject.send(.receivedSyncUpdate)
clientProxy.sessionVerificationControllerProxyReturnValue = .success(controller)
actionsPublisher.send(.receivedSyncUpdate)
waitForExpectations(timeout: 1.0)
}
@@ -52,7 +59,7 @@ final class UserSessionTests: XCTestCase {
let controller = SessionVerificationControllerProxyMock.configureMock(callbacks: PassthroughSubject<SessionVerificationControllerProxyCallback, Never>(),
isVerified: false,
requestDelay: .zero)
clientProxy.sessionVerificationControllerProxyResult = .success(controller)
clientProxy.sessionVerificationControllerProxyReturnValue = .success(controller)
controller.callbacks.sink { value in
switch value {
@@ -64,7 +71,7 @@ final class UserSessionTests: XCTestCase {
}
.store(in: &cancellables)
clientProxy.actionsSubject.send(.receivedSyncUpdate)
actionsPublisher.send(.receivedSyncUpdate)
controller.callbacks.send(.finished)
waitForExpectations(timeout: 1.0)
}
@@ -31,7 +31,7 @@ class WaitlistScreenViewModelTests: XCTestCase {
XCTAssertNil(context.viewState.userSession, "No user session should be set on a new view model.")
XCTAssertTrue(context.viewState.isWaiting, "The view should start off in the waiting state.")
viewModel.update(userSession: MockUserSession(clientProxy: MockClientProxy(userID: "@alice:matrix.org"),
viewModel.update(userSession: MockUserSession(clientProxy: ClientProxyMock(.init(userID: "@alice:matrix.org")),
mediaProvider: MockMediaProvider(),
voiceMessageMediaManager: VoiceMessageMediaManagerMock()))