2023-09-29 15:40:31 +02:00
|
|
|
//
|
2024-09-06 16:34:30 +03:00
|
|
|
// Copyright 2023, 2024 New Vector Ltd.
|
2023-09-29 15:40:31 +02:00
|
|
|
//
|
2025-01-06 11:27:37 +01:00
|
|
|
// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
|
|
|
|
// Please see LICENSE files in the repository root for full details.
|
2023-09-29 15:40:31 +02:00
|
|
|
//
|
|
|
|
|
|
|
|
import Combine
|
|
|
|
import XCTest
|
|
|
|
|
|
|
|
@testable import ElementX
|
|
|
|
|
|
|
|
@MainActor
|
|
|
|
class PillContextTests: XCTestCase {
|
2025-02-25 14:46:01 +01:00
|
|
|
func testUser() async {
|
2023-09-29 15:40:31 +02:00
|
|
|
let id = "@test:matrix.org"
|
2024-08-20 16:13:27 +03:00
|
|
|
let proxyMock = JoinedRoomProxyMock(.init(name: "Test"))
|
2023-09-29 15:40:31 +02:00
|
|
|
let subject = CurrentValueSubject<[RoomMemberProxyProtocol], Never>([])
|
2024-02-28 13:21:54 +02:00
|
|
|
proxyMock.membersPublisher = subject.asCurrentValuePublisher()
|
2024-08-13 13:36:40 +02:00
|
|
|
let mock = TimelineViewModel(roomProxy: proxyMock,
|
2025-02-03 14:14:01 +00:00
|
|
|
timelineController: MockTimelineController(),
|
2024-10-02 17:41:08 +01:00
|
|
|
mediaProvider: MediaProviderMock(configuration: .init()),
|
2024-08-13 13:36:40 +02:00
|
|
|
mediaPlayerProvider: MediaPlayerProviderMock(),
|
|
|
|
voiceMessageMediaManager: VoiceMessageMediaManagerMock(),
|
|
|
|
userIndicatorController: ServiceLocator.shared.userIndicatorController,
|
|
|
|
appMediator: AppMediatorMock.default,
|
|
|
|
appSettings: ServiceLocator.shared.settings,
|
2024-10-25 19:58:56 +03:00
|
|
|
analyticsService: ServiceLocator.shared.analytics,
|
2025-02-03 14:14:01 +00:00
|
|
|
emojiProvider: EmojiProvider(appSettings: ServiceLocator.shared.settings),
|
2025-02-25 14:46:01 +01:00
|
|
|
timelineControllerFactory: TimelineControllerFactoryMock(.init()),
|
|
|
|
clientProxy: ClientProxyMock(.init()))
|
2024-08-13 13:36:40 +02:00
|
|
|
let context = PillContext(timelineContext: mock.context, data: PillTextAttachmentData(type: .user(userID: id), font: .preferredFont(forTextStyle: .body)))
|
2023-09-29 15:40:31 +02:00
|
|
|
|
|
|
|
XCTAssertFalse(context.viewState.isOwnMention)
|
|
|
|
XCTAssertEqual(context.viewState.displayText, id)
|
|
|
|
|
|
|
|
let name = "Mr. Test"
|
|
|
|
let avatarURL = URL(string: "https://test.jpg")
|
|
|
|
subject.send([RoomMemberProxyMock(with: .init(userID: id, displayName: name, avatarURL: avatarURL, membership: .join))])
|
|
|
|
await Task.yield()
|
|
|
|
|
|
|
|
XCTAssertFalse(context.viewState.isOwnMention)
|
2025-02-25 14:46:01 +01:00
|
|
|
XCTAssertNil(context.viewState.image)
|
2023-10-27 09:29:20 +02:00
|
|
|
XCTAssertEqual(context.viewState.displayText, "@\(name)")
|
2023-09-29 15:40:31 +02:00
|
|
|
}
|
|
|
|
|
2025-02-25 14:46:01 +01:00
|
|
|
func testOwnUser() {
|
2023-09-29 15:40:31 +02:00
|
|
|
let id = "@test:matrix.org"
|
2024-08-20 16:13:27 +03:00
|
|
|
let proxyMock = JoinedRoomProxyMock(.init(name: "Test", ownUserID: id))
|
2023-09-29 15:40:31 +02:00
|
|
|
let subject = CurrentValueSubject<[RoomMemberProxyProtocol], Never>([])
|
2024-02-28 13:21:54 +02:00
|
|
|
proxyMock.membersPublisher = subject.asCurrentValuePublisher()
|
2024-08-13 13:36:40 +02:00
|
|
|
let mock = TimelineViewModel(roomProxy: proxyMock,
|
2025-02-03 14:14:01 +00:00
|
|
|
timelineController: MockTimelineController(),
|
2024-10-02 17:41:08 +01:00
|
|
|
mediaProvider: MediaProviderMock(configuration: .init()),
|
2024-08-13 13:36:40 +02:00
|
|
|
mediaPlayerProvider: MediaPlayerProviderMock(),
|
|
|
|
voiceMessageMediaManager: VoiceMessageMediaManagerMock(),
|
|
|
|
userIndicatorController: ServiceLocator.shared.userIndicatorController,
|
|
|
|
appMediator: AppMediatorMock.default,
|
|
|
|
appSettings: ServiceLocator.shared.settings,
|
2024-10-25 19:58:56 +03:00
|
|
|
analyticsService: ServiceLocator.shared.analytics,
|
2025-02-03 14:14:01 +00:00
|
|
|
emojiProvider: EmojiProvider(appSettings: ServiceLocator.shared.settings),
|
2025-02-25 14:46:01 +01:00
|
|
|
timelineControllerFactory: TimelineControllerFactoryMock(.init()),
|
|
|
|
clientProxy: ClientProxyMock(.init()))
|
2024-08-13 13:36:40 +02:00
|
|
|
let context = PillContext(timelineContext: mock.context, data: PillTextAttachmentData(type: .user(userID: id), font: .preferredFont(forTextStyle: .body)))
|
2023-09-29 15:40:31 +02:00
|
|
|
|
2025-02-25 14:46:01 +01:00
|
|
|
XCTAssertNil(context.viewState.image)
|
2023-09-29 15:40:31 +02:00
|
|
|
XCTAssertTrue(context.viewState.isOwnMention)
|
|
|
|
}
|
|
|
|
|
2025-02-25 14:46:01 +01:00
|
|
|
func testAllUsers() {
|
2023-09-29 15:40:31 +02:00
|
|
|
let avatarURL = URL(string: "https://matrix.jpg")
|
|
|
|
let id = "test_room"
|
|
|
|
let displayName = "Test"
|
2024-08-20 16:13:27 +03:00
|
|
|
let proxyMock = JoinedRoomProxyMock(.init(id: id, name: displayName, avatarURL: avatarURL))
|
2025-02-03 14:14:01 +00:00
|
|
|
let mockController = MockTimelineController()
|
2023-09-29 15:40:31 +02:00
|
|
|
mockController.roomProxy = proxyMock
|
2024-08-13 13:36:40 +02:00
|
|
|
let mock = TimelineViewModel(roomProxy: proxyMock,
|
|
|
|
timelineController: mockController,
|
2024-10-02 17:41:08 +01:00
|
|
|
mediaProvider: MediaProviderMock(configuration: .init()),
|
2024-08-13 13:36:40 +02:00
|
|
|
mediaPlayerProvider: MediaPlayerProviderMock(),
|
|
|
|
voiceMessageMediaManager: VoiceMessageMediaManagerMock(),
|
|
|
|
userIndicatorController: ServiceLocator.shared.userIndicatorController,
|
|
|
|
appMediator: AppMediatorMock.default,
|
|
|
|
appSettings: ServiceLocator.shared.settings,
|
2024-10-25 19:58:56 +03:00
|
|
|
analyticsService: ServiceLocator.shared.analytics,
|
2025-02-03 14:14:01 +00:00
|
|
|
emojiProvider: EmojiProvider(appSettings: ServiceLocator.shared.settings),
|
2025-02-25 14:46:01 +01:00
|
|
|
timelineControllerFactory: TimelineControllerFactoryMock(.init()),
|
|
|
|
clientProxy: ClientProxyMock(.init()))
|
2024-08-13 13:36:40 +02:00
|
|
|
let context = PillContext(timelineContext: mock.context, data: PillTextAttachmentData(type: .allUsers, font: .preferredFont(forTextStyle: .body)))
|
2023-09-29 15:40:31 +02:00
|
|
|
|
|
|
|
XCTAssertTrue(context.viewState.isOwnMention)
|
2025-02-25 14:46:01 +01:00
|
|
|
XCTAssertNil(context.viewState.image)
|
2023-10-27 09:29:20 +02:00
|
|
|
XCTAssertEqual(context.viewState.displayText, PillConstants.atRoom)
|
2023-09-29 15:40:31 +02:00
|
|
|
}
|
2025-02-25 14:46:01 +01:00
|
|
|
|
|
|
|
func testRoomIDMention() {
|
|
|
|
let proxyMock = JoinedRoomProxyMock(.init())
|
|
|
|
let mockController = MockTimelineController()
|
|
|
|
let clientMock = ClientProxyMock(.init())
|
|
|
|
clientMock.roomSummaryForIdentifierReturnValue = .mock(id: "1", name: "Foundation 🔭🪐🌌")
|
|
|
|
mockController.roomProxy = proxyMock
|
|
|
|
let mock = TimelineViewModel(roomProxy: proxyMock,
|
|
|
|
timelineController: mockController,
|
|
|
|
mediaProvider: MediaProviderMock(configuration: .init()),
|
|
|
|
mediaPlayerProvider: MediaPlayerProviderMock(),
|
|
|
|
voiceMessageMediaManager: VoiceMessageMediaManagerMock(),
|
|
|
|
userIndicatorController: ServiceLocator.shared.userIndicatorController,
|
|
|
|
appMediator: AppMediatorMock.default,
|
|
|
|
appSettings: ServiceLocator.shared.settings,
|
|
|
|
analyticsService: ServiceLocator.shared.analytics,
|
|
|
|
emojiProvider: EmojiProvider(appSettings: ServiceLocator.shared.settings),
|
|
|
|
timelineControllerFactory: TimelineControllerFactoryMock(.init()),
|
|
|
|
clientProxy: clientMock)
|
|
|
|
let context = PillContext(timelineContext: mock.context, data: PillTextAttachmentData(type: .roomID("1"), font: .preferredFont(forTextStyle: .body)))
|
|
|
|
|
|
|
|
XCTAssertFalse(context.viewState.isOwnMention)
|
|
|
|
XCTAssertFalse(context.viewState.isUndefined)
|
|
|
|
XCTAssertEqual(context.viewState.image, .roomAvatar(.room(id: "1", name: "Foundation 🔭🪐🌌", avatarURL: nil)))
|
|
|
|
XCTAssertEqual(context.viewState.displayText, "Foundation 🔭🪐🌌")
|
|
|
|
}
|
|
|
|
|
|
|
|
func testRoomIDMentionMissingRoom() {
|
|
|
|
let proxyMock = JoinedRoomProxyMock(.init())
|
|
|
|
let mockController = MockTimelineController()
|
|
|
|
mockController.roomProxy = proxyMock
|
|
|
|
let mock = TimelineViewModel(roomProxy: proxyMock,
|
|
|
|
timelineController: mockController,
|
|
|
|
mediaProvider: MediaProviderMock(configuration: .init()),
|
|
|
|
mediaPlayerProvider: MediaPlayerProviderMock(),
|
|
|
|
voiceMessageMediaManager: VoiceMessageMediaManagerMock(),
|
|
|
|
userIndicatorController: ServiceLocator.shared.userIndicatorController,
|
|
|
|
appMediator: AppMediatorMock.default,
|
|
|
|
appSettings: ServiceLocator.shared.settings,
|
|
|
|
analyticsService: ServiceLocator.shared.analytics,
|
|
|
|
emojiProvider: EmojiProvider(appSettings: ServiceLocator.shared.settings),
|
|
|
|
timelineControllerFactory: TimelineControllerFactoryMock(.init()),
|
|
|
|
clientProxy: ClientProxyMock(.init()))
|
|
|
|
let context = PillContext(timelineContext: mock.context, data: PillTextAttachmentData(type: .roomID("1"), font: .preferredFont(forTextStyle: .body)))
|
|
|
|
|
|
|
|
XCTAssertFalse(context.viewState.isOwnMention)
|
|
|
|
XCTAssertFalse(context.viewState.isUndefined)
|
|
|
|
XCTAssertEqual(context.viewState.image, .link)
|
|
|
|
XCTAssertEqual(context.viewState.displayText, "1")
|
|
|
|
}
|
|
|
|
|
|
|
|
func testRoomAliasMention() {
|
|
|
|
let proxyMock = JoinedRoomProxyMock(.init())
|
|
|
|
let mockController = MockTimelineController()
|
|
|
|
mockController.roomProxy = proxyMock
|
|
|
|
let clientMock = ClientProxyMock(.init())
|
|
|
|
clientMock.roomSummaryForAliasReturnValue = .mock(id: "2",
|
|
|
|
name: "Foundation and Empire",
|
|
|
|
canonicalAlias: "#foundation-and-empire:matrix.org")
|
|
|
|
let mock = TimelineViewModel(roomProxy: proxyMock,
|
|
|
|
timelineController: mockController,
|
|
|
|
mediaProvider: MediaProviderMock(configuration: .init()),
|
|
|
|
mediaPlayerProvider: MediaPlayerProviderMock(),
|
|
|
|
voiceMessageMediaManager: VoiceMessageMediaManagerMock(),
|
|
|
|
userIndicatorController: ServiceLocator.shared.userIndicatorController,
|
|
|
|
appMediator: AppMediatorMock.default,
|
|
|
|
appSettings: ServiceLocator.shared.settings,
|
|
|
|
analyticsService: ServiceLocator.shared.analytics,
|
|
|
|
emojiProvider: EmojiProvider(appSettings: ServiceLocator.shared.settings),
|
|
|
|
timelineControllerFactory: TimelineControllerFactoryMock(.init()),
|
|
|
|
clientProxy: clientMock)
|
|
|
|
let context = PillContext(timelineContext: mock.context, data: PillTextAttachmentData(type: .roomAlias("#foundation-and-empire:matrix.org"), font: .preferredFont(forTextStyle: .body)))
|
|
|
|
|
|
|
|
XCTAssertFalse(context.viewState.isOwnMention)
|
|
|
|
XCTAssertFalse(context.viewState.isUndefined)
|
|
|
|
XCTAssertEqual(context.viewState.image, .roomAvatar(.room(id: "2", name: "Foundation and Empire", avatarURL: nil)))
|
|
|
|
XCTAssertEqual(context.viewState.displayText, "Foundation and Empire")
|
|
|
|
}
|
|
|
|
|
|
|
|
func testRoomAliasMentionMissingRoom() {
|
|
|
|
let proxyMock = JoinedRoomProxyMock(.init())
|
|
|
|
let mockController = MockTimelineController()
|
|
|
|
mockController.roomProxy = proxyMock
|
|
|
|
let mock = TimelineViewModel(roomProxy: proxyMock,
|
|
|
|
timelineController: mockController,
|
|
|
|
mediaProvider: MediaProviderMock(configuration: .init()),
|
|
|
|
mediaPlayerProvider: MediaPlayerProviderMock(),
|
|
|
|
voiceMessageMediaManager: VoiceMessageMediaManagerMock(),
|
|
|
|
userIndicatorController: ServiceLocator.shared.userIndicatorController,
|
|
|
|
appMediator: AppMediatorMock.default,
|
|
|
|
appSettings: ServiceLocator.shared.settings,
|
|
|
|
analyticsService: ServiceLocator.shared.analytics,
|
|
|
|
emojiProvider: EmojiProvider(appSettings: ServiceLocator.shared.settings),
|
|
|
|
timelineControllerFactory: TimelineControllerFactoryMock(.init()),
|
|
|
|
clientProxy: ClientProxyMock(.init()))
|
|
|
|
let context = PillContext(timelineContext: mock.context, data: PillTextAttachmentData(type: .roomAlias("#foundation-and-empire:matrix.org"), font: .preferredFont(forTextStyle: .body)))
|
|
|
|
|
|
|
|
XCTAssertFalse(context.viewState.isOwnMention)
|
|
|
|
XCTAssertFalse(context.viewState.isUndefined)
|
|
|
|
XCTAssertEqual(context.viewState.image, .link)
|
|
|
|
XCTAssertEqual(context.viewState.displayText, "#foundation-and-empire:matrix.org")
|
|
|
|
}
|
|
|
|
|
|
|
|
func testEventOnRoomIDMention() {
|
|
|
|
let proxyMock = JoinedRoomProxyMock(.init())
|
|
|
|
let mockController = MockTimelineController()
|
|
|
|
mockController.roomProxy = proxyMock
|
|
|
|
let clientMock = ClientProxyMock(.init())
|
|
|
|
clientMock.roomSummaryForIdentifierReturnValue = .mock(id: "1", name: "Foundation 🔭🪐🌌")
|
|
|
|
let mock = TimelineViewModel(roomProxy: proxyMock,
|
|
|
|
timelineController: mockController,
|
|
|
|
mediaProvider: MediaProviderMock(configuration: .init()),
|
|
|
|
mediaPlayerProvider: MediaPlayerProviderMock(),
|
|
|
|
voiceMessageMediaManager: VoiceMessageMediaManagerMock(),
|
|
|
|
userIndicatorController: ServiceLocator.shared.userIndicatorController,
|
|
|
|
appMediator: AppMediatorMock.default,
|
|
|
|
appSettings: ServiceLocator.shared.settings,
|
|
|
|
analyticsService: ServiceLocator.shared.analytics,
|
|
|
|
emojiProvider: EmojiProvider(appSettings: ServiceLocator.shared.settings),
|
|
|
|
timelineControllerFactory: TimelineControllerFactoryMock(.init()),
|
|
|
|
clientProxy: clientMock)
|
|
|
|
let context = PillContext(timelineContext: mock.context, data: PillTextAttachmentData(type: .event(room: .roomID("1")), font: .preferredFont(forTextStyle: .body)))
|
|
|
|
|
|
|
|
XCTAssertFalse(context.viewState.isOwnMention)
|
|
|
|
XCTAssertFalse(context.viewState.isUndefined)
|
|
|
|
XCTAssertEqual(context.viewState.image, .link)
|
|
|
|
XCTAssertEqual(context.viewState.displayText, L10n.screenRoomEventPill("Foundation 🔭🪐🌌"))
|
|
|
|
}
|
|
|
|
|
|
|
|
func testEventOnRoomIDMentionMissingRoom() {
|
|
|
|
let proxyMock = JoinedRoomProxyMock(.init())
|
|
|
|
let mockController = MockTimelineController()
|
|
|
|
mockController.roomProxy = proxyMock
|
|
|
|
let mock = TimelineViewModel(roomProxy: proxyMock,
|
|
|
|
timelineController: mockController,
|
|
|
|
mediaProvider: MediaProviderMock(configuration: .init()),
|
|
|
|
mediaPlayerProvider: MediaPlayerProviderMock(),
|
|
|
|
voiceMessageMediaManager: VoiceMessageMediaManagerMock(),
|
|
|
|
userIndicatorController: ServiceLocator.shared.userIndicatorController,
|
|
|
|
appMediator: AppMediatorMock.default,
|
|
|
|
appSettings: ServiceLocator.shared.settings,
|
|
|
|
analyticsService: ServiceLocator.shared.analytics,
|
|
|
|
emojiProvider: EmojiProvider(appSettings: ServiceLocator.shared.settings),
|
|
|
|
timelineControllerFactory: TimelineControllerFactoryMock(.init()),
|
|
|
|
clientProxy: ClientProxyMock(.init()))
|
|
|
|
let context = PillContext(timelineContext: mock.context, data: PillTextAttachmentData(type: .event(room: .roomID("1")), font: .preferredFont(forTextStyle: .body)))
|
|
|
|
|
|
|
|
XCTAssertFalse(context.viewState.isOwnMention)
|
|
|
|
XCTAssertFalse(context.viewState.isUndefined)
|
|
|
|
XCTAssertEqual(context.viewState.image, .link)
|
|
|
|
XCTAssertEqual(context.viewState.displayText, L10n.screenRoomEventPill("1"))
|
|
|
|
}
|
|
|
|
|
|
|
|
func testEventOnRoomAliasMention() async throws {
|
|
|
|
let proxyMock = JoinedRoomProxyMock(.init())
|
|
|
|
let mockController = MockTimelineController()
|
|
|
|
mockController.roomProxy = proxyMock
|
|
|
|
let clientMock = ClientProxyMock(.init())
|
|
|
|
clientMock.roomSummaryForAliasReturnValue = .mock(id: "2",
|
|
|
|
name: "Foundation and Empire",
|
|
|
|
canonicalAlias: "#foundation-and-empire:matrix.org")
|
|
|
|
let mock = TimelineViewModel(roomProxy: proxyMock,
|
|
|
|
timelineController: mockController,
|
|
|
|
mediaProvider: MediaProviderMock(configuration: .init()),
|
|
|
|
mediaPlayerProvider: MediaPlayerProviderMock(),
|
|
|
|
voiceMessageMediaManager: VoiceMessageMediaManagerMock(),
|
|
|
|
userIndicatorController: ServiceLocator.shared.userIndicatorController,
|
|
|
|
appMediator: AppMediatorMock.default,
|
|
|
|
appSettings: ServiceLocator.shared.settings,
|
|
|
|
analyticsService: ServiceLocator.shared.analytics,
|
|
|
|
emojiProvider: EmojiProvider(appSettings: ServiceLocator.shared.settings),
|
|
|
|
timelineControllerFactory: TimelineControllerFactoryMock(.init()),
|
|
|
|
clientProxy: clientMock)
|
|
|
|
let context = PillContext(timelineContext: mock.context, data: PillTextAttachmentData(type: .event(room: .roomAlias("#foundation-and-empire:matrix.org")), font: .preferredFont(forTextStyle: .body)))
|
|
|
|
|
|
|
|
XCTAssertFalse(context.viewState.isOwnMention)
|
|
|
|
XCTAssertFalse(context.viewState.isUndefined)
|
|
|
|
XCTAssertEqual(context.viewState.image, .link)
|
|
|
|
XCTAssertEqual(context.viewState.displayText, L10n.screenRoomEventPill("Foundation and Empire"))
|
|
|
|
}
|
|
|
|
|
|
|
|
func testEventOnRoomAliasMentionMissingRoom() async throws {
|
|
|
|
let proxyMock = JoinedRoomProxyMock(.init())
|
|
|
|
let mockController = MockTimelineController()
|
|
|
|
mockController.roomProxy = proxyMock
|
|
|
|
let mock = TimelineViewModel(roomProxy: proxyMock,
|
|
|
|
timelineController: mockController,
|
|
|
|
mediaProvider: MediaProviderMock(configuration: .init()),
|
|
|
|
mediaPlayerProvider: MediaPlayerProviderMock(),
|
|
|
|
voiceMessageMediaManager: VoiceMessageMediaManagerMock(),
|
|
|
|
userIndicatorController: ServiceLocator.shared.userIndicatorController,
|
|
|
|
appMediator: AppMediatorMock.default,
|
|
|
|
appSettings: ServiceLocator.shared.settings,
|
|
|
|
analyticsService: ServiceLocator.shared.analytics,
|
|
|
|
emojiProvider: EmojiProvider(appSettings: ServiceLocator.shared.settings),
|
|
|
|
timelineControllerFactory: TimelineControllerFactoryMock(.init()),
|
|
|
|
clientProxy: ClientProxyMock(.init()))
|
|
|
|
let context = PillContext(timelineContext: mock.context, data: PillTextAttachmentData(type: .event(room: .roomAlias("#foundation-and-empire:matrix.org")), font: .preferredFont(forTextStyle: .body)))
|
|
|
|
|
|
|
|
XCTAssertFalse(context.viewState.isOwnMention)
|
|
|
|
XCTAssertFalse(context.viewState.isUndefined)
|
|
|
|
XCTAssertEqual(context.viewState.image, .link)
|
|
|
|
XCTAssertEqual(context.viewState.displayText, L10n.screenRoomEventPill("#foundation-and-empire:matrix.org"))
|
|
|
|
}
|
2023-09-29 15:40:31 +02:00
|
|
|
}
|