Repository: realm/realm-swift
File: Realm/ObjectServerTests/SwiftFlexibleSyncServerTests.swift (Swift)

Code before:

        // There's inherently a race condition here: notification callbacks can
        // be called up to one more time after they're invalidated if the sync
        // worker thread is in the middle of processing a change at the time
        // that the invalidation is requested, and there's no way to wait for that.
        // This whole test takes 250ms, so we don't need a very long sleep.
        Thread.sleep(forTimeInterval: 0.2)

        downloadCount.value = 0
        uploadCount.value = 0

        try populateRealm()
        waitForDownloads(for: realm)
        try realm.write {
            realm.add(SwiftHugeSyncObject.create())
        }
        waitForUploads(for: realm)

        // We check that the notification block is not called after we reset the
        // counters on the notifiers and call invalidated().
        XCTAssertEqual(downloadCount.value, 0)
        XCTAssertEqual(uploadCount.value, 0)
    }

    func testFlexibleSyncNotEnabledError() throws {
        let appServerId = try RealmServer.shared.retrieveAppServerId(appId)
        let syncServerId = try RealmServer.shared.retrieveSyncServiceId(appServerId: appServerId)
        _ = try RealmServer.shared.disableSync(appServerId: appServerId, syncServiceId: syncServerId)
        var isEnable = try RealmServer.shared.isSyncEnabled(appServerId: appServerId, syncServiceId: syncServerId)
        XCTAssertFalse(isEnable)

        let ex = expectation(description: "Waiting for error handler to be called...")
        ex.assertForOverFulfill = false // error handler can legally be called multiple times
        app.syncManager.errorHandler = { @Sendable (error, _) in
            assertSyncError(error, .clientInternalError, "Sync is not enabled for this app")
            ex.fulfill()
        }

        _ = try Realm(configuration: configuration()) // Sync is disabled so we cannot use async open
        wait(for: [ex], timeout: 10.0)

        let configuration = try RealmServer.shared.getSyncServiceConfiguration(appServerId: appServerId, syncServiceId: syncServerId)
        _ = try RealmServer.shared.enableSync(appServerId: appServerId, syncServiceId: syncServerId, syncServiceConfiguration: configuration!).get()

        isEnable = try RealmServer.shared.isSyncEnabled(appServerId: appServerId, syncServiceId: syncServerId)
        XCTAssertTrue(isEnable)
    }
}

#endif // os(macOS)


Review comment (bug):
Creating a new app with sync disabled is probably faster than toggling sync off and on and eliminates the chance of something going wrong in this test causing problems for other tests. This could be done by adding a new value to `SyncMode` and exiting createApp() after setting up the auth providers.

Code after:

        // There's inherently a race condition here: notification callbacks can
        // be called up to one more time after they're invalidated if the sync
        // worker thread is in the middle of processing a change at the time
        // that the invalidation is requested, and there's no way to wait for that.
        // This whole test takes 250ms, so we don't need a very long sleep.
        Thread.sleep(forTimeInterval: 0.2)

        downloadCount.value = 0
        uploadCount.value = 0

        try populateRealm()
        waitForDownloads(for: realm)
        try realm.write {
            realm.add(SwiftHugeSyncObject.create())
        }
        waitForUploads(for: realm)

        // We check that the notification block is not called after we reset the
        // counters on the notifiers and call invalidated().
        XCTAssertEqual(downloadCount.value, 0)
        XCTAssertEqual(uploadCount.value, 0)
    }

    func testFlexibleSyncNotEnabledError() throws {
        let appId = try RealmServer.shared.createNotSyncApp()
        let app = app(id: appId)
        let ex = expectation(description: "Waiting for error handler to be called...")
        ex.assertForOverFulfill = false // error handler can legally be called multiple times
        app.syncManager.errorHandler = { @Sendable (error, _) in
            assertSyncError(error, .serverWarning, "Sync is not enabled for this app")
            ex.fulfill()
        }

        _ = try Realm(configuration: configuration(app: app)) // Sync is disabled so we cannot use async open
        wait(for: [ex], timeout: 10.0)
    }
}

#endif // os(macOS)