diff --git a/Tests/Integration/ClientIntegrationTests.swift b/Tests/Integration/ClientIntegrationTests.swift index 3dc64cc7..768822d8 100644 --- a/Tests/Integration/ClientIntegrationTests.swift +++ b/Tests/Integration/ClientIntegrationTests.swift @@ -745,4 +745,37 @@ final class ClientIntegrationTests: XCTestCase { try await c1.deactivate() try await c2.deactivate() } + + func test_duplicated_local_changes_not_sent_to_server() async throws { + try await withTwoClientsAndDocuments(self.description, detachDocuments: false) { c1, d1, c2, d2 in + try await d1.update { root, _ in + root.t = JSONTree(initialRoot: + JSONTreeElementNode(type: "doc", + children: [ + JSONTreeElementNode(type: "p", children: [JSONTreeTextNode(value: "12")]), + JSONTreeElementNode(type: "p", children: [JSONTreeTextNode(value: "34")]) + ]) + ) + } + + try await c1.sync() + try await c1.sync() + try await c1.sync() + try await c1.detach(d1) + + try await Task.sleep(nanoseconds: 3_000_000_000) + + try await c2.sync() + + let d1XML = await(d1.getRoot().t as? JSONTree)?.toXML() + let d2XML = await(d2.getRoot().t as? JSONTree)?.toXML() + XCTAssertEqual(d1XML, /* html */ "

12

34

") + XCTAssertEqual(d2XML, /* html */ "

12

34

") + + try await c2.detach(d2) + + try await c1.deactivate() + try await c2.deactivate() + } + } } diff --git a/Tests/Integration/IntegrationHelper.swift b/Tests/Integration/IntegrationHelper.swift index d87fdd01..6d74a069 100644 --- a/Tests/Integration/IntegrationHelper.swift +++ b/Tests/Integration/IntegrationHelper.swift @@ -17,7 +17,7 @@ import XCTest @testable import Yorkie -func withTwoClientsAndDocuments(_ title: String, _ callback: (Client, Document, Client, Document) async throws -> Void) async throws { +func withTwoClientsAndDocuments(_ title: String, detachDocuments: Bool = true, _ callback: (Client, Document, Client, Document) async throws -> Void) async throws { let rpcAddress = "http://localhost:8080" let docKey = "\(Date().description)-\(title)".toDocKey @@ -36,11 +36,13 @@ func withTwoClientsAndDocuments(_ title: String, _ callback: (Client, Document, try await callback(c1, d1, c2, d2) - try await c1.detach(d1) - try await c2.detach(d2) + if detachDocuments { + try await c1.detach(d1) + try await c2.detach(d2) - try await c1.deactivate() - try await c2.deactivate() + try await c1.deactivate() + try await c2.deactivate() + } } protocol OperationInfoForDebug {}