mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-02 12:07:55 +00:00
Refactor theTimelineItemIdentifier handling; stop relying on optional EventOrTransactionIds and be explicit when setting composer modes from the draft service.
This commit is contained in:
@@ -38,7 +38,7 @@ class AudioPlayerStateTests: XCTestCase {
|
||||
override func setUp() async throws {
|
||||
audioPlayerActionsSubject = .init()
|
||||
audioPlayerSeekCallsSubject = .init()
|
||||
audioPlayerState = AudioPlayerState(id: .timelineItemIdentifier(.random), title: "", duration: Self.audioDuration)
|
||||
audioPlayerState = AudioPlayerState(id: .timelineItemIdentifier(.randomEvent), title: "", duration: Self.audioDuration)
|
||||
audioPlayerMock = buildAudioPlayerMock()
|
||||
audioPlayerMock.seekToClosure = { [weak self] progress in
|
||||
self?.audioPlayerMock.currentTime = Self.audioDuration * progress
|
||||
@@ -162,7 +162,7 @@ class AudioPlayerStateTests: XCTestCase {
|
||||
func testHandlingAudioPlayerActionDidFinishLoading() async throws {
|
||||
audioPlayerMock.duration = 10.0
|
||||
|
||||
audioPlayerState = AudioPlayerState(id: .timelineItemIdentifier(.random), title: "", duration: 0)
|
||||
audioPlayerState = AudioPlayerState(id: .timelineItemIdentifier(.randomEvent), title: "", duration: 0)
|
||||
audioPlayerState.attachAudioPlayer(audioPlayerMock)
|
||||
|
||||
let deferred = deferFulfillment(audioPlayerState.$playbackState) { action in
|
||||
|
||||
@@ -41,14 +41,14 @@ class ComposerToolbarViewModelTests: XCTestCase {
|
||||
}
|
||||
|
||||
func testComposerFocus() {
|
||||
viewModel.process(timelineAction: .setMode(mode: .edit(originalItemId: TimelineItemIdentifier(uniqueID: "mock"))))
|
||||
viewModel.process(timelineAction: .setMode(mode: .edit(originalEventOrTransactionID: .eventId(eventId: "mock"), source: .timeline)))
|
||||
XCTAssertTrue(viewModel.state.bindings.composerFocused)
|
||||
viewModel.process(timelineAction: .removeFocus)
|
||||
XCTAssertFalse(viewModel.state.bindings.composerFocused)
|
||||
}
|
||||
|
||||
func testComposerMode() {
|
||||
let mode: ComposerMode = .edit(originalItemId: TimelineItemIdentifier(uniqueID: "mock"))
|
||||
let mode: ComposerMode = .edit(originalEventOrTransactionID: .eventId(eventId: "mock"), source: .timeline)
|
||||
viewModel.process(timelineAction: .setMode(mode: mode))
|
||||
XCTAssertEqual(viewModel.state.composerMode, mode)
|
||||
viewModel.process(timelineAction: .clear)
|
||||
@@ -56,7 +56,7 @@ class ComposerToolbarViewModelTests: XCTestCase {
|
||||
}
|
||||
|
||||
func testComposerModeIsPublished() {
|
||||
let mode: ComposerMode = .edit(originalItemId: TimelineItemIdentifier(uniqueID: "mock"))
|
||||
let mode: ComposerMode = .edit(originalEventOrTransactionID: .eventId(eventId: "mock"), source: .timeline)
|
||||
let expectation = expectation(description: "Composer mode is published")
|
||||
let cancellable = viewModel
|
||||
.context
|
||||
@@ -236,7 +236,7 @@ class ComposerToolbarViewModelTests: XCTestCase {
|
||||
}
|
||||
|
||||
viewModel.context.composerFormattingEnabled = false
|
||||
viewModel.process(timelineAction: .setMode(mode: .edit(originalItemId: .init(uniqueID: "", eventOrTransactionID: .eventId(eventId: "testID")))))
|
||||
viewModel.process(timelineAction: .setMode(mode: .edit(originalEventOrTransactionID: .eventId(eventId: "testID"), source: .timeline)))
|
||||
viewModel.context.plainComposerText = .init(string: "Hello world!")
|
||||
viewModel.saveDraft()
|
||||
|
||||
@@ -257,7 +257,7 @@ class ComposerToolbarViewModelTests: XCTestCase {
|
||||
}
|
||||
|
||||
viewModel.context.composerFormattingEnabled = false
|
||||
viewModel.process(timelineAction: .setMode(mode: .reply(itemID: .init(uniqueID: "", eventOrTransactionID: .eventId(eventId: "testID")),
|
||||
viewModel.process(timelineAction: .setMode(mode: .reply(eventID: "testID",
|
||||
replyDetails: .loaded(sender: .init(id: ""),
|
||||
eventID: "testID",
|
||||
eventContent: .message(.text(.init(body: "reply text")))),
|
||||
@@ -282,7 +282,7 @@ class ComposerToolbarViewModelTests: XCTestCase {
|
||||
}
|
||||
|
||||
viewModel.context.composerFormattingEnabled = false
|
||||
viewModel.process(timelineAction: .setMode(mode: .reply(itemID: .init(uniqueID: "", eventOrTransactionID: .eventId(eventId: "testID")),
|
||||
viewModel.process(timelineAction: .setMode(mode: .reply(eventID: "testID",
|
||||
replyDetails: .loaded(sender: .init(id: ""),
|
||||
eventID: "testID",
|
||||
eventContent: .message(.text(.init(body: "reply text")))),
|
||||
@@ -395,7 +395,7 @@ class ComposerToolbarViewModelTests: XCTestCase {
|
||||
|
||||
await fulfillment(of: [expectation], timeout: 10)
|
||||
XCTAssertFalse(viewModel.context.composerFormattingEnabled)
|
||||
XCTAssertEqual(viewModel.state.composerMode, .edit(originalItemId: .init(uniqueID: "", eventOrTransactionID: .eventId(eventId: "testID"))))
|
||||
XCTAssertEqual(viewModel.state.composerMode, .edit(originalEventOrTransactionID: .eventId(eventId: "testID"), source: .draftService))
|
||||
XCTAssertEqual(viewModel.context.plainComposerText, NSAttributedString(string: "Hello world!"))
|
||||
}
|
||||
|
||||
@@ -429,13 +429,13 @@ class ComposerToolbarViewModelTests: XCTestCase {
|
||||
await fulfillment(of: [draftExpectation], timeout: 10)
|
||||
XCTAssertFalse(viewModel.context.composerFormattingEnabled)
|
||||
// Testing the loading state first
|
||||
XCTAssertEqual(viewModel.state.composerMode, .reply(itemID: .init(uniqueID: "", eventOrTransactionID: .eventId(eventId: testEventID)),
|
||||
XCTAssertEqual(viewModel.state.composerMode, .reply(eventID: testEventID,
|
||||
replyDetails: .loading(eventID: testEventID),
|
||||
isThread: false))
|
||||
XCTAssertEqual(viewModel.context.plainComposerText, NSAttributedString(string: text))
|
||||
|
||||
await fulfillment(of: [loadReplyExpectation], timeout: 10)
|
||||
XCTAssertEqual(viewModel.state.composerMode, .reply(itemID: .init(uniqueID: "", eventOrTransactionID: .eventId(eventId: testEventID)),
|
||||
XCTAssertEqual(viewModel.state.composerMode, .reply(eventID: testEventID,
|
||||
replyDetails: loadedReply,
|
||||
isThread: true))
|
||||
}
|
||||
@@ -469,7 +469,7 @@ class ComposerToolbarViewModelTests: XCTestCase {
|
||||
await fulfillment(of: [draftExpectation], timeout: 10)
|
||||
XCTAssertFalse(viewModel.context.composerFormattingEnabled)
|
||||
// Testing the loading state first
|
||||
XCTAssertEqual(viewModel.state.composerMode, .reply(itemID: .init(uniqueID: "", eventOrTransactionID: .eventId(eventId: testEventID)),
|
||||
XCTAssertEqual(viewModel.state.composerMode, .reply(eventID: testEventID,
|
||||
replyDetails: .loading(eventID: testEventID),
|
||||
isThread: false))
|
||||
XCTAssertEqual(viewModel.context.plainComposerText, NSAttributedString(string: text))
|
||||
@@ -483,7 +483,7 @@ class ComposerToolbarViewModelTests: XCTestCase {
|
||||
func testSaveVolatileDraftWhenEditing() {
|
||||
viewModel.context.composerFormattingEnabled = false
|
||||
viewModel.context.plainComposerText = .init(string: "Hello world!")
|
||||
viewModel.process(timelineAction: .setMode(mode: .edit(originalItemId: .random)))
|
||||
viewModel.process(timelineAction: .setMode(mode: .edit(originalEventOrTransactionID: .eventId(eventId: UUID().uuidString), source: .timeline)))
|
||||
|
||||
let draft = draftServiceMock.saveVolatileDraftReceivedDraft
|
||||
XCTAssertNotNil(draft)
|
||||
|
||||
@@ -116,7 +116,7 @@ class LoggingTests: XCTestCase {
|
||||
func validateTimelineContentIsRedacted() throws {
|
||||
// Given timeline items that contain text
|
||||
let textAttributedString = "TextAttributed"
|
||||
let textMessage = TextRoomTimelineItem(id: .random,
|
||||
let textMessage = TextRoomTimelineItem(id: .randomEvent,
|
||||
timestamp: "",
|
||||
isOutgoing: false,
|
||||
isEditable: false,
|
||||
@@ -125,7 +125,7 @@ class LoggingTests: XCTestCase {
|
||||
sender: .init(id: "sender"),
|
||||
content: .init(body: "TextString", formattedBody: AttributedString(textAttributedString)))
|
||||
let noticeAttributedString = "NoticeAttributed"
|
||||
let noticeMessage = NoticeRoomTimelineItem(id: .random,
|
||||
let noticeMessage = NoticeRoomTimelineItem(id: .randomEvent,
|
||||
timestamp: "",
|
||||
isOutgoing: false,
|
||||
isEditable: false,
|
||||
@@ -134,7 +134,7 @@ class LoggingTests: XCTestCase {
|
||||
sender: .init(id: "sender"),
|
||||
content: .init(body: "NoticeString", formattedBody: AttributedString(noticeAttributedString)))
|
||||
let emoteAttributedString = "EmoteAttributed"
|
||||
let emoteMessage = EmoteRoomTimelineItem(id: .random,
|
||||
let emoteMessage = EmoteRoomTimelineItem(id: .randomEvent,
|
||||
timestamp: "",
|
||||
isOutgoing: false,
|
||||
isEditable: false,
|
||||
@@ -142,7 +142,7 @@ class LoggingTests: XCTestCase {
|
||||
isThreaded: false,
|
||||
sender: .init(id: "sender"),
|
||||
content: .init(body: "EmoteString", formattedBody: AttributedString(emoteAttributedString)))
|
||||
let imageMessage = ImageRoomTimelineItem(id: .init(uniqueID: "myimagemessage"),
|
||||
let imageMessage = ImageRoomTimelineItem(id: .randomEvent,
|
||||
timestamp: "",
|
||||
isOutgoing: false,
|
||||
isEditable: false,
|
||||
@@ -153,7 +153,7 @@ class LoggingTests: XCTestCase {
|
||||
caption: "ImageString",
|
||||
source: MediaSourceProxy(url: .picturesDirectory, mimeType: "image/gif"),
|
||||
thumbnailSource: nil))
|
||||
let videoMessage = VideoRoomTimelineItem(id: .random,
|
||||
let videoMessage = VideoRoomTimelineItem(id: .randomEvent,
|
||||
timestamp: "",
|
||||
isOutgoing: false,
|
||||
isEditable: false,
|
||||
@@ -165,7 +165,7 @@ class LoggingTests: XCTestCase {
|
||||
duration: 0,
|
||||
source: nil,
|
||||
thumbnailSource: nil))
|
||||
let fileMessage = FileRoomTimelineItem(id: .random,
|
||||
let fileMessage = FileRoomTimelineItem(id: .randomEvent,
|
||||
timestamp: "",
|
||||
isOutgoing: false,
|
||||
isEditable: false,
|
||||
|
||||
@@ -60,7 +60,7 @@ class MediaPlayerProviderTests: XCTestCase {
|
||||
}
|
||||
|
||||
func testPlayerStates() async throws {
|
||||
let audioPlayerStateId = AudioPlayerStateIdentifier.timelineItemIdentifier(.random)
|
||||
let audioPlayerStateId = AudioPlayerStateIdentifier.timelineItemIdentifier(.randomEvent)
|
||||
// By default, there should be no player state
|
||||
XCTAssertNil(mediaPlayerProvider.playerState(for: audioPlayerStateId))
|
||||
|
||||
@@ -76,7 +76,7 @@ class MediaPlayerProviderTests: XCTestCase {
|
||||
let audioPlayer = AudioPlayerMock()
|
||||
audioPlayer.actions = PassthroughSubject<AudioPlayerAction, Never>().eraseToAnyPublisher()
|
||||
|
||||
let audioPlayerStates = Array(repeating: AudioPlayerState(id: .timelineItemIdentifier(.random), title: "", duration: 0), count: 10)
|
||||
let audioPlayerStates = Array(repeating: AudioPlayerState(id: .timelineItemIdentifier(.randomEvent), title: "", duration: 0), count: 10)
|
||||
for audioPlayerState in audioPlayerStates {
|
||||
mediaPlayerProvider.register(audioPlayerState: audioPlayerState)
|
||||
audioPlayerState.attachAudioPlayer(audioPlayer)
|
||||
@@ -95,7 +95,7 @@ class MediaPlayerProviderTests: XCTestCase {
|
||||
let audioPlayer = AudioPlayerMock()
|
||||
audioPlayer.actions = PassthroughSubject<AudioPlayerAction, Never>().eraseToAnyPublisher()
|
||||
|
||||
let audioPlayerStates = Array(repeating: AudioPlayerState(id: .timelineItemIdentifier(.random), title: "", duration: 0), count: 10)
|
||||
let audioPlayerStates = Array(repeating: AudioPlayerState(id: .timelineItemIdentifier(.randomEvent), title: "", duration: 0), count: 10)
|
||||
for audioPlayerState in audioPlayerStates {
|
||||
mediaPlayerProvider.register(audioPlayerState: audioPlayerState)
|
||||
audioPlayerState.attachAudioPlayer(audioPlayer)
|
||||
|
||||
@@ -12,7 +12,7 @@ import XCTest
|
||||
|
||||
@MainActor
|
||||
class MessageForwardingScreenViewModelTests: XCTestCase {
|
||||
let forwardingItem = MessageForwardingItem(id: .init(uniqueID: "t1", eventOrTransactionID: .eventId(eventId: "t1")),
|
||||
let forwardingItem = MessageForwardingItem(id: .event(uniqueID: "t1", eventOrTransactionID: .eventId(eventId: "t1")),
|
||||
roomID: "1",
|
||||
content: .init(noPointer: .init()))
|
||||
var viewModel: MessageForwardingScreenViewModelProtocol!
|
||||
|
||||
@@ -61,7 +61,7 @@ class ResolveVerifiedUserSendFailureScreenViewModelTests: XCTestCase {
|
||||
|
||||
private func makeViewModel(with failure: TimelineItemSendFailure.VerifiedUser) -> ResolveVerifiedUserSendFailureScreenViewModel {
|
||||
ResolveVerifiedUserSendFailureScreenViewModel(failure: failure,
|
||||
itemID: .random,
|
||||
itemID: .randomEvent,
|
||||
roomProxy: roomProxy,
|
||||
userIndicatorController: UserIndicatorControllerMock())
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ import XCTest
|
||||
final class TextBasedRoomTimelineTests: XCTestCase {
|
||||
func testTextRoomTimelineItemWhitespaceEnd() {
|
||||
let timestamp = "Now"
|
||||
let timelineItem = TextRoomTimelineItem(id: .random,
|
||||
let timelineItem = TextRoomTimelineItem(id: .randomEvent,
|
||||
timestamp: timestamp,
|
||||
isOutgoing: true,
|
||||
isEditable: true,
|
||||
@@ -24,7 +24,7 @@ final class TextBasedRoomTimelineTests: XCTestCase {
|
||||
|
||||
func testTextRoomTimelineItemWhitespaceEndLonger() {
|
||||
let timestamp = "10:00 AM"
|
||||
let timelineItem = TextRoomTimelineItem(id: .random,
|
||||
let timelineItem = TextRoomTimelineItem(id: .randomEvent,
|
||||
timestamp: timestamp,
|
||||
isOutgoing: true,
|
||||
isEditable: true,
|
||||
@@ -37,7 +37,7 @@ final class TextBasedRoomTimelineTests: XCTestCase {
|
||||
|
||||
func testTextRoomTimelineItemWhitespaceEndWithEdit() {
|
||||
let timestamp = "Now"
|
||||
var timelineItem = TextRoomTimelineItem(id: .random,
|
||||
var timelineItem = TextRoomTimelineItem(id: .randomEvent,
|
||||
timestamp: timestamp,
|
||||
isOutgoing: true,
|
||||
isEditable: true,
|
||||
@@ -52,7 +52,7 @@ final class TextBasedRoomTimelineTests: XCTestCase {
|
||||
|
||||
func testTextRoomTimelineItemWhitespaceEndWithEditAndAlert() {
|
||||
let timestamp = "Now"
|
||||
var timelineItem = TextRoomTimelineItem(id: .random,
|
||||
var timelineItem = TextRoomTimelineItem(id: .randomEvent,
|
||||
timestamp: timestamp,
|
||||
isOutgoing: true,
|
||||
isEditable: true,
|
||||
|
||||
@@ -423,7 +423,7 @@ class TimelineViewModelTests: XCTestCase {
|
||||
private extension TextRoomTimelineItem {
|
||||
init(text: String, sender: String, addReactions: Bool = false, addReadReceipts: [ReadReceipt] = []) {
|
||||
let reactions = addReactions ? [AggregatedReaction(accountOwnerID: "bob", key: "🦄", senders: [ReactionSender(id: sender, timestamp: Date())])] : []
|
||||
self.init(id: .random,
|
||||
self.init(id: .randomEvent,
|
||||
timestamp: "10:47 am",
|
||||
isOutgoing: sender == "bob",
|
||||
isEditable: sender == "bob",
|
||||
@@ -437,13 +437,13 @@ private extension TextRoomTimelineItem {
|
||||
|
||||
private extension SeparatorRoomTimelineItem {
|
||||
init(uniqueID: String) {
|
||||
self.init(id: .init(uniqueID: uniqueID), text: "")
|
||||
self.init(id: .virtual(uniqueID: uniqueID), text: "")
|
||||
}
|
||||
}
|
||||
|
||||
private extension TextRoomTimelineItem {
|
||||
init(eventID: String) {
|
||||
self.init(id: .init(uniqueID: UUID().uuidString, eventOrTransactionID: .eventId(eventId: eventID)),
|
||||
self.init(id: .event(uniqueID: UUID().uuidString, eventOrTransactionID: .eventId(eventId: eventID)),
|
||||
timestamp: "",
|
||||
isOutgoing: false,
|
||||
isEditable: false,
|
||||
|
||||
Reference in New Issue
Block a user