Repo created
This commit is contained in:
parent
4af19165ec
commit
68073add76
12458 changed files with 12350765 additions and 2 deletions
28
iphone/Maps/Tests/Core/TextToSpeech/MWMTextToSpeechTests.mm
Normal file
28
iphone/Maps/Tests/Core/TextToSpeech/MWMTextToSpeechTests.mm
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
#import <XCTest/XCTest.h>
|
||||
#import "MWMTextToSpeech+CPP.h"
|
||||
|
||||
@interface MWMTextToSpeechTest : XCTestCase
|
||||
|
||||
@end
|
||||
|
||||
@implementation MWMTextToSpeechTest
|
||||
|
||||
- (void)testAvailableLanguages {
|
||||
MWMTextToSpeech * tts = [MWMTextToSpeech tts];
|
||||
std::vector<std::pair<std::string, std::string>> langs = tts.availableLanguages;
|
||||
decltype(langs)::value_type const defaultLang = std::make_pair("en-US", "English (United States)");
|
||||
XCTAssertTrue(std::find(langs.begin(), langs.end(), defaultLang) != langs.end());
|
||||
}
|
||||
- (void)testTranslateLocaleWithTwineString {
|
||||
XCTAssertEqual(tts::translateLocale("en"), "English");
|
||||
}
|
||||
|
||||
- (void)testTranslateLocaleWithBcp47String {
|
||||
XCTAssertEqual(tts::translateLocale("en-US"), "English (United States)");
|
||||
}
|
||||
|
||||
- (void)testTranslateLocaleWithUnknownString {
|
||||
XCTAssertEqual(tts::translateLocale("unknown"), "");
|
||||
}
|
||||
|
||||
@end
|
||||
28
iphone/Maps/Tests/Core/TextToSpeech/TTSTesterTest.m
Normal file
28
iphone/Maps/Tests/Core/TextToSpeech/TTSTesterTest.m
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
#import <XCTest/XCTest.h>
|
||||
#import "TTSTester.h"
|
||||
|
||||
@interface TTSTesterTest : XCTestCase
|
||||
|
||||
@end
|
||||
|
||||
@implementation TTSTesterTest
|
||||
|
||||
TTSTester * ttsTester;
|
||||
|
||||
- (void)setUp {
|
||||
ttsTester = [[TTSTester alloc] init];
|
||||
}
|
||||
|
||||
- (void)testTestStringsWithEnglish {
|
||||
XCTAssertTrue([[ttsTester getTestStrings:@"en-US"] containsObject: @"Thank you for using our community-built maps!"]);
|
||||
}
|
||||
|
||||
- (void)testTestStringsWithGerman {
|
||||
XCTAssertTrue([[ttsTester getTestStrings:@"de-DE"] containsObject: @"Danke, dass du unsere von der Community erstellten Karten benutzt!"]);
|
||||
}
|
||||
|
||||
- (void)testTestStringsWithInvalidLanguage {
|
||||
XCTAssertNil([ttsTester getTestStrings:@"xxx"]);
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
@ -0,0 +1,195 @@
|
|||
import XCTest
|
||||
@testable import CoMaps__Debug_
|
||||
|
||||
final class TrackRecordingManagerTests: XCTestCase {
|
||||
|
||||
private var trackRecordingManager: TrackRecordingManager!
|
||||
|
||||
private var mockTrackRecorder: MockTrackRecorder.Type!
|
||||
private var mockLocationService: MockLocationService.Type!
|
||||
private var mockActivityManager: MockTrackRecordingActivityManager!
|
||||
|
||||
override func setUp() {
|
||||
super.setUp()
|
||||
mockTrackRecorder = MockTrackRecorder.self
|
||||
mockLocationService = MockLocationService.self
|
||||
mockActivityManager = MockTrackRecordingActivityManager()
|
||||
|
||||
trackRecordingManager = TrackRecordingManager(
|
||||
trackRecorder: mockTrackRecorder,
|
||||
locationService: mockLocationService,
|
||||
activityManager: mockActivityManager
|
||||
)
|
||||
}
|
||||
|
||||
override func tearDown() {
|
||||
trackRecordingManager = nil
|
||||
mockTrackRecorder.reset()
|
||||
mockLocationService.reset()
|
||||
mockActivityManager = nil
|
||||
super.tearDown()
|
||||
}
|
||||
|
||||
func test_GivenInitialSetup_WhenLocationEnabled_ThenStateIsInactive() {
|
||||
mockLocationService.locationIsProhibited = false
|
||||
mockTrackRecorder.trackRecordingIsEnabled = false
|
||||
|
||||
trackRecordingManager.setup()
|
||||
XCTAssertTrue(trackRecordingManager.recordingState == .inactive)
|
||||
}
|
||||
|
||||
func test_GivenInitialSetup_WhenLocationDisabled_ThenShouldHandleErrorAndIncativeState() {
|
||||
mockLocationService.locationIsProhibited = true
|
||||
|
||||
trackRecordingManager.setup()
|
||||
|
||||
XCTAssertTrue(mockLocationService.checkLocationStatusCalled)
|
||||
XCTAssertTrue(trackRecordingManager.recordingState == .inactive)
|
||||
}
|
||||
|
||||
func test_GivenStartRecording_WhenLocationEnabled_ThenSuccess() {
|
||||
mockLocationService.locationIsProhibited = false
|
||||
mockTrackRecorder.trackRecordingIsEnabled = false
|
||||
|
||||
trackRecordingManager.start()
|
||||
|
||||
XCTAssertTrue(mockTrackRecorder.startTrackRecordingCalled)
|
||||
XCTAssertTrue(mockActivityManager.startCalled)
|
||||
XCTAssertTrue(trackRecordingManager.recordingState == .active)
|
||||
}
|
||||
|
||||
func test_GivenStartRecording_WhenLocationDisabled_ThenShouldFail() {
|
||||
mockLocationService.locationIsProhibited = true
|
||||
let expectation = expectation(description: "Location is prohibited")
|
||||
trackRecordingManager.start() { result in
|
||||
switch result {
|
||||
case .success:
|
||||
XCTFail("Should not succeed")
|
||||
case .failure(let error):
|
||||
switch error {
|
||||
case LocationError.locationIsProhibited:
|
||||
expectation.fulfill()
|
||||
default:
|
||||
XCTFail("Unexpected error: \(error)")
|
||||
}
|
||||
}
|
||||
}
|
||||
wait(for: [expectation], timeout: 1.0)
|
||||
XCTAssertFalse(self.mockTrackRecorder.startTrackRecordingCalled)
|
||||
XCTAssertTrue(trackRecordingManager.recordingState == .inactive)
|
||||
}
|
||||
|
||||
func test_GivenStopRecording_WhenLocationEnabled_ThenSuccess() {
|
||||
mockTrackRecorder.trackRecordingIsEnabled = true
|
||||
mockTrackRecorder.trackRecordingIsEmpty = false
|
||||
|
||||
trackRecordingManager.stopAndSave(withName: "Test Track") { result in
|
||||
switch result {
|
||||
case .success:
|
||||
XCTAssertTrue(true)
|
||||
case .trackIsEmpty:
|
||||
XCTFail("Track should not be empty")
|
||||
}
|
||||
}
|
||||
XCTAssertTrue(mockTrackRecorder.stopTrackRecordingCalled)
|
||||
XCTAssertTrue(mockTrackRecorder.saveTrackRecordingCalled)
|
||||
XCTAssertTrue(mockActivityManager.stopCalled)
|
||||
XCTAssertTrue(trackRecordingManager.recordingState == .inactive)
|
||||
}
|
||||
|
||||
func test_GivenStopRecording_WhenTrackIsEmpty_ThenShouldFail() {
|
||||
mockTrackRecorder.trackRecordingIsEnabled = true
|
||||
mockTrackRecorder.trackRecordingIsEmpty = true
|
||||
let expectation = expectation(description: "Track recording should be empty")
|
||||
trackRecordingManager.stopAndSave(withName: "Test Track") { result in
|
||||
switch result {
|
||||
case .success:
|
||||
XCTFail("Should not succeed")
|
||||
case .trackIsEmpty:
|
||||
expectation.fulfill()
|
||||
}
|
||||
}
|
||||
wait(for: [expectation], timeout: 1.0)
|
||||
XCTAssertFalse(mockTrackRecorder.saveTrackRecordingCalled)
|
||||
XCTAssertTrue(trackRecordingManager.recordingState == .inactive)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Mock Classes
|
||||
|
||||
private final class MockTrackRecorder: TrackRecorder {
|
||||
static var trackRecordingIsEnabled = false
|
||||
static var trackRecordingIsEmpty = false
|
||||
static var startTrackRecordingCalled = false
|
||||
static var stopTrackRecordingCalled = false
|
||||
static var saveTrackRecordingCalled = false
|
||||
|
||||
static func reset() {
|
||||
trackRecordingIsEnabled = false
|
||||
trackRecordingIsEmpty = false
|
||||
startTrackRecordingCalled = false
|
||||
stopTrackRecordingCalled = false
|
||||
saveTrackRecordingCalled = false
|
||||
}
|
||||
|
||||
static func isTrackRecordingEnabled() -> Bool {
|
||||
return trackRecordingIsEnabled
|
||||
}
|
||||
|
||||
static func isTrackRecordingEmpty() -> Bool {
|
||||
return trackRecordingIsEmpty
|
||||
}
|
||||
|
||||
static func startTrackRecording() {
|
||||
startTrackRecordingCalled = true
|
||||
trackRecordingIsEnabled = true
|
||||
}
|
||||
|
||||
static func stopTrackRecording() {
|
||||
stopTrackRecordingCalled = true
|
||||
trackRecordingIsEnabled = false
|
||||
}
|
||||
|
||||
static func saveTrackRecording(withName name: String) {
|
||||
saveTrackRecordingCalled = true
|
||||
}
|
||||
|
||||
static func setTrackRecordingUpdateHandler(_ handler: ((TrackInfo) -> Void)?) {}
|
||||
|
||||
static func trackRecordingElevationInfo() -> ElevationProfileData {
|
||||
ElevationProfileData()
|
||||
}
|
||||
}
|
||||
|
||||
private final class MockLocationService: LocationService {
|
||||
static var locationIsProhibited = false
|
||||
static var checkLocationStatusCalled = false
|
||||
|
||||
static func reset() {
|
||||
locationIsProhibited = false
|
||||
checkLocationStatusCalled = false
|
||||
}
|
||||
|
||||
static func isLocationProhibited() -> Bool {
|
||||
return locationIsProhibited
|
||||
}
|
||||
|
||||
static func checkLocationStatus() {
|
||||
checkLocationStatusCalled = true
|
||||
}
|
||||
}
|
||||
|
||||
final class MockTrackRecordingActivityManager: TrackRecordingActivityManager {
|
||||
var startCalled = false
|
||||
var stopCalled = false
|
||||
|
||||
func start(with info: TrackInfo) throws {
|
||||
startCalled = true
|
||||
}
|
||||
|
||||
func stop() {
|
||||
stopCalled = true
|
||||
}
|
||||
|
||||
func update(_ info: TrackInfo) {}
|
||||
}
|
||||
|
|
@ -0,0 +1,134 @@
|
|||
import XCTest
|
||||
@testable import CoMaps__Debug_
|
||||
|
||||
final class DefaultLocalDirectoryMonitorTests: XCTestCase {
|
||||
|
||||
let fileManager = FileManager.default
|
||||
let tempDirectory = FileManager.default.temporaryDirectory.appendingPathComponent(UUID().uuidString)
|
||||
var directoryMonitor: FileSystemDispatchSourceMonitor!
|
||||
var mockDelegate: LocalDirectoryMonitorDelegateMock!
|
||||
|
||||
override func setUpWithError() throws {
|
||||
try super.setUpWithError()
|
||||
// Setup with a temporary directory and a mock delegate
|
||||
directoryMonitor = try FileSystemDispatchSourceMonitor(fileManager: fileManager, directory: tempDirectory)
|
||||
mockDelegate = LocalDirectoryMonitorDelegateMock()
|
||||
directoryMonitor.delegate = mockDelegate
|
||||
}
|
||||
|
||||
override func tearDownWithError() throws {
|
||||
directoryMonitor.stop()
|
||||
mockDelegate = nil
|
||||
try? fileManager.removeItem(at: tempDirectory)
|
||||
try super.tearDownWithError()
|
||||
}
|
||||
|
||||
func testInitialization() {
|
||||
XCTAssertEqual(directoryMonitor.directory, tempDirectory, "Monitor initialized with incorrect directory.")
|
||||
XCTAssertTrue(directoryMonitor.state == .stopped, "Monitor should be stopped initially.")
|
||||
}
|
||||
|
||||
func testStartMonitoring() {
|
||||
let startExpectation = expectation(description: "Start monitoring")
|
||||
directoryMonitor.start { result in
|
||||
switch result {
|
||||
case .success:
|
||||
XCTAssertTrue(self.directoryMonitor.state == .started, "Monitor should be started.")
|
||||
case .failure(let error):
|
||||
XCTFail("Monitoring failed to start with error: \(error)")
|
||||
}
|
||||
startExpectation.fulfill()
|
||||
}
|
||||
wait(for: [startExpectation], timeout: 5.0)
|
||||
}
|
||||
|
||||
func testStopMonitoring() {
|
||||
directoryMonitor.start()
|
||||
directoryMonitor.stop()
|
||||
XCTAssertTrue(directoryMonitor.state == .stopped, "Monitor should be stopped.")
|
||||
}
|
||||
|
||||
func testPauseAndResumeMonitoring() {
|
||||
directoryMonitor.start()
|
||||
directoryMonitor.pause()
|
||||
XCTAssertTrue(directoryMonitor.state == .paused, "Monitor should be paused.")
|
||||
|
||||
directoryMonitor.resume()
|
||||
XCTAssertTrue(directoryMonitor.state == .started, "Monitor should be started.")
|
||||
}
|
||||
|
||||
func testDelegateDidFinishGathering() {
|
||||
mockDelegate.didFinishGatheringExpectation = expectation(description: "didFinishGathering called")
|
||||
directoryMonitor.start()
|
||||
wait(for: [mockDelegate.didFinishGatheringExpectation!], timeout: 5.0)
|
||||
}
|
||||
|
||||
func testDelegateDidReceiveError() {
|
||||
mockDelegate.didReceiveErrorExpectation = expectation(description: "didReceiveLocalMonitorError called")
|
||||
|
||||
let error = NSError(domain: NSCocoaErrorDomain, code: NSFileNoSuchFileError, userInfo: nil)
|
||||
directoryMonitor.delegate?.didReceiveLocalMonitorError(error)
|
||||
|
||||
wait(for: [mockDelegate.didReceiveErrorExpectation!], timeout: 1.0)
|
||||
}
|
||||
|
||||
func testContentUpdateDetection() {
|
||||
let startExpectation = expectation(description: "Start monitoring")
|
||||
let didFinishGatheringExpectation = expectation(description: "didFinishGathering called")
|
||||
let didUpdateExpectation = expectation(description: "didUpdate called")
|
||||
|
||||
mockDelegate.didFinishGatheringExpectation = didFinishGatheringExpectation
|
||||
mockDelegate.didUpdateExpectation = didUpdateExpectation
|
||||
|
||||
directoryMonitor.start { result in
|
||||
if case .success = result {
|
||||
XCTAssertTrue(self.directoryMonitor.state == .started, "Monitor should be started.")
|
||||
}
|
||||
startExpectation.fulfill()
|
||||
}
|
||||
|
||||
wait(for: [startExpectation], timeout: 5)
|
||||
|
||||
let fileURL = tempDirectory.appendingPathComponent("test.kml")
|
||||
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
|
||||
self.fileManager.createFile(atPath: fileURL.path, contents: Data(), attributes: nil)
|
||||
}
|
||||
|
||||
wait(for: [didFinishGatheringExpectation, didUpdateExpectation], timeout: 20)
|
||||
}
|
||||
|
||||
func testFileWithIncorrectExtension() {
|
||||
let startExpectation = expectation(description: "Start monitoring")
|
||||
let didFinishGatheringExpectation = expectation(description: "didFinishGathering called")
|
||||
mockDelegate.didFinishGatheringExpectation = didFinishGatheringExpectation
|
||||
|
||||
let file1URL = tempDirectory.appendingPathComponent("test.kml.tmp")
|
||||
let file2URL = tempDirectory.appendingPathComponent("test2.tmp")
|
||||
let file3URL = tempDirectory.appendingPathComponent("test3.jpg")
|
||||
let correctFileURL = tempDirectory.appendingPathComponent("test.kml")
|
||||
|
||||
let fileData = Data(count: 12)
|
||||
try! fileData.write(to: file1URL, options: .atomic)
|
||||
try! fileData.write(to: file2URL, options: .atomic)
|
||||
try! fileData.write(to: file3URL, options: .atomic)
|
||||
try! fileData.write(to: correctFileURL, options: .atomic)
|
||||
|
||||
directoryMonitor.start { result in
|
||||
switch result {
|
||||
case .failure(let error):
|
||||
XCTFail("Monitoring failed to start with error: \(error)")
|
||||
case .success:
|
||||
XCTAssertTrue(self.directoryMonitor.state == .started, "Monitor should be started.")
|
||||
startExpectation.fulfill()
|
||||
}
|
||||
}
|
||||
wait(for: [startExpectation, didFinishGatheringExpectation], timeout: 5)
|
||||
|
||||
let contents = self.mockDelegate.contents.map { $0.fileUrl }
|
||||
XCTAssertFalse(contents.contains(file1URL), "File with incorrect extension should not be included")
|
||||
XCTAssertFalse(contents.contains(file2URL), "File with incorrect extension should not be included")
|
||||
XCTAssertFalse(contents.contains(file3URL), "File with incorrect extension should not be included")
|
||||
XCTAssertTrue(contents.contains(correctFileURL), "File with correct extension should be included")
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
import XCTest
|
||||
@testable import CoMaps__Debug_
|
||||
|
||||
class LocalDirectoryMonitorDelegateMock: LocalDirectoryMonitorDelegate {
|
||||
var contents = LocalContents()
|
||||
|
||||
var didFinishGatheringExpectation: XCTestExpectation?
|
||||
var didUpdateExpectation: XCTestExpectation?
|
||||
var didReceiveErrorExpectation: XCTestExpectation?
|
||||
|
||||
func didFinishGathering(_ contents: LocalContents) {
|
||||
self.contents = contents
|
||||
didFinishGatheringExpectation?.fulfill()
|
||||
}
|
||||
|
||||
func didUpdate(_ contents: LocalContents, _ update: LocalContentsUpdate) {
|
||||
self.contents = contents
|
||||
didUpdateExpectation?.fulfill()
|
||||
}
|
||||
|
||||
func didReceiveLocalMonitorError(_ error: Error) {
|
||||
didReceiveErrorExpectation?.fulfill()
|
||||
}
|
||||
}
|
||||
30
iphone/Maps/Tests/Core/iCloudTests/MetadataItemStubs.swift
Normal file
30
iphone/Maps/Tests/Core/iCloudTests/MetadataItemStubs.swift
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
@testable import CoMaps__Debug_
|
||||
|
||||
extension LocalMetadataItem {
|
||||
static func stub(fileName: String,
|
||||
lastModificationDate: TimeInterval) -> LocalMetadataItem {
|
||||
let item = LocalMetadataItem(fileName: fileName,
|
||||
fileUrl: URL(string: "url")!,
|
||||
lastModificationDate: lastModificationDate)
|
||||
return item
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
extension CloudMetadataItem {
|
||||
static func stub(fileName: String,
|
||||
lastModificationDate: TimeInterval,
|
||||
isDownloaded: Bool = true,
|
||||
percentDownloaded: NSNumber = 100.0,
|
||||
hasUnresolvedConflicts: Bool = false) -> CloudMetadataItem {
|
||||
let item = CloudMetadataItem(fileName: fileName,
|
||||
fileUrl: URL(string: "url")!,
|
||||
isDownloaded: isDownloaded,
|
||||
percentDownloaded: percentDownloaded,
|
||||
lastModificationDate: lastModificationDate,
|
||||
downloadingError: nil,
|
||||
uploadingError: nil,
|
||||
hasUnresolvedConflicts: hasUnresolvedConflicts)
|
||||
return item
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,573 @@
|
|||
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()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
class FileManagerMock: FileManager {
|
||||
var stubUbiquityIdentityToken: UbiquityIdentityToken?
|
||||
var shouldReturnContainerURL: Bool = true
|
||||
var stubCloudDirectory: URL?
|
||||
|
||||
override var ubiquityIdentityToken: (any UbiquityIdentityToken)? {
|
||||
return stubUbiquityIdentityToken
|
||||
}
|
||||
|
||||
override func url(forUbiquityContainerIdentifier identifier: String?) -> URL? {
|
||||
return shouldReturnContainerURL ? stubCloudDirectory ?? URL(fileURLWithPath: NSTemporaryDirectory()) : nil
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
import XCTest
|
||||
@testable import CoMaps__Debug_
|
||||
|
||||
class UbiquitousDirectoryMonitorDelegateMock: CloudDirectoryMonitorDelegate {
|
||||
var didFinishGatheringCalled = false
|
||||
var didUpdateCalled = false
|
||||
var didReceiveErrorCalled = false
|
||||
|
||||
var didFinishGatheringExpectation: XCTestExpectation?
|
||||
var didUpdateExpectation: XCTestExpectation?
|
||||
var didReceiveErrorExpectation: XCTestExpectation?
|
||||
|
||||
var contents = CloudContents()
|
||||
|
||||
func didFinishGathering(_ contents: CloudContents) {
|
||||
didFinishGatheringCalled = true
|
||||
didFinishGatheringExpectation?.fulfill()
|
||||
self.contents = contents
|
||||
}
|
||||
|
||||
func didUpdate(_ contents: CloudContents, _ update: CloudContentsUpdate) {
|
||||
didUpdateCalled = true
|
||||
didUpdateExpectation?.fulfill()
|
||||
self.contents = contents
|
||||
}
|
||||
|
||||
func didReceiveCloudMonitorError(_ error: Error) {
|
||||
didReceiveErrorCalled = true
|
||||
didReceiveErrorExpectation?.fulfill()
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
import XCTest
|
||||
@testable import CoMaps__Debug_
|
||||
|
||||
typealias UbiquityIdentityToken = NSCoding & NSCopying & NSObjectProtocol
|
||||
|
||||
class iCloudDirectoryMonitorTests: XCTestCase {
|
||||
|
||||
var cloudMonitor: iCloudDocumentsMonitor!
|
||||
var mockFileManager: FileManagerMock!
|
||||
var mockDelegate: UbiquitousDirectoryMonitorDelegateMock!
|
||||
var cloudContainerIdentifier: String = "iCloud.app.comaps.debug"
|
||||
|
||||
override func setUp() {
|
||||
super.setUp()
|
||||
mockFileManager = FileManagerMock()
|
||||
mockDelegate = UbiquitousDirectoryMonitorDelegateMock()
|
||||
cloudMonitor = iCloudDocumentsMonitor(fileManager: mockFileManager, cloudContainerIdentifier: cloudContainerIdentifier, fileType: .kml)
|
||||
cloudMonitor.delegate = mockDelegate
|
||||
}
|
||||
|
||||
override func tearDown() {
|
||||
cloudMonitor = nil
|
||||
mockFileManager = nil
|
||||
mockDelegate = nil
|
||||
super.tearDown()
|
||||
}
|
||||
|
||||
func testInitialization() {
|
||||
XCTAssertNotNil(cloudMonitor)
|
||||
XCTAssertEqual(cloudMonitor.containerIdentifier, cloudContainerIdentifier)
|
||||
}
|
||||
|
||||
func testCloudAvailability() {
|
||||
mockFileManager.stubUbiquityIdentityToken = NSString(string: "mockToken")
|
||||
XCTAssertTrue(cloudMonitor.isCloudAvailable())
|
||||
|
||||
mockFileManager.stubUbiquityIdentityToken = nil
|
||||
XCTAssertFalse(cloudMonitor.isCloudAvailable())
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue