* migrated a lot of unit tests to Swift Testing and added a new implementation for deferred fulfillment more tests migration Cleaned the code manually to establish some good patterns more code improvements some more code improvements removed empty tests update project * more pr suggestions and cleanups * removed the TestSetup pattern * fixing claude not reusing tests * pr suggestion + added indent rule to swiftformat so that we can prevent AIs to change that
291 lines
18 KiB
Swift
291 lines
18 KiB
Swift
//
|
|
// Copyright 2025 Element Creations Ltd.
|
|
// Copyright 2023-2025 New Vector Ltd.
|
|
//
|
|
// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
|
// Please see LICENSE files in the repository root for full details.
|
|
//
|
|
|
|
import Combine
|
|
@testable import ElementX
|
|
import Foundation
|
|
import Testing
|
|
|
|
@MainActor
|
|
@Suite
|
|
struct PillContextTests {
|
|
@Test
|
|
func user() async {
|
|
let id = "@test:matrix.org"
|
|
let proxyMock = JoinedRoomProxyMock(.init(name: "Test"))
|
|
let subject = CurrentValueSubject<[RoomMemberProxyProtocol], Never>([])
|
|
proxyMock.membersPublisher = subject.asCurrentValuePublisher()
|
|
let mock = TimelineViewModel(roomProxy: proxyMock,
|
|
timelineController: MockTimelineController(),
|
|
userSession: UserSessionMock(.init()),
|
|
mediaPlayerProvider: MediaPlayerProviderMock(),
|
|
userIndicatorController: ServiceLocator.shared.userIndicatorController,
|
|
appMediator: AppMediatorMock.default,
|
|
appSettings: ServiceLocator.shared.settings,
|
|
analyticsService: ServiceLocator.shared.analytics,
|
|
emojiProvider: EmojiProvider(appSettings: ServiceLocator.shared.settings),
|
|
linkMetadataProvider: LinkMetadataProvider(),
|
|
timelineControllerFactory: TimelineControllerFactoryMock(.init()))
|
|
let context = PillContext(timelineContext: mock.context, data: PillTextAttachmentData(type: .user(userID: id), font: .preferredFont(forTextStyle: .body)))
|
|
|
|
#expect(!context.viewState.isOwnMention)
|
|
#expect(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()
|
|
|
|
#expect(!context.viewState.isOwnMention)
|
|
#expect(context.viewState.displayText == "@\(name)")
|
|
}
|
|
|
|
@Test
|
|
func ownUser() {
|
|
let id = "@test:matrix.org"
|
|
let proxyMock = JoinedRoomProxyMock(.init(name: "Test", ownUserID: id))
|
|
let subject = CurrentValueSubject<[RoomMemberProxyProtocol], Never>([])
|
|
proxyMock.membersPublisher = subject.asCurrentValuePublisher()
|
|
let mock = TimelineViewModel(roomProxy: proxyMock,
|
|
timelineController: MockTimelineController(),
|
|
userSession: UserSessionMock(.init()),
|
|
mediaPlayerProvider: MediaPlayerProviderMock(),
|
|
userIndicatorController: ServiceLocator.shared.userIndicatorController,
|
|
appMediator: AppMediatorMock.default,
|
|
appSettings: ServiceLocator.shared.settings,
|
|
analyticsService: ServiceLocator.shared.analytics,
|
|
emojiProvider: EmojiProvider(appSettings: ServiceLocator.shared.settings),
|
|
linkMetadataProvider: LinkMetadataProvider(),
|
|
timelineControllerFactory: TimelineControllerFactoryMock(.init()))
|
|
let context = PillContext(timelineContext: mock.context, data: PillTextAttachmentData(type: .user(userID: id), font: .preferredFont(forTextStyle: .body)))
|
|
|
|
#expect(context.viewState.isOwnMention)
|
|
}
|
|
|
|
@Test
|
|
func allUsers() {
|
|
let avatarURL = URL(string: "https://matrix.jpg")
|
|
let id = "test_room"
|
|
let displayName = "Test"
|
|
let proxyMock = JoinedRoomProxyMock(.init(id: id, name: displayName, avatarURL: avatarURL))
|
|
let mockController = MockTimelineController()
|
|
mockController.roomProxy = proxyMock
|
|
let mock = TimelineViewModel(roomProxy: proxyMock,
|
|
timelineController: mockController,
|
|
userSession: UserSessionMock(.init()),
|
|
mediaPlayerProvider: MediaPlayerProviderMock(),
|
|
userIndicatorController: ServiceLocator.shared.userIndicatorController,
|
|
appMediator: AppMediatorMock.default,
|
|
appSettings: ServiceLocator.shared.settings,
|
|
analyticsService: ServiceLocator.shared.analytics,
|
|
emojiProvider: EmojiProvider(appSettings: ServiceLocator.shared.settings),
|
|
linkMetadataProvider: LinkMetadataProvider(),
|
|
timelineControllerFactory: TimelineControllerFactoryMock(.init()))
|
|
let context = PillContext(timelineContext: mock.context, data: PillTextAttachmentData(type: .allUsers, font: .preferredFont(forTextStyle: .body)))
|
|
|
|
#expect(context.viewState.isOwnMention)
|
|
#expect(context.viewState.displayText == PillUtilities.atRoom)
|
|
}
|
|
|
|
@Test
|
|
func roomIDMention() {
|
|
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,
|
|
userSession: UserSessionMock(.init(clientProxy: clientMock)),
|
|
mediaPlayerProvider: MediaPlayerProviderMock(),
|
|
userIndicatorController: ServiceLocator.shared.userIndicatorController,
|
|
appMediator: AppMediatorMock.default,
|
|
appSettings: ServiceLocator.shared.settings,
|
|
analyticsService: ServiceLocator.shared.analytics,
|
|
emojiProvider: EmojiProvider(appSettings: ServiceLocator.shared.settings),
|
|
linkMetadataProvider: LinkMetadataProvider(),
|
|
timelineControllerFactory: TimelineControllerFactoryMock(.init()))
|
|
let context = PillContext(timelineContext: mock.context, data: PillTextAttachmentData(type: .roomID("1"), font: .preferredFont(forTextStyle: .body)))
|
|
|
|
#expect(!context.viewState.isOwnMention)
|
|
#expect(!context.viewState.isUndefined)
|
|
#expect(context.viewState.displayText == "#Foundation 🔭🪐🌌")
|
|
}
|
|
|
|
@Test
|
|
func roomIDMentionMissingRoom() {
|
|
let proxyMock = JoinedRoomProxyMock(.init())
|
|
let mockController = MockTimelineController()
|
|
mockController.roomProxy = proxyMock
|
|
let mock = TimelineViewModel(roomProxy: proxyMock,
|
|
timelineController: mockController,
|
|
userSession: UserSessionMock(.init()),
|
|
mediaPlayerProvider: MediaPlayerProviderMock(),
|
|
userIndicatorController: ServiceLocator.shared.userIndicatorController,
|
|
appMediator: AppMediatorMock.default,
|
|
appSettings: ServiceLocator.shared.settings,
|
|
analyticsService: ServiceLocator.shared.analytics,
|
|
emojiProvider: EmojiProvider(appSettings: ServiceLocator.shared.settings),
|
|
linkMetadataProvider: LinkMetadataProvider(),
|
|
timelineControllerFactory: TimelineControllerFactoryMock(.init()))
|
|
let context = PillContext(timelineContext: mock.context, data: PillTextAttachmentData(type: .roomID("1"), font: .preferredFont(forTextStyle: .body)))
|
|
|
|
#expect(!context.viewState.isOwnMention)
|
|
#expect(!context.viewState.isUndefined)
|
|
#expect(context.viewState.displayText == "1")
|
|
}
|
|
|
|
@Test
|
|
func roomAliasMention() {
|
|
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,
|
|
userSession: UserSessionMock(.init(clientProxy: clientMock)),
|
|
mediaPlayerProvider: MediaPlayerProviderMock(),
|
|
userIndicatorController: ServiceLocator.shared.userIndicatorController,
|
|
appMediator: AppMediatorMock.default,
|
|
appSettings: ServiceLocator.shared.settings,
|
|
analyticsService: ServiceLocator.shared.analytics,
|
|
emojiProvider: EmojiProvider(appSettings: ServiceLocator.shared.settings),
|
|
linkMetadataProvider: LinkMetadataProvider(),
|
|
timelineControllerFactory: TimelineControllerFactoryMock(.init()))
|
|
let context = PillContext(timelineContext: mock.context, data: PillTextAttachmentData(type: .roomAlias("#foundation-and-empire:matrix.org"), font: .preferredFont(forTextStyle: .body)))
|
|
|
|
#expect(!context.viewState.isOwnMention)
|
|
#expect(!context.viewState.isUndefined)
|
|
#expect(context.viewState.displayText == "#Foundation and Empire")
|
|
}
|
|
|
|
@Test
|
|
func roomAliasMentionMissingRoom() {
|
|
let proxyMock = JoinedRoomProxyMock(.init())
|
|
let mockController = MockTimelineController()
|
|
mockController.roomProxy = proxyMock
|
|
let mock = TimelineViewModel(roomProxy: proxyMock,
|
|
timelineController: mockController,
|
|
userSession: UserSessionMock(.init()),
|
|
mediaPlayerProvider: MediaPlayerProviderMock(),
|
|
userIndicatorController: ServiceLocator.shared.userIndicatorController,
|
|
appMediator: AppMediatorMock.default,
|
|
appSettings: ServiceLocator.shared.settings,
|
|
analyticsService: ServiceLocator.shared.analytics,
|
|
emojiProvider: EmojiProvider(appSettings: ServiceLocator.shared.settings),
|
|
linkMetadataProvider: LinkMetadataProvider(),
|
|
timelineControllerFactory: TimelineControllerFactoryMock(.init()))
|
|
let context = PillContext(timelineContext: mock.context, data: PillTextAttachmentData(type: .roomAlias("#foundation-and-empire:matrix.org"), font: .preferredFont(forTextStyle: .body)))
|
|
|
|
#expect(!context.viewState.isOwnMention)
|
|
#expect(!context.viewState.isUndefined)
|
|
#expect(context.viewState.displayText == "#foundation-and-empire:matrix.org")
|
|
}
|
|
|
|
@Test
|
|
func eventOnRoomIDMention() {
|
|
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,
|
|
userSession: UserSessionMock(.init(clientProxy: clientMock)),
|
|
mediaPlayerProvider: MediaPlayerProviderMock(),
|
|
userIndicatorController: ServiceLocator.shared.userIndicatorController,
|
|
appMediator: AppMediatorMock.default,
|
|
appSettings: ServiceLocator.shared.settings,
|
|
analyticsService: ServiceLocator.shared.analytics,
|
|
emojiProvider: EmojiProvider(appSettings: ServiceLocator.shared.settings),
|
|
linkMetadataProvider: LinkMetadataProvider(),
|
|
timelineControllerFactory: TimelineControllerFactoryMock(.init()))
|
|
let context = PillContext(timelineContext: mock.context, data: PillTextAttachmentData(type: .event(room: .roomID("1")), font: .preferredFont(forTextStyle: .body)))
|
|
|
|
#expect(!context.viewState.isOwnMention)
|
|
#expect(!context.viewState.isUndefined)
|
|
#expect(context.viewState.displayText == "💬 > #Foundation 🔭🪐🌌")
|
|
}
|
|
|
|
@Test
|
|
func eventOnRoomIDMentionMissingRoom() {
|
|
let proxyMock = JoinedRoomProxyMock(.init())
|
|
let mockController = MockTimelineController()
|
|
mockController.roomProxy = proxyMock
|
|
let mock = TimelineViewModel(roomProxy: proxyMock,
|
|
timelineController: mockController,
|
|
userSession: UserSessionMock(.init()),
|
|
mediaPlayerProvider: MediaPlayerProviderMock(),
|
|
userIndicatorController: ServiceLocator.shared.userIndicatorController,
|
|
appMediator: AppMediatorMock.default,
|
|
appSettings: ServiceLocator.shared.settings,
|
|
analyticsService: ServiceLocator.shared.analytics,
|
|
emojiProvider: EmojiProvider(appSettings: ServiceLocator.shared.settings),
|
|
linkMetadataProvider: LinkMetadataProvider(),
|
|
timelineControllerFactory: TimelineControllerFactoryMock(.init()))
|
|
let context = PillContext(timelineContext: mock.context, data: PillTextAttachmentData(type: .event(room: .roomID("1")), font: .preferredFont(forTextStyle: .body)))
|
|
|
|
#expect(!context.viewState.isOwnMention)
|
|
#expect(!context.viewState.isUndefined)
|
|
#expect(context.viewState.displayText == "💬 > 1")
|
|
}
|
|
|
|
@Test
|
|
func eventOnRoomAliasMention() {
|
|
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,
|
|
userSession: UserSessionMock(.init(clientProxy: clientMock)),
|
|
mediaPlayerProvider: MediaPlayerProviderMock(),
|
|
userIndicatorController: ServiceLocator.shared.userIndicatorController,
|
|
appMediator: AppMediatorMock.default,
|
|
appSettings: ServiceLocator.shared.settings,
|
|
analyticsService: ServiceLocator.shared.analytics,
|
|
emojiProvider: EmojiProvider(appSettings: ServiceLocator.shared.settings),
|
|
linkMetadataProvider: LinkMetadataProvider(),
|
|
timelineControllerFactory: TimelineControllerFactoryMock(.init()))
|
|
let context = PillContext(timelineContext: mock.context, data: PillTextAttachmentData(type: .event(room: .roomAlias("#foundation-and-empire:matrix.org")), font: .preferredFont(forTextStyle: .body)))
|
|
|
|
#expect(!context.viewState.isOwnMention)
|
|
#expect(!context.viewState.isUndefined)
|
|
#expect(context.viewState.displayText == "💬 > #Foundation and Empire")
|
|
}
|
|
|
|
@Test
|
|
func eventOnRoomAliasMentionMissingRoom() {
|
|
let proxyMock = JoinedRoomProxyMock(.init())
|
|
let mockController = MockTimelineController()
|
|
mockController.roomProxy = proxyMock
|
|
let mock = TimelineViewModel(roomProxy: proxyMock,
|
|
timelineController: mockController,
|
|
userSession: UserSessionMock(.init()),
|
|
mediaPlayerProvider: MediaPlayerProviderMock(),
|
|
userIndicatorController: ServiceLocator.shared.userIndicatorController,
|
|
appMediator: AppMediatorMock.default,
|
|
appSettings: ServiceLocator.shared.settings,
|
|
analyticsService: ServiceLocator.shared.analytics,
|
|
emojiProvider: EmojiProvider(appSettings: ServiceLocator.shared.settings),
|
|
linkMetadataProvider: LinkMetadataProvider(),
|
|
timelineControllerFactory: TimelineControllerFactoryMock(.init()))
|
|
let context = PillContext(timelineContext: mock.context, data: PillTextAttachmentData(type: .event(room: .roomAlias("#foundation-and-empire:matrix.org")), font: .preferredFont(forTextStyle: .body)))
|
|
|
|
#expect(!context.viewState.isOwnMention)
|
|
#expect(!context.viewState.isUndefined)
|
|
#expect(context.viewState.displayText == "💬 > #foundation-and-empire:matrix.org")
|
|
}
|
|
}
|