De-protocolize & de-shim EditManager

This commit is contained in:
Pete Walters
2025-11-17 10:51:21 -06:00
committed by GitHub
parent 2e348030e9
commit c2500f6dc9
10 changed files with 70 additions and 385 deletions

View File

@@ -811,7 +811,6 @@
66062E712E43F83600D5F8C1 /* OWSSequentialProgress.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66062E702E43F83200D5F8C1 /* OWSSequentialProgress.swift */; };
66076B4C2BC053290043D547 /* LinkPreviewBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66076B4B2BC053290043D547 /* LinkPreviewBuilder.swift */; };
66076B4E2BC056980043D547 /* LinkPreviewBuilderImpl.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66076B4D2BC056980043D547 /* LinkPreviewBuilderImpl.swift */; };
66076B5C2BC06CA70043D547 /* EditManagerAttachmentsShims.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66076B582BC06CA70043D547 /* EditManagerAttachmentsShims.swift */; };
66076B5D2BC06CA70043D547 /* MockEditManagerAttachments.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66076B592BC06CA70043D547 /* MockEditManagerAttachments.swift */; };
66076B5E2BC06CA70043D547 /* EditManagerAttachmentsImpl.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66076B5A2BC06CA70043D547 /* EditManagerAttachmentsImpl.swift */; };
66076B5F2BC06CA70043D547 /* EditManagerAttachments.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66076B5B2BC06CA70043D547 /* EditManagerAttachments.swift */; };
@@ -4791,7 +4790,6 @@
66062E702E43F83200D5F8C1 /* OWSSequentialProgress.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OWSSequentialProgress.swift; sourceTree = "<group>"; };
66076B4B2BC053290043D547 /* LinkPreviewBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LinkPreviewBuilder.swift; sourceTree = "<group>"; };
66076B4D2BC056980043D547 /* LinkPreviewBuilderImpl.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LinkPreviewBuilderImpl.swift; sourceTree = "<group>"; };
66076B582BC06CA70043D547 /* EditManagerAttachmentsShims.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EditManagerAttachmentsShims.swift; sourceTree = "<group>"; };
66076B592BC06CA70043D547 /* MockEditManagerAttachments.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MockEditManagerAttachments.swift; sourceTree = "<group>"; };
66076B5A2BC06CA70043D547 /* EditManagerAttachmentsImpl.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EditManagerAttachmentsImpl.swift; sourceTree = "<group>"; };
66076B5B2BC06CA70043D547 /* EditManagerAttachments.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EditManagerAttachments.swift; sourceTree = "<group>"; };
@@ -9430,7 +9428,6 @@
children = (
66076B5B2BC06CA70043D547 /* EditManagerAttachments.swift */,
66076B5A2BC06CA70043D547 /* EditManagerAttachmentsImpl.swift */,
66076B582BC06CA70043D547 /* EditManagerAttachmentsShims.swift */,
66076B592BC06CA70043D547 /* MockEditManagerAttachments.swift */,
);
path = Attachments;
@@ -18042,7 +18039,6 @@
C1DB22C329C9F95500757380 /* EditManager.swift in Sources */,
66076B5F2BC06CA70043D547 /* EditManagerAttachments.swift in Sources */,
66076B5E2BC06CA70043D547 /* EditManagerAttachmentsImpl.swift in Sources */,
66076B5C2BC06CA70043D547 /* EditManagerAttachmentsShims.swift in Sources */,
668B30092BBDD9A20001FD25 /* EditManagerImpl.swift in Sources */,
C1C4AA3329E7038D000CE9D3 /* EditManagerShims.swift in Sources */,
C167387529E8397B0068EA92 /* EditMessageStore.swift in Sources */,

View File

@@ -64,10 +64,10 @@ final class BackupArchiveTSMessageEditHistoryArchiver<MessageType: TSMessage>
private typealias ArchiveFrameError = BackupArchive.ArchiveFrameError<BackupArchive.InteractionUniqueId>
private typealias RestoreFrameError = BackupArchive.RestoreFrameError<BackupArchive.ChatItemId>
private let editMessageStore: any EditMessageStore
private let editMessageStore: EditMessageStore
init(
editMessageStore: any EditMessageStore
editMessageStore: EditMessageStore
) {
self.editMessageStore = editMessageStore
}

