co-maps/iphone/Maps/Tests/Core/iCloudTests/SynchronizationStateManagerTests.swift
2025-11-22 13:58:55 +01:00

573 lines
27 KiB
Swift

import XCTest
@testable import CoMaps__Debug_
final class SynchronizationtateManagerTests: XCTestCase {
var syncStateManager: SynchronizationStateResolver!
var outgoingEvents: [OutgoingSynchronizationEvent] = []
override func setUp() {
super.setUp()
syncStateManager = iCloudSynchronizationStateResolver(isInitialSynchronization: false)
}
override func tearDown() {
syncStateManager = nil
outgoingEvents.removeAll()
super.tearDown()
}
// MARK: - Test didFinishGathering without errors and on initial synchronization
func testInitialSynchronization() {
syncStateManager = iCloudSynchronizationStateResolver(isInitialSynchronization: true)
let localItem1 = LocalMetadataItem.stub(fileName: "file1", lastModificationDate: TimeInterval(1))
let localItem2 = LocalMetadataItem.stub(fileName: "file2", lastModificationDate: TimeInterval(3)) // Local only item
let cloudItem1 = CloudMetadataItem.stub(fileName: "file1", lastModificationDate: TimeInterval(2)) // Conflicting item
let cloudItem3 = CloudMetadataItem.stub(fileName: "file3", lastModificationDate: TimeInterval(4)) // Cloud only item
let localItems: LocalContents = [localItem1, localItem2]
let cloudItems: CloudContents = [cloudItem1, cloudItem3]
outgoingEvents.append(contentsOf: syncStateManager.resolveEvent(.didFinishGatheringLocalContents(localItems)))
outgoingEvents.append(contentsOf: syncStateManager.resolveEvent(.didFinishGatheringCloudContents(cloudItems)))
XCTAssertTrue(outgoingEvents.contains { event in
if case .resolveInitialSynchronizationConflict(let item) = event, item == localItem1 {
return true
}
return false
}, "Expected to resolve initial synchronization conflict for localItem1")
XCTAssertTrue(outgoingEvents.contains { event in
if case .createLocalItem(let item) = event, item == cloudItem3 {
return true
}
return false
}, "Expected to create local item for cloudItem3")
XCTAssertTrue(outgoingEvents.contains { event in
if case .createCloudItem(let item) = event, item == localItem2 {
return true
}
return false
}, "Expected to create cloud item for localItem2")
XCTAssertTrue(outgoingEvents.contains { event in
if case .didFinishInitialSynchronization = event {
return true
}
return false
}, "Expected to finish initial synchronization")
}
func testInitialSynchronizationWithNewerCloudItem() {
syncStateManager = iCloudSynchronizationStateResolver(isInitialSynchronization: true)
let localItem = LocalMetadataItem.stub(fileName: "file", lastModificationDate: TimeInterval(1))
let cloudItem = CloudMetadataItem.stub(fileName: "file", lastModificationDate: TimeInterval(2))
outgoingEvents.append(contentsOf: syncStateManager.resolveEvent(.didFinishGatheringLocalContents([localItem])))
outgoingEvents.append(contentsOf: syncStateManager.resolveEvent(.didFinishGatheringCloudContents([cloudItem])))
XCTAssertTrue(outgoingEvents.contains { if case .resolveInitialSynchronizationConflict(_) = $0 { return true } else { return false } }, "Expected conflict resolution for a newer cloud item")
}
func testInitialSynchronizationWithNewerLocalItem() {
syncStateManager = iCloudSynchronizationStateResolver(isInitialSynchronization: true)
let localItem = LocalMetadataItem.stub(fileName: "file", lastModificationDate: TimeInterval(2))
let cloudItem = CloudMetadataItem.stub(fileName: "file", lastModificationDate: TimeInterval(1))
outgoingEvents.append(contentsOf: syncStateManager.resolveEvent(.didFinishGatheringLocalContents([localItem])))
outgoingEvents.append(contentsOf: syncStateManager.resolveEvent(.didFinishGatheringCloudContents([cloudItem])))
XCTAssertTrue(outgoingEvents.contains { if case .resolveInitialSynchronizationConflict(_) = $0 { return true } else { return false } }, "Expected conflict resolution for a newer local item")
}
func testInitialSynchronizationWithNonConflictingItems() {
syncStateManager = iCloudSynchronizationStateResolver(isInitialSynchronization: true)
let localItem = LocalMetadataItem.stub(fileName: "localFile", lastModificationDate: TimeInterval(1))
let cloudItem = CloudMetadataItem.stub(fileName: "cloudFile", lastModificationDate: TimeInterval(2))
outgoingEvents.append(contentsOf: syncStateManager.resolveEvent(.didFinishGatheringLocalContents([localItem])))
outgoingEvents.append(contentsOf: syncStateManager.resolveEvent(.didFinishGatheringCloudContents([cloudItem])))
XCTAssertTrue(outgoingEvents.contains { if case .createLocalItem(_) = $0 { return true } else { return false } }, "Expected creation of local item for cloudFile")
XCTAssertTrue(outgoingEvents.contains { if case .createCloudItem(_) = $0 { return true } else { return false } }, "Expected creation of cloud item for localFile")
}
func testInitialSynchronizationWhenCloudFilesAreNotDownloadedTheDownloadingShouldStart () {
syncStateManager = iCloudSynchronizationStateResolver(isInitialSynchronization: true)
let localItem1 = LocalMetadataItem.stub(fileName: "file1", lastModificationDate: TimeInterval(1))
let cloudItem1 = CloudMetadataItem.stub(fileName: "file1", lastModificationDate: TimeInterval(2))
let cloudItem2 = CloudMetadataItem.stub(fileName: "file2", lastModificationDate: TimeInterval(3), isDownloaded: false, percentDownloaded: 0.0)
let cloudItem3 = CloudMetadataItem.stub(fileName: "file3", lastModificationDate: TimeInterval(4))
let localItems = LocalContents([localItem1])
let cloudItems = CloudContents([cloudItem1, cloudItem2, cloudItem3])
outgoingEvents.append(contentsOf: syncStateManager.resolveEvent(.didFinishGatheringLocalContents(localItems)))
outgoingEvents.append(contentsOf: syncStateManager.resolveEvent(.didFinishGatheringCloudContents(cloudItems)))
XCTAssertEqual(outgoingEvents.count, 5)
outgoingEvents.forEach { event in
switch event {
case .resolveInitialSynchronizationConflict(let item):
// copy local file with a new name and replace the original with the cloud file
XCTAssertEqual(item, localItem1)
case .updateLocalItem(let item):
XCTAssertEqual(item, cloudItem1)
case .startDownloading(let item):
XCTAssertEqual(item, cloudItem2)
case .createLocalItem(let item):
XCTAssertEqual(item, cloudItem3)
case .didFinishInitialSynchronization:
XCTAssertTrue(event == outgoingEvents.last)
default:
XCTFail()
}
}
// update the cloud items with the new downloaded status
let cloudItem2Downloaded = CloudMetadataItem.stub(fileName: "file2", lastModificationDate: TimeInterval(3))
let newCloudItems = [cloudItem1, cloudItem2Downloaded, cloudItem3]
let cloudUpdate = CloudContentsUpdate(added: [], updated: [cloudItem2Downloaded], removed: [])
outgoingEvents = syncStateManager.resolveEvent(.didUpdateCloudContents(contents: newCloudItems, update: cloudUpdate))
XCTAssertEqual(outgoingEvents.count, 1)
outgoingEvents.forEach { event in
switch event {
case .createLocalItem(let item):
XCTAssertEqual(item, cloudItem2Downloaded)
default:
XCTFail()
}
}
}
// MARK: - Test didFinishGathering without errors and after initial synchronization
func testDidFinishGatheringWhenCloudAndLocalIsEmpty() {
let localItems: LocalContents = []
let cloudItems: CloudContents = []
outgoingEvents = syncStateManager.resolveEvent(.didFinishGatheringCloudContents(cloudItems))
XCTAssertEqual(outgoingEvents.count, 0)
outgoingEvents = syncStateManager.resolveEvent(.didFinishGatheringLocalContents(localItems))
XCTAssertEqual(outgoingEvents.count, 0)
}
func testDidFinishGatheringWhenOnlyCloudIsEmpty() {
let localItem1 = LocalMetadataItem.stub(fileName: "file1", lastModificationDate: TimeInterval(1))
let localItem2 = LocalMetadataItem.stub(fileName: "file2", lastModificationDate: TimeInterval(2))
let localItem3 = LocalMetadataItem.stub(fileName: "file3", lastModificationDate: TimeInterval(3))
let localItems: LocalContents = LocalContents([localItem1, localItem2, localItem3])
let cloudItems: CloudContents = []
outgoingEvents = syncStateManager.resolveEvent(.didFinishGatheringCloudContents(cloudItems))
XCTAssertEqual(outgoingEvents.count, 0)
outgoingEvents = syncStateManager.resolveEvent(.didFinishGatheringLocalContents(localItems))
outgoingEvents.forEach { event in
switch event {
case .createCloudItem(let item):
XCTAssertTrue(localItems.containsByName(item))
default:
XCTFail()
}
}
}
func testDidFinishGatheringWhenOnlyLocalIsEmpty() {
let cloudItem1 = CloudMetadataItem.stub(fileName: "file1", lastModificationDate: TimeInterval(1))
let cloudItem2 = CloudMetadataItem.stub(fileName: "file2", lastModificationDate: TimeInterval(2))
let cloudItem3 = CloudMetadataItem.stub(fileName: "file3", lastModificationDate: TimeInterval(3))
let localItems = LocalContents()
let cloudItems = CloudContents([cloudItem1, cloudItem2, cloudItem3])
outgoingEvents = syncStateManager.resolveEvent(.didFinishGatheringCloudContents(cloudItems))
XCTAssertEqual(outgoingEvents.count, 0)
outgoingEvents = syncStateManager.resolveEvent(.didFinishGatheringLocalContents(localItems))
outgoingEvents.forEach { event in
switch event {
case .createLocalItem(let item):
XCTAssertTrue(cloudItems.containsByName(item))
default:
XCTFail()
}
}
}
func testDidFinishGatheringWhenTreCloudIsEmpty() {
let localItem1 = LocalMetadataItem.stub(fileName: "file1", lastModificationDate: TimeInterval(1))
let localItem2 = LocalMetadataItem.stub(fileName: "file2", lastModificationDate: TimeInterval(2))
let localItem3 = LocalMetadataItem.stub(fileName: "file3", lastModificationDate: TimeInterval(3))
let localItems = [localItem1, localItem2, localItem3]
outgoingEvents = syncStateManager.resolveEvent(.didFinishGatheringCloudContents([]))
outgoingEvents = syncStateManager.resolveEvent(.didFinishGatheringLocalContents(localItems))
XCTAssertEqual(outgoingEvents.count, 3)
outgoingEvents.forEach { event in
switch event {
case .createCloudItem(let item):
XCTAssertTrue(localItems.containsByName(item))
default:
XCTFail()
}
}
}
func testDidFinishGatheringWhenLocalIsEmpty() {
let cloudItem1 = CloudMetadataItem.stub(fileName: "file1", lastModificationDate: TimeInterval(1))
let cloudItem2 = CloudMetadataItem.stub(fileName: "file2", lastModificationDate: TimeInterval(2))
let cloudItem3 = CloudMetadataItem.stub(fileName: "file3", lastModificationDate: TimeInterval(3))
let localItems = LocalContents()
let cloudItems = CloudContents([cloudItem1, cloudItem2, cloudItem3])
outgoingEvents = syncStateManager.resolveEvent(.didFinishGatheringCloudContents(cloudItems))
XCTAssertEqual(outgoingEvents.count, 0)
outgoingEvents = syncStateManager.resolveEvent(.didFinishGatheringLocalContents(localItems))
XCTAssertEqual(outgoingEvents.count, 3)
outgoingEvents.forEach { event in
switch event {
case .createLocalItem(let item):
XCTAssertTrue(cloudItems.containsByName(item))
default:
XCTFail()
}
}
}
func testDidFinishGatheringWhenLocalAndCloudAreNotEmptyAndAllFilesEqual() {
let localItem1 = LocalMetadataItem.stub(fileName: "file1", lastModificationDate: TimeInterval(1))
let localItem2 = LocalMetadataItem.stub(fileName: "file2", lastModificationDate: TimeInterval(2))
let localItem3 = LocalMetadataItem.stub(fileName: "file3", lastModificationDate: TimeInterval(3))
let cloudItem1 = CloudMetadataItem.stub(fileName: "file1", lastModificationDate: TimeInterval(1))
let cloudItem2 = CloudMetadataItem.stub(fileName: "file2", lastModificationDate: TimeInterval(2))
let cloudItem3 = CloudMetadataItem.stub(fileName: "file3", lastModificationDate: TimeInterval(3))
let localItems = LocalContents([localItem1, localItem2, localItem3])
let cloudItems = CloudContents([cloudItem1, cloudItem2, cloudItem3])
outgoingEvents = syncStateManager.resolveEvent(.didFinishGatheringLocalContents(localItems))
XCTAssertEqual(outgoingEvents.count, 0)
outgoingEvents = syncStateManager.resolveEvent(.didFinishGatheringCloudContents(cloudItems))
XCTAssertEqual(outgoingEvents.count, 0)
}
func testDidFinishGatheringWhenLocalAndCloudAreNotEmptyAndSomeLocalItemsAreNewer() {
let localItem1 = LocalMetadataItem.stub(fileName: "file1", lastModificationDate: TimeInterval(1))
let localItem2 = LocalMetadataItem.stub(fileName: "file2", lastModificationDate: TimeInterval(3))
let localItem3 = LocalMetadataItem.stub(fileName: "file3", lastModificationDate: TimeInterval(4))
let cloudItem1 = CloudMetadataItem.stub(fileName: "file1", lastModificationDate: TimeInterval(1))
let cloudItem2 = CloudMetadataItem.stub(fileName: "file2", lastModificationDate: TimeInterval(2))
let cloudItem3 = CloudMetadataItem.stub(fileName: "file3", lastModificationDate: TimeInterval(3))
let localItems = LocalContents([localItem1, localItem2, localItem3])
let cloudItems = CloudContents([cloudItem1, cloudItem2, cloudItem3])
outgoingEvents = syncStateManager.resolveEvent(.didFinishGatheringLocalContents(localItems))
XCTAssertEqual(outgoingEvents.count, 0)
outgoingEvents = syncStateManager.resolveEvent(.didFinishGatheringCloudContents(cloudItems))
XCTAssertEqual(outgoingEvents.count, 2)
outgoingEvents.forEach { event in
switch event {
case .updateCloudItem(let item):
XCTAssertTrue([localItem2, localItem3].containsByName(item))
default:
XCTFail()
}
}
}
func testDidFinishGatheringWhenLocalAndCloudAreNotEmptyAndSomeCloudItemsAreNewer() {
let localItem1 = LocalMetadataItem.stub(fileName: "file1", lastModificationDate: TimeInterval(1))
let localItem2 = LocalMetadataItem.stub(fileName: "file2", lastModificationDate: TimeInterval(2))
let localItem3 = LocalMetadataItem.stub(fileName: "file3", lastModificationDate: TimeInterval(3))
let cloudItem1 = CloudMetadataItem.stub(fileName: "file1", lastModificationDate: TimeInterval(4))
let cloudItem2 = CloudMetadataItem.stub(fileName: "file2", lastModificationDate: TimeInterval(2))
let cloudItem3 = CloudMetadataItem.stub(fileName: "file3", lastModificationDate: TimeInterval(7))
let localItems = LocalContents([localItem1, localItem2, localItem3])
let cloudItems = CloudContents([cloudItem1, cloudItem2, cloudItem3])
outgoingEvents = syncStateManager.resolveEvent(.didFinishGatheringLocalContents(localItems))
XCTAssertEqual(outgoingEvents.count, 0)
outgoingEvents = syncStateManager.resolveEvent(.didFinishGatheringCloudContents(cloudItems))
XCTAssertEqual(outgoingEvents.count, 2)
outgoingEvents.forEach { event in
switch event {
case .updateLocalItem(let item):
XCTAssertTrue([cloudItem1, cloudItem3].containsByName(item))
default:
XCTFail()
}
}
}
func testDidFinishGatheringWhenCloudFileNewerThanLocal() {
let localItem = LocalMetadataItem.stub(fileName: "file3", lastModificationDate: TimeInterval(3))
let cloudItem = CloudMetadataItem.stub(fileName: "file3", lastModificationDate: TimeInterval(8))
let localItems = LocalContents([localItem])
let cloudItems = CloudContents([cloudItem])
outgoingEvents = syncStateManager.resolveEvent(.didFinishGatheringLocalContents(localItems))
XCTAssertEqual(outgoingEvents.count, 0)
outgoingEvents = syncStateManager.resolveEvent(.didFinishGatheringCloudContents(cloudItems))
XCTAssertEqual(outgoingEvents.count, 1)
outgoingEvents.forEach { event in
switch event {
case .updateLocalItem(let item):
XCTAssertEqual(item, cloudItem)
default:
XCTFail()
}
}
}
func testDidFinishGatheringWhenCloudHaveSameFileBothInTrashedAndNotAndTrashedBotLocalIsNewer() {
let localItem3 = LocalMetadataItem.stub(fileName: "file3", lastModificationDate: TimeInterval(9))
let cloudItem3 = CloudMetadataItem.stub(fileName: "file3", lastModificationDate: TimeInterval(2))
let cloudItem3Trashed = CloudMetadataItem.stub(fileName: "file3", lastModificationDate: TimeInterval(6))
let localItems = LocalContents([localItem3])
let cloudItems = CloudContents([cloudItem3, cloudItem3Trashed])
outgoingEvents = syncStateManager.resolveEvent(.didFinishGatheringLocalContents(localItems))
XCTAssertEqual(outgoingEvents.count, 0)
outgoingEvents = syncStateManager.resolveEvent(.didFinishGatheringCloudContents(cloudItems))
XCTAssertEqual(outgoingEvents.count, 1)
outgoingEvents.forEach { event in
switch event {
case .updateCloudItem(let item):
XCTAssertEqual(item, localItem3)
default:
XCTFail()
}
}
}
// MARK: - Test didUpdateLocalContents
func testDidUpdateLocalContentsWhenContentWasNotChanged() {
let localItem1 = LocalMetadataItem.stub(fileName: "file1", lastModificationDate: TimeInterval(1))
let localItem2 = LocalMetadataItem.stub(fileName: "file2", lastModificationDate: TimeInterval(2))
let localItem3 = LocalMetadataItem.stub(fileName: "file3", lastModificationDate: TimeInterval(3))
let localItems = LocalContents([localItem1, localItem2, localItem3])
let cloudItems = CloudContents([])
outgoingEvents = syncStateManager.resolveEvent(.didFinishGatheringLocalContents(localItems))
outgoingEvents = syncStateManager.resolveEvent(.didFinishGatheringCloudContents(cloudItems))
XCTAssertEqual(outgoingEvents.count, 3)
let newLocalItems = LocalContents([localItem1, localItem2, localItem3])
let update = LocalContentsUpdate(added: [], updated: [], removed: [])
outgoingEvents = syncStateManager.resolveEvent(.didUpdateLocalContents(contents: newLocalItems, update: update))
XCTAssertEqual(outgoingEvents.count, 0)
}
func testDidUpdateLocalContentsWhenNewLocalItemWasAdded() {
let localItem1 = LocalMetadataItem.stub(fileName: "file1", lastModificationDate: TimeInterval(1))
let localItem2 = LocalMetadataItem.stub(fileName: "file2", lastModificationDate: TimeInterval(2))
let localItem3 = LocalMetadataItem.stub(fileName: "file3", lastModificationDate: TimeInterval(3))
let cloudItem1 = CloudMetadataItem.stub(fileName: "file1", lastModificationDate: TimeInterval(1))
let cloudItem2 = CloudMetadataItem.stub(fileName: "file2", lastModificationDate: TimeInterval(2))
let cloudItem3 = CloudMetadataItem.stub(fileName: "file3", lastModificationDate: TimeInterval(3))
let localItems = LocalContents([localItem1, localItem2, localItem3])
let cloudItems = CloudContents([cloudItem1, cloudItem2, cloudItem3])
outgoingEvents = syncStateManager.resolveEvent(.didFinishGatheringLocalContents(localItems))
outgoingEvents = syncStateManager.resolveEvent(.didFinishGatheringCloudContents(cloudItems))
XCTAssertEqual(outgoingEvents.count, 0)
let localItem4 = LocalMetadataItem.stub(fileName: "file4", lastModificationDate: TimeInterval(4))
let newLocalItems = LocalContents([localItem1, localItem2, localItem3])
let update = LocalContentsUpdate(added: [localItem4], updated: [], removed: [])
outgoingEvents = syncStateManager.resolveEvent(.didUpdateLocalContents(contents: newLocalItems, update: update))
XCTAssertEqual(outgoingEvents.count, 1)
outgoingEvents.forEach { event in
switch event {
case .createCloudItem(let item):
XCTAssertEqual(item, localItem4)
default:
XCTFail()
}
}
}
func testDidUpdateLocalContentsWhenLocalItemWasUpdated() {
let localItem1 = LocalMetadataItem.stub(fileName: "file1", lastModificationDate: TimeInterval(1))
let localItem2 = LocalMetadataItem.stub(fileName: "file2", lastModificationDate: TimeInterval(2))
let localItem3 = LocalMetadataItem.stub(fileName: "file3", lastModificationDate: TimeInterval(3))
let cloudItem1 = CloudMetadataItem.stub(fileName: "file1", lastModificationDate: TimeInterval(1))
let cloudItem2 = CloudMetadataItem.stub(fileName: "file2", lastModificationDate: TimeInterval(2))
let cloudItem3 = CloudMetadataItem.stub(fileName: "file3", lastModificationDate: TimeInterval(3))
let localItems = LocalContents([localItem1, localItem2, localItem3])
let cloudItems = CloudContents([cloudItem1, cloudItem2, cloudItem3])
outgoingEvents = syncStateManager.resolveEvent(.didFinishGatheringLocalContents(localItems))
outgoingEvents = syncStateManager.resolveEvent(.didFinishGatheringCloudContents(cloudItems))
XCTAssertEqual(outgoingEvents.count, 0)
let localItem2Updated = LocalMetadataItem.stub(fileName: "file2", lastModificationDate: TimeInterval(3))
let localItem3Updated = LocalMetadataItem.stub(fileName: "file3", lastModificationDate: TimeInterval(4))
let newLocalItems = LocalContents([localItem1, localItem2Updated, localItem3Updated])
let update = LocalContentsUpdate(added: [], updated: [localItem2Updated, localItem3Updated], removed: [])
outgoingEvents = syncStateManager.resolveEvent(.didUpdateLocalContents(contents: newLocalItems, update: update))
XCTAssertEqual(outgoingEvents.count, 2)
outgoingEvents.forEach { event in
switch event {
case .updateCloudItem(let item):
XCTAssertTrue([localItem2Updated, localItem3Updated].containsByName(item))
default:
XCTFail()
}
}
}
func testDidUpdateLocalContentsWhenLocalItemWasRemoved() {
let localItem1 = LocalMetadataItem.stub(fileName: "file1", lastModificationDate: TimeInterval(1))
let localItem2 = LocalMetadataItem.stub(fileName: "file2", lastModificationDate: TimeInterval(2))
let localItem3 = LocalMetadataItem.stub(fileName: "file3", lastModificationDate: TimeInterval(3))
let cloudItem1 = CloudMetadataItem.stub(fileName: "file1", lastModificationDate: TimeInterval(1))
let cloudItem2 = CloudMetadataItem.stub(fileName: "file2", lastModificationDate: TimeInterval(2))
let cloudItem3 = CloudMetadataItem.stub(fileName: "file3", lastModificationDate: TimeInterval(3))
let localItems = LocalContents([localItem1, localItem2, localItem3])
let cloudItems = CloudContents([cloudItem1, cloudItem2, cloudItem3])
outgoingEvents = syncStateManager.resolveEvent(.didFinishGatheringLocalContents(localItems))
outgoingEvents = syncStateManager.resolveEvent(.didFinishGatheringCloudContents(cloudItems))
XCTAssertEqual(outgoingEvents.count, 0)
let newLocalItems = LocalContents([localItem1, localItem2])
let update = LocalContentsUpdate(added: [], updated: [], removed: [localItem3])
outgoingEvents = syncStateManager.resolveEvent(.didUpdateLocalContents(contents: newLocalItems, update: update))
XCTAssertEqual(outgoingEvents.count, 1)
outgoingEvents.forEach { event in
switch event {
case .removeCloudItem(let item):
XCTAssertEqual(item, cloudItem3)
default:
XCTFail()
}
}
}
// TODO: Test didUpdateCloudContents
func testDidUpdateCloudContentsWhenContentWasNotChanged() {
let localItem1 = LocalMetadataItem.stub(fileName: "file1", lastModificationDate: TimeInterval(1))
let localItem2 = LocalMetadataItem.stub(fileName: "file2", lastModificationDate: TimeInterval(2))
let localItem3 = LocalMetadataItem.stub(fileName: "file3", lastModificationDate: TimeInterval(3))
let cloudItem1 = CloudMetadataItem.stub(fileName: "file1", lastModificationDate: TimeInterval(1))
let cloudItem2 = CloudMetadataItem.stub(fileName: "file2", lastModificationDate: TimeInterval(2))
let cloudItem3 = CloudMetadataItem.stub(fileName: "file3", lastModificationDate: TimeInterval(3))
let localItems = LocalContents([localItem1, localItem2, localItem3])
let cloudItems = CloudContents([cloudItem1, cloudItem2, cloudItem3])
outgoingEvents = syncStateManager.resolveEvent(.didFinishGatheringLocalContents(localItems))
outgoingEvents = syncStateManager.resolveEvent(.didFinishGatheringCloudContents(cloudItems))
XCTAssertEqual(outgoingEvents.count, 0)
let newCloudItems = CloudContents([cloudItem1, cloudItem2, cloudItem3])
let update = CloudContentsUpdate(added: [], updated: [], removed: [])
outgoingEvents = syncStateManager.resolveEvent(.didUpdateCloudContents(contents: newCloudItems, update: update))
XCTAssertEqual(outgoingEvents.count, 0)
}
func testDidUpdateCloudContentsWhenContentItemWasAdded() {
let localItem1 = LocalMetadataItem.stub(fileName: "file1", lastModificationDate: TimeInterval(1))
let localItem2 = LocalMetadataItem.stub(fileName: "file2", lastModificationDate: TimeInterval(2))
let localItem3 = LocalMetadataItem.stub(fileName: "file3", lastModificationDate: TimeInterval(3))
let cloudItem1 = CloudMetadataItem.stub(fileName: "file1", lastModificationDate: TimeInterval(1))
let cloudItem2 = CloudMetadataItem.stub(fileName: "file2", lastModificationDate: TimeInterval(2))
let cloudItem3 = CloudMetadataItem.stub(fileName: "file3", lastModificationDate: TimeInterval(3))
let localItems = LocalContents([localItem1, localItem2, localItem3])
var cloudItems = CloudContents([cloudItem1, cloudItem2, cloudItem3])
outgoingEvents = syncStateManager.resolveEvent(.didFinishGatheringLocalContents(localItems))
outgoingEvents = syncStateManager.resolveEvent(.didFinishGatheringCloudContents(cloudItems))
XCTAssertEqual(outgoingEvents.count, 0)
var cloudItem4 = CloudMetadataItem.stub(fileName: "file4", lastModificationDate: TimeInterval(3), isDownloaded: false, percentDownloaded: 0.0)
cloudItems.append(cloudItem4)
var update = CloudContentsUpdate(added: [cloudItem4], updated: [], removed: [])
outgoingEvents = syncStateManager.resolveEvent(.didUpdateCloudContents(contents: cloudItems, update: update))
XCTAssertEqual(outgoingEvents.count, 1)
outgoingEvents.forEach { event in
switch event {
case .startDownloading(let cloudMetadataItem):
XCTAssertEqual(cloudMetadataItem, cloudItem4)
default:
XCTFail()
}
}
cloudItem4.percentDownloaded = 50.0
update = CloudContentsUpdate(added: [], updated: [cloudItem4], removed: [])
outgoingEvents = syncStateManager.resolveEvent(.didUpdateCloudContents(contents: cloudItems, update: update))
XCTAssertEqual(outgoingEvents.count, 0)
cloudItem4.percentDownloaded = 100.0
update = CloudContentsUpdate(added: [], updated: [cloudItem4], removed: [])
outgoingEvents = syncStateManager.resolveEvent(.didUpdateCloudContents(contents: cloudItems, update: update))
XCTAssertEqual(outgoingEvents.count, 0)
cloudItem4.isDownloaded = true
// recreate collection
cloudItems = [cloudItem1, cloudItem2, cloudItem3, cloudItem4]
update = CloudContentsUpdate(added: [], updated: [cloudItem4], removed: [])
outgoingEvents = syncStateManager.resolveEvent(.didUpdateCloudContents(contents: cloudItems, update: update))
XCTAssertEqual(outgoingEvents.count, 1)
outgoingEvents.forEach { event in
switch event {
case .createLocalItem(let cloudMetadataItem):
XCTAssertEqual(cloudMetadataItem, cloudItem4)
default:
XCTFail()
}
}
}
}