View File

@@ -786,18 +786,16 @@ extension AppSetup.GlobalsContinuation {
linkPreviewSettingStore: linkPreviewSettingStore
)
let editMessageStore = EditMessageStoreImpl()
let editMessageStore = EditMessageStore()
let editManager = EditManagerImpl(
context: .init(
attachmentContentValidator: attachmentContentValidator,
attachmentStore: attachmentStore,
dataStore: EditManagerImpl.Wrappers.DataStore(),
editManagerAttachments: EditManagerAttachmentsImpl(
attachmentManager: attachmentManager,
attachmentStore: attachmentStore,
attachmentValidator: attachmentContentValidator,
linkPreviewManager: linkPreviewManager,
tsMessageStore: EditManagerAttachmentsImpl.Wrappers.TSMessageStore()
),
editMessageStore: editMessageStore,
receiptManagerShim: EditManagerImpl.Wrappers.ReceiptManager(receiptManager: receiptManager)

View File

@@ -11,20 +11,17 @@ public class EditManagerAttachmentsImpl: EditManagerAttachments {
private let attachmentStore: AttachmentStore
private let attachmentValidator: AttachmentContentValidator
private let linkPreviewManager: LinkPreviewManager
private let tsMessageStore: EditManagerAttachmentsImpl.Shims.TSMessageStore
public init(
attachmentManager: AttachmentManager,
attachmentStore: AttachmentStore,
attachmentValidator: AttachmentContentValidator,
linkPreviewManager: LinkPreviewManager,
tsMessageStore: EditManagerAttachmentsImpl.Shims.TSMessageStore
) {
self.attachmentManager = attachmentManager
self.attachmentStore = attachmentStore
self.attachmentValidator = attachmentValidator
self.linkPreviewManager = linkPreviewManager
self.tsMessageStore = tsMessageStore
}
public func reconcileAttachments<EditTarget: EditMessageWrapper>(
@@ -102,7 +99,7 @@ public class EditManagerAttachmentsImpl: EditManagerAttachments {
if let quotedReplyPriorToEdit {
// If we had a quoted reply, always keep it on the prior revision.
tsMessageStore.update(priorRevision, with: quotedReplyPriorToEdit, tx: tx)
priorRevision.update(with: quotedReplyPriorToEdit, transaction: tx)
}
if let attachmentReferencePriorToEdit {
// IMPORTANT: we MUST assign the prior revision owner BEFORE removing
@@ -129,7 +126,7 @@ public class EditManagerAttachmentsImpl: EditManagerAttachments {
case .keep:
if let quotedReplyPriorToEdit {
// The latest revision keeps the prior revision's quoted reply.
tsMessageStore.update(latestRevision, with: quotedReplyPriorToEdit, tx: tx)
latestRevision.update(with: quotedReplyPriorToEdit, transaction: tx)
}
if let attachmentReferencePriorToEdit {
@@ -175,7 +172,7 @@ public class EditManagerAttachmentsImpl: EditManagerAttachments {
if let linkPreviewPriorToEdit {
// If we had a link preview, always keep it on the prior revision.
tsMessageStore.update(priorRevision, with: linkPreviewPriorToEdit, tx: tx)
priorRevision.update(with: linkPreviewPriorToEdit, transaction: tx)
}
if let attachmentReferencePriorToEdit {
// IMPORTANT: we MUST assign the prior revision owner BEFORE removing
@@ -220,7 +217,7 @@ public class EditManagerAttachmentsImpl: EditManagerAttachments {
builder: builder,
tx: tx
)
tsMessageStore.update(latestRevision, with: builder.info, tx: tx)
latestRevision.update(with: builder.info, transaction: tx)
try builder.finalize(
owner: .messageLinkPreview(.init(
messageRowId: latestRevisionRowId,
@@ -252,7 +249,7 @@ public class EditManagerAttachmentsImpl: EditManagerAttachments {
} catch let error {
throw error
}
tsMessageStore.update(latestRevision, with: linkPreviewBuilder.info, tx: tx)
latestRevision.update(with: linkPreviewBuilder.info, transaction: tx)
try linkPreviewBuilder.finalize(
owner: .messageLinkPreview(.init(
messageRowId: latestRevisionRowId,

View File

@@ -1,55 +0,0 @@
//
// Copyright 2023 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
//
import Foundation
import LibSignalClient
extension EditManagerAttachmentsImpl {
public enum Shims {
public typealias TSMessageStore = _EditManagerAttachmentsImpl_TSMessageStoreShim
}
public enum Wrappers {
public typealias TSMessageStore = _EditManagerAttachmentsImpl_TSMessageStoreWrapper
}
}
// MARK: - EditManager.TSMessageStore
public protocol _EditManagerAttachmentsImpl_TSMessageStoreShim {
func update(
_ message: TSMessage,
with quotedReply: TSQuotedMessage,
tx: DBWriteTransaction
)
func update(
_ message: TSMessage,
with linkPreview: OWSLinkPreview,
tx: DBWriteTransaction
)
}
public class _EditManagerAttachmentsImpl_TSMessageStoreWrapper: EditManagerAttachmentsImpl.Shims.TSMessageStore {
public init() {}
public func update(
_ message: TSMessage,
with quotedReply: TSQuotedMessage,
tx: DBWriteTransaction
) {
message.update(with: quotedReply, transaction: tx)
}
public func update(
_ message: TSMessage,
with linkPreview: OWSLinkPreview,
tx: DBWriteTransaction
) {
message.update(with: linkPreview, transaction: tx)
}
}

View File

@@ -32,7 +32,6 @@ public class EditManagerImpl: EditManager {
public struct Context {
let attachmentContentValidator: AttachmentContentValidator
let attachmentStore: AttachmentStore
let dataStore: EditManagerImpl.Shims.DataStore
let editManagerAttachments: EditManagerAttachments
let editMessageStore: EditMessageStore
let receiptManagerShim: EditManagerImpl.Shims.ReceiptManager
@@ -40,14 +39,12 @@ public class EditManagerImpl: EditManager {
public init(
attachmentContentValidator: AttachmentContentValidator,
attachmentStore: AttachmentStore,
dataStore: EditManagerImpl.Shims.DataStore,
editManagerAttachments: EditManagerAttachments,
editMessageStore: EditMessageStore,
receiptManagerShim: EditManagerImpl.Shims.ReceiptManager
) {
self.attachmentContentValidator = attachmentContentValidator
self.attachmentStore = attachmentStore
self.dataStore = dataStore
self.editManagerAttachments = editManagerAttachments
self.editMessageStore = editMessageStore
self.receiptManagerShim = receiptManagerShim
@@ -143,17 +140,16 @@ public class EditManagerImpl: EditManager {
// MARK: - Edit UI Validation
public func canShowEditMenu(interaction: TSInteraction, thread: TSThread) -> Bool {
return Self.validateCanShowEditMenu(interaction: interaction, thread: thread, dataStore: context.dataStore) == nil
return Self.validateCanShowEditMenu(interaction: interaction, thread: thread) == nil
}
private static func validateCanShowEditMenu(
interaction: TSInteraction,
thread: TSThread,
dataStore: EditManagerImpl.Shims.DataStore
) -> EditSendValidationError? {
guard let message = interaction as? TSOutgoingMessage else { return .messageTypeNotSupported }
if !Self.editMessageTypeSupported(message: message, dataStore: dataStore) {
if !Self.editMessageTypeSupported(message: message) {
return .messageTypeNotSupported
}
@@ -193,7 +189,7 @@ public class EditManagerImpl: EditManager {
let targetMessage = targetMessageWrapper.message
if let error = Self.validateCanShowEditMenu(interaction: targetMessage, thread: thread, dataStore: context.dataStore) {
if let error = Self.validateCanShowEditMenu(interaction: targetMessage, thread: thread) {
return error
}
@@ -238,11 +234,11 @@ public class EditManagerImpl: EditManager {
tx: tx
)
let outgoingEditMessage = context.dataStore.createOutgoingEditMessage(
let outgoingEditMessage = OutgoingEditMessage(
thread: thread,
targetMessageTimestamp: targetMessage.timestamp,
editMessage: editedMessage,
tx: tx
transaction: tx
)
return outgoingEditMessage
@@ -276,7 +272,7 @@ public class EditManagerImpl: EditManager {
edits: editsToApply,
tx: tx
)
context.dataStore.overwritingUpdate(latestRevisionMessage, tx: tx)
latestRevisionMessage.anyOverwritingUpdate(transaction: tx)
let latestRevisionRowId = latestRevisionMessage.sqliteRowId!
/// Create and insert a clone of the original message, preserving all
@@ -292,10 +288,9 @@ public class EditManagerImpl: EditManager {
)
let priorRevisionMessage = EditTarget.build(
priorRevisionMessageBuilder,
dataStore: context.dataStore,
tx: tx
)
context.dataStore.insert(priorRevisionMessage, tx: tx)
priorRevisionMessage.anyInsert(transaction: tx)
let priorRevisionRowId = priorRevisionMessage.sqliteRowId!
try context.editManagerAttachments.reconcileAttachments(
@@ -314,7 +309,6 @@ public class EditManagerImpl: EditManager {
// Update the newly inserted message with any data that needs to be
// copied from the original message
editTargetWrapper.updateMessageCopy(
dataStore: context.dataStore,
newMessageCopy: priorRevisionMessage,
tx: tx
)
@@ -356,7 +350,6 @@ public class EditManagerImpl: EditManager {
let editedMessage = EditTarget.build(
editedMessageBuilder,
dataStore: context.dataStore,
tx: tx
)
@@ -422,7 +415,7 @@ public class EditManagerImpl: EditManager {
}
}
if !Self.editMessageTypeSupported(message: targetMessage, dataStore: context.dataStore) {
if !Self.editMessageTypeSupported(message: targetMessage) {
throw OWSAssertionError("Edit of message type not supported")
}
@@ -446,7 +439,6 @@ public class EditManagerImpl: EditManager {
private static func editMessageTypeSupported(
message: TSMessage,
dataStore: EditManagerImpl.Shims.DataStore
) -> Bool {
// Skip remotely deleted
if message.wasRemotelyDeleted {
@@ -464,7 +456,7 @@ public class EditManagerImpl: EditManager {
}
// Skip contact shares
if dataStore.isMessageContactShare(message) {
if message.contactShare != nil {
return false
}

View File

@@ -8,104 +8,14 @@ import LibSignalClient
extension EditManagerImpl {
public enum Shims {
public typealias DataStore = _EditManagerImpl_DataStore
public typealias ReceiptManager = _EditManagerImpl_ReceiptManagerShim
}
public enum Wrappers {
public typealias DataStore = _EditManagerImpl_DataStoreWrapper
public typealias ReceiptManager = _EditManagerImpl_ReceiptManagerWrapper
}
}
// MARK: - EditManager.DataStore
public protocol _EditManagerImpl_DataStore {
func build(
_ builder: TSOutgoingMessageBuilder,
tx: DBReadTransaction
) -> TSOutgoingMessage
func createOutgoingEditMessage(
thread: TSThread,
targetMessageTimestamp: UInt64,
editMessage: TSOutgoingMessage,
tx: DBReadTransaction
) -> OutgoingEditMessage
func isMessageContactShare(_ message: TSMessage) -> Bool
func update(
_ message: TSOutgoingMessage,
withRecipientAddressStates: [SignalServiceAddress: TSOutgoingMessageRecipientState]?,
tx: DBWriteTransaction
)
func insert(
_ message: TSMessage,
tx: DBWriteTransaction
)
func overwritingUpdate(
_ message: TSMessage,
tx: DBWriteTransaction
)
}
public class _EditManagerImpl_DataStoreWrapper: EditManagerImpl.Shims.DataStore {
public func createOutgoingEditMessage(
thread: TSThread,
targetMessageTimestamp: UInt64,
editMessage: TSOutgoingMessage,
tx: DBReadTransaction
) -> OutgoingEditMessage {
return OutgoingEditMessage(
thread: thread,
targetMessageTimestamp: targetMessageTimestamp,
editMessage: editMessage,
transaction: tx
)
}
public func build(
_ builder: TSOutgoingMessageBuilder,
tx: DBReadTransaction
) -> TSOutgoingMessage {
return builder.build(transaction: tx)
}
public func isMessageContactShare(_ message: TSMessage) -> Bool {
return message.contactShare != nil
}
public func update(
_ message: TSOutgoingMessage,
withRecipientAddressStates recipientAddressStates: [SignalServiceAddress: TSOutgoingMessageRecipientState]?,
tx: DBWriteTransaction
) {
message.updateWithRecipientAddressStates(
recipientAddressStates,
tx: tx
)
}
public func insert(
_ message: TSMessage,
tx: DBWriteTransaction
) {
message.anyInsert(transaction: tx)
}
public func overwritingUpdate(
_ message: TSMessage,
tx: DBWriteTransaction
) {
message.anyOverwritingUpdate(transaction: tx)
}
}
// MARK: - OWSReceiptManager
public protocol _EditManagerImpl_ReceiptManagerShim {

View File

@@ -21,76 +21,12 @@ public enum EditMessageTarget {
}
}
public protocol EditMessageStore {
// MARK: - Reads
func editTarget(
timestamp: UInt64,
authorAci: Aci?,
tx: DBReadTransaction
) -> EditMessageTarget?
func findMessage(
fromEdit edit: TSMessage,
tx: DBReadTransaction
) -> TSMessage?
func numberOfEdits(
for message: TSMessage,
tx: DBReadTransaction
) -> Int
/// Fetches all past revisions for the given most-recent-revision message.
///
/// - Returns
/// An edit record and message instance (if one is found) for each past
/// revision, from newest to oldest.
func findEditHistory<MessageType: TSMessage>(
forMostRecentRevision message: MessageType,
tx: DBReadTransaction
) throws -> [(record: EditRecord, message: MessageType?)]
/// Fetches all EditRecords related to `message`.
///
/// The `message` may be the latest revision or a past revision.
///
/// The EditRecords are fetched "recursively", meaning that every EditRecord
/// that references a message ID which is referenced by any element of the
/// result will be returned. This is useful when deleting messages because
/// it allows us to maintain invariants required by FOREIGN KEY constraints.
///
/// For example, if the revision "graph" is well-formed, we'll return
/// EditRecords with distinct pastRevisionIds (e.g., 102, 103) which all
/// refer to the same latestRevisionId (e.g., 101), and we'll return this
/// exact same result regardless of whether `message` refers to a past
/// revision (e.g., 102) or the latest revision (e.g., 101).
///
/// If the revision "graph" isn't well-formed, we must fetch extra
/// EditRecords to ensure we delete all the EditRecords that reference the
/// messages that are about to be deleted.
func findEditRecords(
relatedTo message: TSMessage,
tx: DBReadTransaction
) throws -> [EditRecord]
// MARK: - Writes
func insert(
_ editRecord: EditRecord,
tx: DBWriteTransaction
) throws
func update(
_ editRecord: EditRecord,
tx: DBWriteTransaction
) throws
}
public class EditMessageStoreImpl: EditMessageStore {
public struct EditMessageStore {
public init() {}
// MARK: - Reads
public func editTarget(
timestamp: UInt64,
authorAci: Aci?,
@@ -190,6 +126,11 @@ public class EditMessageStoreImpl: EditMessageStore {
}
}
/// Fetches all past revisions for the given most-recent-revision message.
///
/// - Returns
/// An edit record and message instance (if one is found) for each past
/// revision, from newest to oldest.
public func findEditHistory<MessageType: TSMessage>(
forMostRecentRevision message: MessageType,
tx: DBReadTransaction
@@ -224,6 +165,24 @@ public class EditMessageStoreImpl: EditMessageStore {
}
}
/// Fetches all EditRecords related to `message`.
///
/// The `message` may be the latest revision or a past revision.
///
/// The EditRecords are fetched "recursively", meaning that every EditRecord
/// that references a message ID which is referenced by any element of the
/// result will be returned. This is useful when deleting messages because
/// it allows us to maintain invariants required by FOREIGN KEY constraints.
///
/// For example, if the revision "graph" is well-formed, we'll return
/// EditRecords with distinct pastRevisionIds (e.g., 102, 103) which all
/// refer to the same latestRevisionId (e.g., 101), and we'll return this
/// exact same result regardless of whether `message` refers to a past
/// revision (e.g., 102) or the latest revision (e.g., 101).
///
/// If the revision "graph" isn't well-formed, we must fetch extra
/// EditRecords to ensure we delete all the EditRecords that reference the
/// messages that are about to be deleted.
public func findEditRecords(
relatedTo message: TSMessage,
tx: DBReadTransaction
@@ -253,6 +212,8 @@ public class EditMessageStoreImpl: EditMessageStore {
return editRecords.removingDuplicates(uniquingElementsBy: { $0.id! })
}
// MARK: - Writes
public func insert(
_ editRecord: EditRecord,
tx: DBWriteTransaction

View File

@@ -32,12 +32,10 @@ public protocol EditMessageWrapper {
static func build(
_ builder: MessageBuilderType,
dataStore: EditManagerImpl.Shims.DataStore,
tx: DBReadTransaction
) -> MessageType
func updateMessageCopy(
dataStore: EditManagerImpl.Shims.DataStore,
newMessageCopy: MessageType,
tx: DBWriteTransaction
)
@@ -173,14 +171,12 @@ public struct IncomingEditMessageWrapper: EditMessageWrapper {
public static func build(
_ builder: TSIncomingMessageBuilder,
dataStore: EditManagerImpl.Shims.DataStore,
tx: DBReadTransaction
) -> TSIncomingMessage {
return builder.build()
}
public func updateMessageCopy(
dataStore: EditManagerImpl.Shims.DataStore,
newMessageCopy: TSIncomingMessage,
tx: DBWriteTransaction
) {}
@@ -266,22 +262,19 @@ public struct OutgoingEditMessageWrapper: EditMessageWrapper {
public static func build(
_ builder: TSOutgoingMessageBuilder,
dataStore: EditManagerImpl.Shims.DataStore,
tx: DBReadTransaction
) -> TSOutgoingMessage {
return dataStore.build(builder, tx: tx)
return builder.build(transaction: tx)
}
public func updateMessageCopy(
dataStore: EditManagerImpl.Shims.DataStore,
newMessageCopy: TSOutgoingMessage,
tx: DBWriteTransaction
) {
// Need to copy over the recipient address from the old message
// This is needed when procesing sync messages.
dataStore.update(
newMessageCopy,
withRecipientAddressStates: message.recipientAddressStates,
newMessageCopy.updateWithRecipientAddressStates(
message.recipientAddressStates,
tx: tx
)
}

View File

@@ -49,23 +49,22 @@ class EditManagerTests: SSKBaseTest {
}
let editMessage = createEditDataMessage { $0.setBody("FOO") }
let dataStoreMock = EditManagerDataStoreMock(targetMessage: targetMessage)
let editMessageStoreMock = EditMessageStoreMock()
let editManager = EditManagerImpl(context:
.init(
attachmentContentValidator: AttachmentContentValidatorMock(),
attachmentStore: AttachmentStoreMock(),
dataStore: dataStoreMock,
editManagerAttachments: MockEditManagerAttachments(),
editMessageStore: editMessageStoreMock,
editMessageStore: EditMessageStore(),
receiptManagerShim: ReceiptManagerMock()
)
)
var newMessage: TSMessage!
try db.write { tx in
_ = try editManager.processIncomingEditMessage(
targetMessage.anyInsert(transaction: tx)
newMessage = try editManager.processIncomingEditMessage(
editMessage,
serverTimestamp: 1,
serverTimestamp: 2,
serverGuid: UUID().uuidString,
serverDeliveryTimestamp: 1234,
thread: thread,
@@ -76,15 +75,20 @@ class EditManagerTests: SSKBaseTest {
)),
tx: tx
)
}
try db.read { tx in
// Inserted edit
compare(
dataStoreMock.editMessageCopy,
newMessage,
targetMessage,
propertyList: editPropertyList
)
// original
let dbOriginal = try InteractionFinder.fetchInteractions(timestamp: targetMessage.timestamp, transaction: tx).first!
compare(
dataStoreMock.oldMessageCopy,
dbOriginal,
targetMessage,
propertyList: originalPropetyList
)
@@ -97,15 +101,12 @@ class EditManagerTests: SSKBaseTest {
builder.isViewOnceMessage = true
}
let editMessage = createEditDataMessage { _ in }
let dataStoreMock = EditManagerDataStoreMock(targetMessage: targetMessage)
let editMessageStoreMock = EditMessageStoreMock()
let editManager = EditManagerImpl(context:
.init(
attachmentContentValidator: AttachmentContentValidatorMock(),
attachmentStore: AttachmentStoreMock(),
dataStore: dataStoreMock,
editManagerAttachments: MockEditManagerAttachments(),
editMessageStore: editMessageStoreMock,
editMessageStore: EditMessageStore(),
receiptManagerShim: ReceiptManagerMock()
)
)
@@ -139,24 +140,20 @@ class EditManagerTests: SSKBaseTest {
func testContactShareEditMessageFails() {
let targetMessage = createIncomingMessage(with: thread) { builder in
builder.authorAci = authorAci
builder.contactShare = OWSContact(name: .init(givenName: "Test"))
}
let editMessage = createEditDataMessage { _ in }
let dataStoreMock = EditManagerDataStoreMock(targetMessage: targetMessage)
let editMessageStoreMock = EditMessageStoreMock()
let editManager = EditManagerImpl(context:
.init(
attachmentContentValidator: AttachmentContentValidatorMock(),
attachmentStore: AttachmentStoreMock(),
dataStore: dataStoreMock,
editManagerAttachments: MockEditManagerAttachments(),
editMessageStore: editMessageStoreMock,
editMessageStore: EditMessageStore(),
receiptManagerShim: ReceiptManagerMock()
)
)
dataStoreMock.isContactShare = true
db.write { tx in
do {
OWSAssertionError.test_skipAssertions = true
@@ -188,16 +185,12 @@ class EditManagerTests: SSKBaseTest {
builder.authorAci = authorAci
}
let editMessage = createEditDataMessage { _ in }
let dataStoreMock = EditManagerDataStoreMock(targetMessage: targetMessage)
let editMessageStoreMock = EditMessageStoreMock()
let editManager = EditManagerImpl(context:
.init(
attachmentContentValidator: AttachmentContentValidatorMock(),
attachmentStore: AttachmentStoreMock(),
dataStore: dataStoreMock,
editManagerAttachments: MockEditManagerAttachments(),
editMessageStore: editMessageStoreMock,
editMessageStore: EditMessageStore(),
receiptManagerShim: ReceiptManagerMock()
)
)
@@ -237,16 +230,12 @@ class EditManagerTests: SSKBaseTest {
builder.serverTimestamp = bigInt
}
let editMessage = createEditDataMessage { _ in }
let dataStoreMock = EditManagerDataStoreMock(targetMessage: targetMessage)
let editMessageStoreMock = EditMessageStoreMock()
let editManager = EditManagerImpl(context:
.init(
attachmentContentValidator: AttachmentContentValidatorMock(),
attachmentStore: AttachmentStoreMock(),
dataStore: dataStoreMock,
editManagerAttachments: MockEditManagerAttachments(),
editMessageStore: editMessageStoreMock,
editMessageStore: EditMessageStore(),
receiptManagerShim: ReceiptManagerMock()
)
)
@@ -363,107 +352,11 @@ class EditManagerTests: SSKBaseTest {
)
messageBuilder.serverTimestamp = 1
customizeBlock(messageBuilder)
let targetMessage = messageBuilder.build()
targetMessage.replaceRowId(1, uniqueId: "1")
return targetMessage
return messageBuilder.build()
}
// MARK: - Test Mocks
private class EditManagerDataStoreMock: EditManagerImpl.Shims.DataStore {
func createOutgoingEditMessage(
thread: TSThread,
targetMessageTimestamp: UInt64,
editMessage: TSOutgoingMessage,
tx: DBReadTransaction
) -> OutgoingEditMessage {
return try! OutgoingEditMessage(dictionary: [:])
}
func build(
_ builder: TSOutgoingMessageBuilder,
tx: DBReadTransaction
) -> TSOutgoingMessage {
return builder.build(transaction: tx)
}
var isContactShare = false
func isMessageContactShare(_ message: TSMessage) -> Bool {
return isContactShare
}
func update(
_ message: TSOutgoingMessage,
withRecipientAddressStates: [SignalServiceAddress: TSOutgoingMessageRecipientState]?,
tx: DBWriteTransaction
) {}
let targetMessage: TSMessage?
var editMessageCopy: TSMessage?
var oldMessageCopy: TSMessage?
init(targetMessage: TSMessage?) {
self.targetMessage = targetMessage
}
func insert(_ message: TSMessage, tx: DBWriteTransaction) {
oldMessageCopy = message
message.replaceRowId(2, uniqueId: message.uniqueId)
}
func overwritingUpdate(_ message: TSMessage, tx: DBWriteTransaction) {
editMessageCopy = message
}
}
private class EditMessageStoreMock: EditMessageStore {
func editTarget(
timestamp: UInt64,
authorAci: Aci?,
tx: DBReadTransaction
) -> EditMessageTarget? {
return nil
}
func findMessage(
fromEdit edit: TSMessage,
tx: DBReadTransaction
) -> TSMessage? {
nil
}
func numberOfEdits(
for message: TSMessage,
tx: DBReadTransaction
) -> Int {
return 1
}
func findEditHistory<MessageType: TSMessage>(
forMostRecentRevision message: MessageType,
tx: DBReadTransaction
) throws -> [(record: EditRecord, message: MessageType?)] {
return []
}
func findEditRecords(
relatedTo message: TSMessage,
tx: DBReadTransaction
) throws -> [EditRecord] {
return []
}
var editRecord: EditRecord?
func insert(_ editRecord: EditRecord, tx: DBWriteTransaction) {
self.editRecord = editRecord
}
func update(_ editRecord: EditRecord, tx: DBWriteTransaction) throws {}
}
private class ReceiptManagerMock: EditManagerImpl.Shims.ReceiptManager {
func messageWasRead(
_ message: TSIncomingMessage,
@@ -489,11 +382,11 @@ class EditManagerTests: SSKBaseTest {
"isOutgoing": .unchanged,
"editState": .changed,
"body": .changed,
"bodyRanges": .changed,
"bodyRanges": .ignore, // MessageBodyRanges are not equatable, so ignore
"expiresInSeconds": .unchanged,
"expireTimerVersion": .unchanged,
"expireStartedAt": .unchanged,
"schemaVersion": .unchanged,
"schemaVersion": .ignore,
"quotedMessage": .unchanged,
"contactShare": .unchanged,
"linkPreview": .unchanged,
@@ -527,11 +420,11 @@ class EditManagerTests: SSKBaseTest {
"isOutgoing": .unchanged,
"editState": .changed,
"body": .unchanged,
"bodyRanges": .unchanged,
"bodyRanges": .ignore,
"expiresInSeconds": .unchanged,
"expireTimerVersion": .unchanged,
"expireStartedAt": .unchanged,
"schemaVersion": .unchanged,
"schemaVersion": .ignore,
"quotedMessage": .unchanged,
"contactShare": .unchanged,
"linkPreview": .unchanged,